destination ui
This commit is contained in:
parent
004b1544f3
commit
cdc8e9afdf
@ -85,8 +85,8 @@ export const Pages = {
|
|||||||
balanceHistory: pageDefinition<{ currency?: string }>(
|
balanceHistory: pageDefinition<{ currency?: string }>(
|
||||||
"/balance/history/:currency?",
|
"/balance/history/:currency?",
|
||||||
),
|
),
|
||||||
balanceManualWithdraw: pageDefinition<{ currency?: string }>(
|
balanceManualWithdraw: pageDefinition<{ amount?: string }>(
|
||||||
"/balance/manual-withdraw/:currency?",
|
"/balance/manual-withdraw/:amount?",
|
||||||
),
|
),
|
||||||
balanceDeposit: pageDefinition<{ currency: string }>(
|
balanceDeposit: pageDefinition<{ currency: string }>(
|
||||||
"/balance/deposit/:currency",
|
"/balance/deposit/:currency",
|
||||||
@ -94,12 +94,8 @@ export const Pages = {
|
|||||||
balanceTransaction: pageDefinition<{ tid: string }>(
|
balanceTransaction: pageDefinition<{ tid: string }>(
|
||||||
"/balance/transaction/:tid",
|
"/balance/transaction/:tid",
|
||||||
),
|
),
|
||||||
sendCash: pageDefinition<{ currency?: string }>(
|
sendCash: pageDefinition<{ amount?: string }>("/destination/send/:amount"),
|
||||||
"/destination/send/:currency?",
|
receiveCash: pageDefinition<{ amount?: string }>("/destination/get/:amount?"),
|
||||||
),
|
|
||||||
receiveCash: pageDefinition<{ currency?: string }>(
|
|
||||||
"/destination/get/:currency?",
|
|
||||||
),
|
|
||||||
dev: "/dev",
|
dev: "/dev",
|
||||||
|
|
||||||
backup: "/backup",
|
backup: "/backup",
|
||||||
|
@ -842,10 +842,12 @@ interface SvgIconProps {
|
|||||||
title: string;
|
title: string;
|
||||||
color: string;
|
color: string;
|
||||||
onClick?: any;
|
onClick?: any;
|
||||||
|
transform?: string;
|
||||||
}
|
}
|
||||||
export const SvgIcon = styled.div<SvgIconProps>`
|
export const SvgIcon = styled.div<SvgIconProps>`
|
||||||
& > svg {
|
& > svg {
|
||||||
fill: ${({ color }) => color};
|
fill: ${({ color }) => color};
|
||||||
|
transform: ${({ transform }) => (transform ? transform : "")};
|
||||||
}
|
}
|
||||||
width: 24px;
|
width: 24px;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
|
@ -27,7 +27,7 @@ import { LoadingUriView, BaseView } from "./views.js";
|
|||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
talerPayUri?: string;
|
talerPayUri?: string;
|
||||||
goToWalletManualWithdraw: (currency?: string) => Promise<void>;
|
goToWalletManualWithdraw: (amount?: string) => Promise<void>;
|
||||||
cancel: () => Promise<void>;
|
cancel: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ export namespace State {
|
|||||||
amount: AmountJson;
|
amount: AmountJson;
|
||||||
uri: string;
|
uri: string;
|
||||||
error: undefined;
|
error: undefined;
|
||||||
goToWalletManualWithdraw: (currency?: string) => Promise<void>;
|
goToWalletManualWithdraw: (amount?: string) => Promise<void>;
|
||||||
cancel: () => Promise<void>;
|
cancel: () => Promise<void>;
|
||||||
}
|
}
|
||||||
export interface NoBalanceForCurrency extends BaseInfo {
|
export interface NoBalanceForCurrency extends BaseInfo {
|
||||||
|
@ -393,7 +393,9 @@ function ButtonsSection({
|
|||||||
<Button
|
<Button
|
||||||
variant="contained"
|
variant="contained"
|
||||||
color="success"
|
color="success"
|
||||||
onClick={() => goToWalletManualWithdraw(state.amount.currency)}
|
onClick={() =>
|
||||||
|
goToWalletManualWithdraw(Amounts.stringify(state.amount))
|
||||||
|
}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Get digital cash</i18n.Translate>
|
<i18n.Translate>Get digital cash</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -129,7 +129,6 @@ export function SuccessView(state: State.Success): VNode {
|
|||||||
title="Edit"
|
title="Edit"
|
||||||
dangerouslySetInnerHTML={{ __html: editIcon }}
|
dangerouslySetInnerHTML={{ __html: editIcon }}
|
||||||
color="black"
|
color="black"
|
||||||
onClick={() => console.log("ok")}
|
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -34,11 +34,9 @@ export function useDiagnostics(): [WalletDiagnostics | undefined, boolean] {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
const doFetch = async (): Promise<void> => {
|
const doFetch = async (): Promise<void> => {
|
||||||
const d = await wxApi.getDiagnostics();
|
const d = await wxApi.getDiagnostics();
|
||||||
console.log("got diagnostics", d);
|
|
||||||
gotDiagnostics = true;
|
gotDiagnostics = true;
|
||||||
setDiagnostics(d);
|
setDiagnostics(d);
|
||||||
};
|
};
|
||||||
console.log("fetching diagnostics");
|
|
||||||
doFetch();
|
doFetch();
|
||||||
}, []);
|
}, []);
|
||||||
return [diagnostics, timedOut];
|
return [diagnostics, timedOut];
|
||||||
|
@ -33,6 +33,10 @@ export default {
|
|||||||
const Stack = styled.div`
|
const Stack = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
& > button {
|
||||||
|
margin: 14px;
|
||||||
|
}
|
||||||
|
background-color: white;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const BasicExample = (): VNode => (
|
export const BasicExample = (): VNode => (
|
||||||
|
@ -43,6 +43,9 @@ export interface Props {
|
|||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
required?: boolean;
|
required?: boolean;
|
||||||
|
|
||||||
|
startAdornment?: VNode;
|
||||||
|
endAdornment?: VNode;
|
||||||
|
|
||||||
//FIXME: change to "grabFocus"
|
//FIXME: change to "grabFocus"
|
||||||
// focused?: boolean;
|
// focused?: boolean;
|
||||||
rows?: number;
|
rows?: number;
|
||||||
@ -75,7 +78,6 @@ export function TextField({
|
|||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
// htmlFor={id} id={inputLabelId}
|
// htmlFor={id} id={inputLabelId}
|
||||||
const Input = select ? selectVariant[variant] : inputVariant[variant];
|
const Input = select ? selectVariant[variant] : inputVariant[variant];
|
||||||
// console.log("variant", Input);
|
|
||||||
return (
|
return (
|
||||||
<FormControl {...props}>
|
<FormControl {...props}>
|
||||||
{label && <InputLabel>{label}</InputLabel>}
|
{label && <InputLabel>{label}</InputLabel>}
|
||||||
|
@ -53,6 +53,8 @@ export function InputBaseRoot({
|
|||||||
multiline,
|
multiline,
|
||||||
focused,
|
focused,
|
||||||
fullWidth,
|
fullWidth,
|
||||||
|
startAdornment,
|
||||||
|
endAdornment,
|
||||||
children,
|
children,
|
||||||
}: any): VNode {
|
}: any): VNode {
|
||||||
const fcs = useFormControl({});
|
const fcs = useFormControl({});
|
||||||
@ -61,6 +63,8 @@ export function InputBaseRoot({
|
|||||||
data-disabled={disabled}
|
data-disabled={disabled}
|
||||||
data-focused={focused}
|
data-focused={focused}
|
||||||
data-multiline={multiline}
|
data-multiline={multiline}
|
||||||
|
data-hasStart={!!startAdornment}
|
||||||
|
data-hasEnd={!!endAdornment}
|
||||||
data-error={error}
|
data-error={error}
|
||||||
class={[
|
class={[
|
||||||
_class,
|
_class,
|
||||||
@ -156,22 +160,28 @@ export function InputBaseComponent({
|
|||||||
multiline,
|
multiline,
|
||||||
type,
|
type,
|
||||||
class: _class,
|
class: _class,
|
||||||
|
startAdornment,
|
||||||
|
endAdornment,
|
||||||
...props
|
...props
|
||||||
}: any): VNode {
|
}: any): VNode {
|
||||||
return (
|
return (
|
||||||
<input
|
<Fragment>
|
||||||
disabled={disabled}
|
{startAdornment}
|
||||||
type={type}
|
<input
|
||||||
class={[
|
disabled={disabled}
|
||||||
componentStyle,
|
type={type}
|
||||||
_class,
|
class={[
|
||||||
disabled && componentDisabledStyle,
|
componentStyle,
|
||||||
size === "small" && componentSmallStyle,
|
_class,
|
||||||
// multiline && componentMultilineStyle,
|
disabled && componentDisabledStyle,
|
||||||
type === "search" && searchStyle,
|
size === "small" && componentSmallStyle,
|
||||||
].join(" ")}
|
// multiline && componentMultilineStyle,
|
||||||
{...props}
|
type === "search" && searchStyle,
|
||||||
/>
|
].join(" ")}
|
||||||
|
{...props}
|
||||||
|
/>
|
||||||
|
{endAdornment}
|
||||||
|
</Fragment>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -388,7 +398,6 @@ export function TextareaAutoSize({
|
|||||||
getStyleValue(computedStyle, "border-bottom-width") +
|
getStyleValue(computedStyle, "border-bottom-width") +
|
||||||
getStyleValue(computedStyle, "border-top-width");
|
getStyleValue(computedStyle, "border-top-width");
|
||||||
|
|
||||||
// console.log(boxSizing, padding, border);
|
|
||||||
// The height of the inner content
|
// The height of the inner content
|
||||||
const innerHeight = inputShallow.scrollHeight;
|
const innerHeight = inputShallow.scrollHeight;
|
||||||
|
|
||||||
@ -412,7 +421,6 @@ export function TextareaAutoSize({
|
|||||||
outerHeight + (boxSizing === "border-box" ? padding + border : 0);
|
outerHeight + (boxSizing === "border-box" ? padding + border : 0);
|
||||||
const overflow = Math.abs(outerHeight - innerHeight) <= 1;
|
const overflow = Math.abs(outerHeight - innerHeight) <= 1;
|
||||||
|
|
||||||
console.log("height", outerHeight, minRows, maxRows);
|
|
||||||
setState((prevState) => {
|
setState((prevState) => {
|
||||||
// Need a large enough difference to update the height.
|
// Need a large enough difference to update the height.
|
||||||
// This prevents infinite rendering loop.
|
// This prevents infinite rendering loop.
|
||||||
|
@ -27,7 +27,6 @@ export interface Props {
|
|||||||
defaultValue?: string;
|
defaultValue?: string;
|
||||||
disabled?: boolean;
|
disabled?: boolean;
|
||||||
disableUnderline?: boolean;
|
disableUnderline?: boolean;
|
||||||
endAdornment?: VNode;
|
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
id?: string;
|
id?: string;
|
||||||
@ -42,6 +41,7 @@ export interface Props {
|
|||||||
required?: boolean;
|
required?: boolean;
|
||||||
rows?: number;
|
rows?: number;
|
||||||
startAdornment?: VNode;
|
startAdornment?: VNode;
|
||||||
|
endAdornment?: VNode;
|
||||||
type?: string;
|
type?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
}
|
}
|
||||||
@ -108,6 +108,9 @@ const filledRootStyle = css`
|
|||||||
&[data-multiline] {
|
&[data-multiline] {
|
||||||
padding: 25px 12px 8px;
|
padding: 25px 12px 8px;
|
||||||
}
|
}
|
||||||
|
/* &[data-hasStart] {
|
||||||
|
padding-left: 25px;
|
||||||
|
} */
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const underlineStyle = css`
|
const underlineStyle = css`
|
||||||
|
@ -40,7 +40,6 @@ const api: PlatformAPI = {
|
|||||||
function waitAndNotify(): void {
|
function waitAndNotify(): void {
|
||||||
total--;
|
total--;
|
||||||
if (total < 1) {
|
if (total < 1) {
|
||||||
console.log("done");
|
|
||||||
fn();
|
fn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,6 @@ function notifyWhenAppIsReady(callback: () => void): void {
|
|||||||
|
|
||||||
function redirectTabToWalletPage(tabId: number, page: string): void {
|
function redirectTabToWalletPage(tabId: number, page: string): void {
|
||||||
const url = chrome.runtime.getURL(`/static/wallet.html#${page}`);
|
const url = chrome.runtime.getURL(`/static/wallet.html#${page}`);
|
||||||
console.log("redirecting tabId: ", tabId, " to: ", url);
|
|
||||||
chrome.tabs.update(tabId, { url, loadReplace: true } as any);
|
chrome.tabs.update(tabId, { url, loadReplace: true } as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ export function Application(): VNode {
|
|||||||
path={Pages.balance}
|
path={Pages.balance}
|
||||||
component={BalancePage}
|
component={BalancePage}
|
||||||
goToWalletManualWithdraw={() =>
|
goToWalletManualWithdraw={() =>
|
||||||
redirectTo(Pages.balanceManualWithdraw({}))
|
redirectTo(Pages.receiveCash({}))
|
||||||
}
|
}
|
||||||
goToWalletDeposit={(currency: string) =>
|
goToWalletDeposit={(currency: string) =>
|
||||||
redirectTo(Pages.balanceDeposit({ currency }))
|
redirectTo(Pages.balanceDeposit({ currency }))
|
||||||
@ -133,6 +133,10 @@ export function Application(): VNode {
|
|||||||
path={Pages.backupProviderAdd}
|
path={Pages.backupProviderAdd}
|
||||||
component={RedirectToWalletPage}
|
component={RedirectToWalletPage}
|
||||||
/>
|
/>
|
||||||
|
<Route
|
||||||
|
path={Pages.receiveCash.pattern}
|
||||||
|
component={RedirectToWalletPage}
|
||||||
|
/>
|
||||||
<Route path={Pages.qr} component={RedirectToWalletPage} />
|
<Route path={Pages.qr} component={RedirectToWalletPage} />
|
||||||
<Route path={Pages.settings} component={RedirectToWalletPage} />
|
<Route path={Pages.settings} component={RedirectToWalletPage} />
|
||||||
<Route
|
<Route
|
||||||
|
@ -172,7 +172,7 @@ export function BalanceView(state: State.Balances): VNode {
|
|||||||
variant="contained"
|
variant="contained"
|
||||||
onClick={state.goToWalletManualWithdraw.onClick}
|
onClick={state.goToWalletManualWithdraw.onClick}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Get</i18n.Translate>
|
<i18n.Translate>Add</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
{currencyWithNonZeroAmount.length > 0 && (
|
{currencyWithNonZeroAmount.length > 0 && (
|
||||||
<MultiActionButton
|
<MultiActionButton
|
||||||
|
@ -57,6 +57,7 @@ import {
|
|||||||
DestinationSelectionGetCash,
|
DestinationSelectionGetCash,
|
||||||
DestinationSelectionSendCash,
|
DestinationSelectionSendCash,
|
||||||
} from "./DestinationSelection.js";
|
} from "./DestinationSelection.js";
|
||||||
|
import { Amounts } from "@gnu-taler/taler-util";
|
||||||
|
|
||||||
export function Application(): VNode {
|
export function Application(): VNode {
|
||||||
const [globalNotification, setGlobalNotification] = useState<
|
const [globalNotification, setGlobalNotification] = useState<
|
||||||
@ -130,10 +131,14 @@ export function Application(): VNode {
|
|||||||
path={Pages.balanceHistory.pattern}
|
path={Pages.balanceHistory.pattern}
|
||||||
component={HistoryPage}
|
component={HistoryPage}
|
||||||
goToWalletDeposit={(currency: string) =>
|
goToWalletDeposit={(currency: string) =>
|
||||||
redirectTo(Pages.sendCash({ currency }))
|
redirectTo(Pages.sendCash({ amount: `${currency}:0` }))
|
||||||
}
|
}
|
||||||
goToWalletManualWithdraw={(currency?: string) =>
|
goToWalletManualWithdraw={(currency?: string) =>
|
||||||
redirectTo(Pages.receiveCash({ currency }))
|
redirectTo(
|
||||||
|
Pages.receiveCash({
|
||||||
|
amount: !currency ? undefined : `${currency}:0`,
|
||||||
|
}),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
@ -143,6 +148,9 @@ export function Application(): VNode {
|
|||||||
<Route
|
<Route
|
||||||
path={Pages.receiveCash.pattern}
|
path={Pages.receiveCash.pattern}
|
||||||
component={DestinationSelectionGetCash}
|
component={DestinationSelectionGetCash}
|
||||||
|
goToWalletManualWithdraw={(amount?: string) =>
|
||||||
|
redirectTo(Pages.balanceManualWithdraw({ amount }))
|
||||||
|
}
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={Pages.balanceTransaction.pattern}
|
path={Pages.balanceTransaction.pattern}
|
||||||
@ -226,8 +234,8 @@ export function Application(): VNode {
|
|||||||
<Route
|
<Route
|
||||||
path={Pages.ctaPay}
|
path={Pages.ctaPay}
|
||||||
component={PaymentPage}
|
component={PaymentPage}
|
||||||
goToWalletManualWithdraw={(currency?: string) =>
|
goToWalletManualWithdraw={(amount?: string) =>
|
||||||
redirectTo(Pages.balanceManualWithdraw({ currency }))
|
redirectTo(Pages.balanceManualWithdraw({ amount }))
|
||||||
}
|
}
|
||||||
cancel={() => redirectTo(Pages.balance)}
|
cancel={() => redirectTo(Pages.balance)}
|
||||||
/>
|
/>
|
||||||
|
@ -30,8 +30,8 @@ export default {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const GetCash = createExample(DestinationSelectionGetCash, {
|
export const GetCash = createExample(DestinationSelectionGetCash, {
|
||||||
currency: "usd",
|
amount: "usd:0",
|
||||||
});
|
});
|
||||||
export const SendCash = createExample(DestinationSelectionSendCash, {
|
export const SendCash = createExample(DestinationSelectionSendCash, {
|
||||||
currency: "eur",
|
amount: "eur:1",
|
||||||
});
|
});
|
||||||
|
@ -14,17 +14,22 @@
|
|||||||
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { Amounts } from "@gnu-taler/taler-util";
|
||||||
import { styled } from "@linaria/react";
|
import { styled } from "@linaria/react";
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
|
import { useState } from "preact/hooks";
|
||||||
|
import {
|
||||||
|
InputWithLabel,
|
||||||
|
LightText,
|
||||||
|
SvgIcon,
|
||||||
|
} from "../components/styled/index.js";
|
||||||
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
import { Grid } from "../mui/Grid.js";
|
||||||
import { Paper } from "../mui/Paper.js";
|
import { Paper } from "../mui/Paper.js";
|
||||||
|
import { TextField } from "../mui/TextField.js";
|
||||||
const QrVideo = styled.video`
|
import arrowIcon from "../svg/chevron-down.svg";
|
||||||
width: 80%;
|
import bankIcon from "../svg/ri-bank-line.svg";
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
padding: 8px;
|
|
||||||
background-color: black;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -36,25 +41,379 @@ const Container = styled.div`
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
action: "send" | "get";
|
action: "send" | "get";
|
||||||
currency?: string;
|
amount?: string;
|
||||||
|
goToWalletManualWithdraw: (amount: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DestinationSelectionGetCash({ currency }: Props): VNode {
|
type Contact = {
|
||||||
|
icon: string;
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const ContactTable = styled.table`
|
||||||
|
width: 100%;
|
||||||
|
& > tr > td {
|
||||||
|
padding: 8px;
|
||||||
|
& > div:not([data-disabled]):hover {
|
||||||
|
background-color: lightblue;
|
||||||
|
}
|
||||||
|
color: black;
|
||||||
|
div[data-disabled] > * {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > tr:nth-child(2n) {
|
||||||
|
background: #ebebeb;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MediaExample = styled.div`
|
||||||
|
text-size-adjust: 100%;
|
||||||
|
color: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
text-transform: none;
|
||||||
|
text-align: left;
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
padding: 8px 8px;
|
||||||
|
|
||||||
|
&[data-disabled]:hover {
|
||||||
|
cursor: inherit;
|
||||||
|
}
|
||||||
|
cursor: pointer;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MediaLeft = styled.div`
|
||||||
|
text-size-adjust: 100%;
|
||||||
|
|
||||||
|
color: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
text-transform: none;
|
||||||
|
text-align: left;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-right: 8px;
|
||||||
|
display: block;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const MediaBody = styled.div`
|
||||||
|
text-size-adjust: 100%;
|
||||||
|
|
||||||
|
font-family: inherit;
|
||||||
|
text-transform: none;
|
||||||
|
text-align: left;
|
||||||
|
box-sizing: border-box;
|
||||||
|
flex: 1 1;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.42857;
|
||||||
|
`;
|
||||||
|
const MediaRight = styled.div`
|
||||||
|
text-size-adjust: 100%;
|
||||||
|
|
||||||
|
color: inherit;
|
||||||
|
font-family: inherit;
|
||||||
|
font-size: inherit;
|
||||||
|
line-height: inherit;
|
||||||
|
text-transform: none;
|
||||||
|
text-align: left;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-left: 8px;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const CircleDiv = styled.div`
|
||||||
|
box-sizing: border-box;
|
||||||
|
align-items: center;
|
||||||
|
background-position: 50%;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-size: cover;
|
||||||
|
border-radius: 50%;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: uppercase;
|
||||||
|
transition: background-color 0.15s ease, border-color 0.15s ease,
|
||||||
|
color 0.15s ease;
|
||||||
|
font-size: 16px;
|
||||||
|
background-color: #86a7bd1a;
|
||||||
|
height: 40px;
|
||||||
|
line-height: 40px;
|
||||||
|
width: 40px;
|
||||||
|
border: none;
|
||||||
|
`;
|
||||||
|
|
||||||
|
function RowExample({
|
||||||
|
info,
|
||||||
|
disabled,
|
||||||
|
}: {
|
||||||
|
info: Contact;
|
||||||
|
disabled?: boolean;
|
||||||
|
}): VNode {
|
||||||
|
return (
|
||||||
|
<MediaExample data-disabled={disabled}>
|
||||||
|
<MediaLeft>
|
||||||
|
<CircleDiv>
|
||||||
|
<SvgIcon
|
||||||
|
title={info.name}
|
||||||
|
dangerouslySetInnerHTML={{ __html: info.icon }}
|
||||||
|
color="currentColor"
|
||||||
|
/>
|
||||||
|
</CircleDiv>
|
||||||
|
</MediaLeft>
|
||||||
|
<MediaBody>
|
||||||
|
<span>{info.name}</span>
|
||||||
|
<LightText>{info.description}</LightText>
|
||||||
|
</MediaBody>
|
||||||
|
<MediaRight>
|
||||||
|
<SvgIcon
|
||||||
|
title="Select this contact"
|
||||||
|
dangerouslySetInnerHTML={{ __html: arrowIcon }}
|
||||||
|
color="currentColor"
|
||||||
|
transform="rotate(-90deg)"
|
||||||
|
/>
|
||||||
|
</MediaRight>
|
||||||
|
</MediaExample>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function DestinationSelectionGetCash({
|
||||||
|
amount: initialAmount,
|
||||||
|
goToWalletManualWithdraw,
|
||||||
|
}: Props): VNode {
|
||||||
|
const parsedInitialAmount = !initialAmount
|
||||||
|
? undefined
|
||||||
|
: Amounts.parse(initialAmount);
|
||||||
|
const parsedInitialAmountValue = !parsedInitialAmount
|
||||||
|
? ""
|
||||||
|
: Amounts.stringifyValue(parsedInitialAmount);
|
||||||
|
const currency = parsedInitialAmount?.currency;
|
||||||
|
|
||||||
|
const [amount, setAmount] = useState(parsedInitialAmountValue);
|
||||||
|
const { i18n } = useTranslationContext();
|
||||||
|
const previous1: Contact[] = [];
|
||||||
|
const previous2: Contact[] = [
|
||||||
|
{
|
||||||
|
name: "International Bank",
|
||||||
|
icon: bankIcon,
|
||||||
|
description: "account ending with 3454",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Max",
|
||||||
|
icon: bankIcon,
|
||||||
|
description: "account ending with 3454",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Alex",
|
||||||
|
icon: bankIcon,
|
||||||
|
description: "account ending with 3454",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!currency) {
|
||||||
|
return <div>currency not provided</div>;
|
||||||
|
}
|
||||||
|
const currencyAndAmount = `${currency}:${amount}`;
|
||||||
|
const parsedAmount = Amounts.parse(currencyAndAmount);
|
||||||
|
// const dirty = parsedInitialAmountValue !== amount;
|
||||||
|
const invalid = !parsedAmount || Amounts.isZero(parsedAmount);
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<p>Request {currency} from:</p>
|
<h1>
|
||||||
<Paper style={{ padding: 8 }}>Bank account</Paper>
|
<i18n.Translate>Specify the amount and the origin</i18n.Translate>
|
||||||
<Paper style={{ padding: 8 }}>Another person</Paper>
|
</h1>
|
||||||
|
<TextField
|
||||||
|
label="Amount"
|
||||||
|
type="number"
|
||||||
|
variant="filled"
|
||||||
|
error={invalid}
|
||||||
|
required
|
||||||
|
startAdornment={
|
||||||
|
<div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div>
|
||||||
|
}
|
||||||
|
value={amount}
|
||||||
|
onChange={(e) => {
|
||||||
|
setAmount(e);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Grid container spacing={1} columns={1}>
|
||||||
|
{previous2.length > 0 ? (
|
||||||
|
<Fragment>
|
||||||
|
<p>Previous origins:</p>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<ContactTable>
|
||||||
|
{previous2.map((info, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>
|
||||||
|
<RowExample info={info} disabled={invalid} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</ContactTable>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
) : undefined}
|
||||||
|
<Grid item>
|
||||||
|
<p>Create new origin for the money</p>
|
||||||
|
</Grid>
|
||||||
|
<Grid item container columns={3} spacing={1}>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>From my bank account</p>
|
||||||
|
<Button
|
||||||
|
disabled={invalid}
|
||||||
|
onClick={async () =>
|
||||||
|
goToWalletManualWithdraw(currencyAndAmount)
|
||||||
|
}
|
||||||
|
>
|
||||||
|
Withdraw
|
||||||
|
</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>From someone else</p>
|
||||||
|
<Button disabled>Request</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>From a business or charity</p>
|
||||||
|
<Button disabled>Invoice</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid item columns={1} spacing={1} xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>From a exchange reserve or purse</p>
|
||||||
|
<Button disabled>Create</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DestinationSelectionSendCash({ currency }: Props): VNode {
|
export function DestinationSelectionSendCash({
|
||||||
|
amount: initialAmount,
|
||||||
|
}: Props): VNode {
|
||||||
|
const parsedInitialAmount = !initialAmount
|
||||||
|
? undefined
|
||||||
|
: Amounts.parse(initialAmount);
|
||||||
|
const parsedInitialAmountValue = !parsedInitialAmount
|
||||||
|
? ""
|
||||||
|
: Amounts.stringifyValue(parsedInitialAmount);
|
||||||
|
const currency = parsedInitialAmount?.currency;
|
||||||
|
|
||||||
|
const [amount, setAmount] = useState(parsedInitialAmountValue);
|
||||||
|
const { i18n } = useTranslationContext();
|
||||||
|
const previous1: Contact[] = [];
|
||||||
|
const previous2: Contact[] = [
|
||||||
|
{
|
||||||
|
name: "International Bank",
|
||||||
|
icon: bankIcon,
|
||||||
|
description: "account ending with 3454",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Max",
|
||||||
|
icon: bankIcon,
|
||||||
|
description: "account ending with 3454",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Alex",
|
||||||
|
icon: bankIcon,
|
||||||
|
description: "account ending with 3454",
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
if (!currency) {
|
||||||
|
return <div>currency not provided</div>;
|
||||||
|
}
|
||||||
|
const currencyAndAmount = `${currency}:${amount}`;
|
||||||
|
const parsedAmount = Amounts.parse(currencyAndAmount);
|
||||||
|
const invalid = !parsedAmount || Amounts.isZero(parsedAmount);
|
||||||
return (
|
return (
|
||||||
<Container>
|
<Container>
|
||||||
<p>Sending {currency} to:</p>
|
<h1>
|
||||||
<Paper style={{ padding: 8 }}>Bank account</Paper>
|
<i18n.Translate>Specify the amount and the destination</i18n.Translate>
|
||||||
<Paper style={{ padding: 8 }}>Another person</Paper>
|
</h1>
|
||||||
|
|
||||||
|
<TextField
|
||||||
|
label="Amount"
|
||||||
|
type="number"
|
||||||
|
variant="filled"
|
||||||
|
required
|
||||||
|
error={invalid}
|
||||||
|
startAdornment={
|
||||||
|
<div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div>
|
||||||
|
}
|
||||||
|
value={amount}
|
||||||
|
onChange={(e) => {
|
||||||
|
setAmount(e);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<Grid container spacing={1} columns={1}>
|
||||||
|
{previous2.length > 0 ? (
|
||||||
|
<Fragment>
|
||||||
|
<p>Previous destinations:</p>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<ContactTable>
|
||||||
|
{previous2.map((info, i) => (
|
||||||
|
<tr key={i}>
|
||||||
|
<td>
|
||||||
|
<RowExample info={info} disabled={invalid} />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
))}
|
||||||
|
</ContactTable>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Fragment>
|
||||||
|
) : undefined}
|
||||||
|
<Grid item>
|
||||||
|
<p>Create a destination for the money</p>
|
||||||
|
</Grid>
|
||||||
|
<Grid item container columns={3} spacing={1}>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>To my bank account</p>
|
||||||
|
<Button disabled={invalid}>Deposit</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>To someone else</p>
|
||||||
|
<Button disabled>Send</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
<Grid item xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>To a business or charity</p>
|
||||||
|
<Button disabled>Pay</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
|
<Grid item columns={1} spacing={1} xs={1}>
|
||||||
|
<Paper style={{ padding: 8 }}>
|
||||||
|
<p>To an exchange reserve or purse</p>
|
||||||
|
<Button disabled>Create</Button>
|
||||||
|
</Paper>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -210,7 +210,7 @@ export function HistoryView({
|
|||||||
// style={{ marginLeft: 0, marginTop: 8 }}
|
// style={{ marginLeft: 0, marginTop: 8 }}
|
||||||
onClick={() => goToWalletManualWithdraw(selectedCurrency)}
|
onClick={() => goToWalletManualWithdraw(selectedCurrency)}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Get</i18n.Translate>
|
<i18n.Translate>Add</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
{currencyAmount && Amounts.isNonZero(currencyAmount) && (
|
{currencyAmount && Amounts.isNonZero(currencyAmount) && (
|
||||||
<Button
|
<Button
|
||||||
|
@ -33,11 +33,11 @@ import { CreateManualWithdraw } from "./CreateManualWithdraw.js";
|
|||||||
import { ReserveCreated } from "./ReserveCreated.js";
|
import { ReserveCreated } from "./ReserveCreated.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currency?: string;
|
amount?: string;
|
||||||
onCancel: () => Promise<void>;
|
onCancel: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
|
export function ManualWithdrawPage({ amount, onCancel }: Props): VNode {
|
||||||
const [success, setSuccess] = useState<
|
const [success, setSuccess] = useState<
|
||||||
| {
|
| {
|
||||||
response: AcceptManualWithdrawalResult;
|
response: AcceptManualWithdrawalResult;
|
||||||
@ -117,12 +117,18 @@ export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
|
|||||||
{} as Record<string, string>,
|
{} as Record<string, string>,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const parsedAmount = !amount ? undefined : Amounts.parse(amount);
|
||||||
|
const currency = parsedAmount?.currency;
|
||||||
|
const amountValue = !parsedAmount
|
||||||
|
? undefined
|
||||||
|
: Amounts.stringifyValue(parsedAmount);
|
||||||
return (
|
return (
|
||||||
<CreateManualWithdraw
|
<CreateManualWithdraw
|
||||||
error={error}
|
error={error}
|
||||||
exchangeUrlWithCurrency={exchangeList}
|
exchangeUrlWithCurrency={exchangeList}
|
||||||
onCreate={doCreate}
|
onCreate={doCreate}
|
||||||
initialCurrency={currency}
|
initialCurrency={currency}
|
||||||
|
initialAmount={amountValue}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user