mui button impl
This commit is contained in:
parent
2aade8e7ae
commit
af7b107f45
@ -77,8 +77,8 @@ export const BasicExample = (): VNode => (
|
|||||||
]}
|
]}
|
||||||
confirm={{
|
confirm={{
|
||||||
label: "turn on wifi",
|
label: "turn on wifi",
|
||||||
action: () => {
|
action: async () => {
|
||||||
return null;
|
return;
|
||||||
},
|
},
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
@ -15,7 +15,7 @@ interface Props extends JSX.HTMLAttributes<HTMLDivElement> {
|
|||||||
}[];
|
}[];
|
||||||
confirm?: {
|
confirm?: {
|
||||||
label: string;
|
label: string;
|
||||||
action: () => void;
|
action: () => Promise<void>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ import { h, VNode } from "preact";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
enabled?: boolean;
|
enabled?: boolean;
|
||||||
onToggle?: () => void;
|
onToggle?: () => Promise<void>;
|
||||||
label: VNode;
|
label: VNode;
|
||||||
name: string;
|
name: string;
|
||||||
description?: VNode;
|
description?: VNode;
|
||||||
|
@ -19,7 +19,7 @@ import { h, VNode } from "preact";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
onToggle: () => void;
|
onToggle: () => Promise<void>;
|
||||||
label: VNode;
|
label: VNode;
|
||||||
name: string;
|
name: string;
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
|
import { getUnpackedSettings } from "http2";
|
||||||
import { h, VNode } from "preact";
|
import { h, VNode } from "preact";
|
||||||
import arrowDown from "../svg/chevron-down.svg";
|
|
||||||
import {
|
|
||||||
ButtonBoxPrimary,
|
|
||||||
ButtonPrimary,
|
|
||||||
ParagraphClickable,
|
|
||||||
} from "./styled/index.js";
|
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
import arrowDown from "../svg/chevron-down.svg";
|
||||||
|
import { ParagraphClickable } from "./styled/index.js";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
label: (s: string) => VNode;
|
label: (s: string) => VNode;
|
||||||
actions: string[];
|
actions: string[];
|
||||||
onClick: (s: string) => void;
|
onClick: (s: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,9 +41,9 @@ export function MultiActionButton({
|
|||||||
|
|
||||||
if (!canChange) {
|
if (!canChange) {
|
||||||
return (
|
return (
|
||||||
<ButtonPrimary onClick={() => doClick(selected)}>
|
<Button variant="contained" onClick={() => doClick(selected)}>
|
||||||
{label(selected)}
|
{label(selected)}
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,40 +71,44 @@ export function MultiActionButton({
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<ButtonBoxPrimary
|
<Button
|
||||||
|
variant="contained"
|
||||||
onClick={() => doClick(selected)}
|
onClick={() => doClick(selected)}
|
||||||
style={{
|
style={{
|
||||||
borderTopRightRadius: 0,
|
borderTopRightRadius: 0,
|
||||||
borderBottomRightRadius: 0,
|
borderBottomRightRadius: 0,
|
||||||
marginRight: 0,
|
marginRight: 0,
|
||||||
maxWidth: 170,
|
// maxWidth: 170,
|
||||||
overflowX: "hidden",
|
overflowX: "hidden",
|
||||||
textOverflow: "ellipsis",
|
textOverflow: "ellipsis",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{label(selected)}
|
{label(selected)}
|
||||||
</ButtonBoxPrimary>
|
</Button>
|
||||||
|
|
||||||
<ButtonPrimary
|
<Button
|
||||||
onClick={() => setOpened((s) => !s)}
|
variant="outlined"
|
||||||
|
onClick={async () => setOpened((s) => !s)}
|
||||||
style={{
|
style={{
|
||||||
marginLeft: 0,
|
marginLeft: 0,
|
||||||
borderTopLeftRadius: 0,
|
borderTopLeftRadius: 0,
|
||||||
borderBottomLeftRadius: 0,
|
borderBottomLeftRadius: 0,
|
||||||
width: 36,
|
paddingLeft: 4,
|
||||||
padding: 4,
|
paddingRight: 4,
|
||||||
height: 36,
|
minWidth: "unset",
|
||||||
fill: "white",
|
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
height: 24,
|
height: 24,
|
||||||
width: 24,
|
width: 24,
|
||||||
|
marginLeft: 4,
|
||||||
|
marginRight: 4,
|
||||||
|
// fill: "white",
|
||||||
}}
|
}}
|
||||||
dangerouslySetInnerHTML={{ __html: arrowDown }}
|
dangerouslySetInnerHTML={{ __html: arrowDown }}
|
||||||
/>
|
/>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -25,11 +25,11 @@ import { useLocalStorage } from "../hooks/useLocalStorage.js";
|
|||||||
|
|
||||||
interface Type {
|
interface Type {
|
||||||
devMode: boolean;
|
devMode: boolean;
|
||||||
toggleDevMode: () => void;
|
toggleDevMode: () => Promise<void>;
|
||||||
}
|
}
|
||||||
const Context = createContext<Type>({
|
const Context = createContext<Type>({
|
||||||
devMode: false,
|
devMode: false,
|
||||||
toggleDevMode: () => null,
|
toggleDevMode: async () => { return; },
|
||||||
});
|
});
|
||||||
|
|
||||||
export const useDevContext = (): Type => useContext(Context);
|
export const useDevContext = (): Type => useContext(Context);
|
||||||
@ -44,8 +44,8 @@ export const DevContextProviderForTesting = ({
|
|||||||
return h(Context.Provider, {
|
return h(Context.Provider, {
|
||||||
value: {
|
value: {
|
||||||
devMode: value,
|
devMode: value,
|
||||||
toggleDevMode: () => {
|
toggleDevMode: async () => {
|
||||||
null;
|
return;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
children,
|
children,
|
||||||
@ -55,7 +55,7 @@ export const DevContextProviderForTesting = ({
|
|||||||
export const DevContextProvider = ({ children }: { children: any }): VNode => {
|
export const DevContextProvider = ({ children }: { children: any }): VNode => {
|
||||||
const [value, setter] = useLocalStorage("devMode");
|
const [value, setter] = useLocalStorage("devMode");
|
||||||
const devMode = value === "true";
|
const devMode = value === "true";
|
||||||
const toggleDevMode = (): void => setter((v) => (!v ? "true" : undefined));
|
const toggleDevMode = async (): Promise<void> => setter((v) => (!v ? "true" : undefined));
|
||||||
children =
|
children =
|
||||||
children.length === 1 && typeof children === "function"
|
children.length === 1 && typeof children === "function"
|
||||||
? children({ devMode })
|
? children({ devMode })
|
||||||
|
@ -44,13 +44,14 @@ import {
|
|||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { ButtonHandler } from "../mui/handlers.js";
|
import { ButtonHandler } from "../mui/handlers.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
talerDepositUri?: string;
|
talerDepositUri?: string;
|
||||||
amount: AmountString;
|
amount: AmountString;
|
||||||
goBack: () => void;
|
goBack: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = Loading | Ready | Completed;
|
type State = Loading | Ready | Completed;
|
||||||
@ -206,11 +207,15 @@ export function View({ state }: ViewProps): VNode {
|
|||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess upperCased onClick={state.confirm.onClick}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={state.confirm.onClick}
|
||||||
|
>
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
Deposit {<Amount value={state.effective} />}
|
Deposit {<Amount value={state.effective} />}
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
</WalletAction>
|
</WalletAction>
|
||||||
);
|
);
|
||||||
|
@ -33,6 +33,10 @@ export default {
|
|||||||
argTypes: {},
|
argTypes: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const noop = async (): Promise<void> => {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
export const NoBalance = createExample(TestedComponent, {
|
export const NoBalance = createExample(TestedComponent, {
|
||||||
state: {
|
state: {
|
||||||
status: "ready",
|
status: "ready",
|
||||||
@ -61,8 +65,8 @@ export const NoBalance = createExample(TestedComponent, {
|
|||||||
amountRaw: "USD:10",
|
amountRaw: "USD:10",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const NoEnoughBalance = createExample(TestedComponent, {
|
export const NoEnoughBalance = createExample(TestedComponent, {
|
||||||
@ -97,8 +101,8 @@ export const NoEnoughBalance = createExample(TestedComponent, {
|
|||||||
amountRaw: "USD:10",
|
amountRaw: "USD:10",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const EnoughBalanceButRestricted = createExample(TestedComponent, {
|
export const EnoughBalanceButRestricted = createExample(TestedComponent, {
|
||||||
@ -133,8 +137,8 @@ export const EnoughBalanceButRestricted = createExample(TestedComponent, {
|
|||||||
amountRaw: "USD:10",
|
amountRaw: "USD:10",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PaymentPossible = createExample(TestedComponent, {
|
export const PaymentPossible = createExample(TestedComponent, {
|
||||||
@ -172,8 +176,8 @@ export const PaymentPossible = createExample(TestedComponent, {
|
|||||||
proposalId: "proposal1234",
|
proposalId: "proposal1234",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const PaymentPossibleWithFee = createExample(TestedComponent, {
|
export const PaymentPossibleWithFee = createExample(TestedComponent, {
|
||||||
@ -211,8 +215,8 @@ export const PaymentPossibleWithFee = createExample(TestedComponent, {
|
|||||||
proposalId: "proposal1234",
|
proposalId: "proposal1234",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
import beer from "../../static-dev/beer.png";
|
import beer from "../../static-dev/beer.png";
|
||||||
@ -271,8 +275,8 @@ export const TicketWithAProductList = createExample(TestedComponent, {
|
|||||||
proposalId: "proposal1234",
|
proposalId: "proposal1234",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AlreadyConfirmedByOther = createExample(TestedComponent, {
|
export const AlreadyConfirmedByOther = createExample(TestedComponent, {
|
||||||
@ -309,8 +313,8 @@ export const AlreadyConfirmedByOther = createExample(TestedComponent, {
|
|||||||
paid: false,
|
paid: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AlreadyPaidWithoutFulfillment = createExample(TestedComponent, {
|
export const AlreadyPaidWithoutFulfillment = createExample(TestedComponent, {
|
||||||
@ -347,8 +351,8 @@ export const AlreadyPaidWithoutFulfillment = createExample(TestedComponent, {
|
|||||||
paid: true,
|
paid: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
|
||||||
export const AlreadyPaidWithFulfillment = createExample(TestedComponent, {
|
export const AlreadyPaidWithFulfillment = createExample(TestedComponent, {
|
||||||
@ -387,6 +391,6 @@ export const AlreadyPaidWithFulfillment = createExample(TestedComponent, {
|
|||||||
paid: true,
|
paid: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
goBack: () => null,
|
goBack: noop,
|
||||||
goToWalletManualWithdraw: () => null,
|
goToWalletManualWithdraw: noop,
|
||||||
});
|
});
|
||||||
|
@ -60,13 +60,14 @@ import {
|
|||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { ButtonHandler } from "../mui/handlers.js";
|
import { ButtonHandler } from "../mui/handlers.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
talerPayUri?: string;
|
talerPayUri?: string;
|
||||||
goToWalletManualWithdraw: (currency?: string) => void;
|
goToWalletManualWithdraw: (currency?: string) => Promise<void>;
|
||||||
goBack: () => void;
|
goBack: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
type State = Loading | Ready | Confirmed;
|
type State = Loading | Ready | Confirmed;
|
||||||
@ -265,8 +266,8 @@ export function View({
|
|||||||
goToWalletManualWithdraw,
|
goToWalletManualWithdraw,
|
||||||
}: {
|
}: {
|
||||||
state: Ready | Confirmed;
|
state: Ready | Confirmed;
|
||||||
goToWalletManualWithdraw: (currency?: string) => void;
|
goToWalletManualWithdraw: (currency?: string) => Promise<void>;
|
||||||
goBack: () => void;
|
goBack: () => Promise<void>;
|
||||||
}): VNode {
|
}): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
const contractTerms: ContractTerms = state.payStatus.contractTerms;
|
const contractTerms: ContractTerms = state.payStatus.contractTerms;
|
||||||
@ -522,7 +523,7 @@ function ButtonsSection({
|
|||||||
goToWalletManualWithdraw,
|
goToWalletManualWithdraw,
|
||||||
}: {
|
}: {
|
||||||
state: Ready | Confirmed;
|
state: Ready | Confirmed;
|
||||||
goToWalletManualWithdraw: (currency: string) => void;
|
goToWalletManualWithdraw: (currency: string) => Promise<void>;
|
||||||
}): VNode {
|
}): VNode {
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
if (state.status === "ready") {
|
if (state.status === "ready") {
|
||||||
@ -531,11 +532,15 @@ function ButtonsSection({
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess upperCased onClick={state.payHandler.onClick}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={state.payHandler.onClick}
|
||||||
|
>
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
Pay {<Amount value={payStatus.amountEffective} />}
|
Pay {<Amount value={payStatus.amountEffective} />}
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
<PayWithMobile state={state} />
|
<PayWithMobile state={state} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
@ -560,12 +565,13 @@ function ButtonsSection({
|
|||||||
<WarningBox>{BalanceMessage}</WarningBox>
|
<WarningBox>{BalanceMessage}</WarningBox>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess
|
<Button
|
||||||
upperCased
|
variant="contained"
|
||||||
|
color="success"
|
||||||
onClick={() => goToWalletManualWithdraw(state.amount.currency)}
|
onClick={() => goToWalletManualWithdraw(state.amount.currency)}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Withdraw digital cash</i18n.Translate>
|
<i18n.Translate>Withdraw digital cash</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
<PayWithMobile state={state} />
|
<PayWithMobile state={state} />
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -40,6 +40,7 @@ import {
|
|||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { ButtonHandler } from "../mui/handlers.js";
|
import { ButtonHandler } from "../mui/handlers.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
import { ProductList } from "./Pay.js";
|
import { ProductList } from "./Pay.js";
|
||||||
@ -188,9 +189,9 @@ export function View({ state }: ViewProps): VNode {
|
|||||||
</section>
|
</section>
|
||||||
) : undefined}
|
) : undefined}
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess onClick={state.accept.onClick}>
|
<Button variant="contained" onClick={state.accept.onClick}>
|
||||||
<i18n.Translate>Confirm refund</i18n.Translate>
|
<i18n.Translate>Confirm refund</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
</WalletAction>
|
</WalletAction>
|
||||||
);
|
);
|
||||||
|
@ -2,14 +2,13 @@ import { Fragment, h, VNode } from "preact";
|
|||||||
import { CheckboxOutlined } from "../components/CheckboxOutlined.js";
|
import { CheckboxOutlined } from "../components/CheckboxOutlined.js";
|
||||||
import { ExchangeXmlTos } from "../components/ExchangeToS.js";
|
import { ExchangeXmlTos } from "../components/ExchangeToS.js";
|
||||||
import {
|
import {
|
||||||
ButtonSuccess,
|
|
||||||
ButtonWarning,
|
|
||||||
LinkSuccess,
|
LinkSuccess,
|
||||||
TermsOfService,
|
TermsOfService,
|
||||||
WarningBox,
|
WarningBox,
|
||||||
WarningText,
|
WarningText,
|
||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { TermsState } from "../utils/index.js";
|
import { TermsState } from "../utils/index.js";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
@ -58,20 +57,28 @@ export function TermsOfServiceSection({
|
|||||||
)}
|
)}
|
||||||
{terms.status === "new" && (
|
{terms.status === "new" && (
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess upperCased onClick={() => onReview(true)}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={async () => onReview(true)}
|
||||||
|
>
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
Review exchange terms of service
|
Review exchange terms of service
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
{terms.status === "changed" && (
|
{terms.status === "changed" && (
|
||||||
<section>
|
<section>
|
||||||
<ButtonWarning upperCased onClick={() => onReview(true)}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={async () => onReview(true)}
|
||||||
|
>
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
Review new version of terms of service
|
Review new version of terms of service
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</ButtonWarning>
|
</Button>
|
||||||
</section>
|
</section>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
@ -95,7 +102,7 @@ export function TermsOfServiceSection({
|
|||||||
I accept the exchange terms of service
|
I accept the exchange terms of service
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
}
|
}
|
||||||
onToggle={() => {
|
onToggle={async () => {
|
||||||
onAccept(!reviewed);
|
onAccept(!reviewed);
|
||||||
if (ableToReviewTermsOfService) onReview(false);
|
if (ableToReviewTermsOfService) onReview(false);
|
||||||
}}
|
}}
|
||||||
@ -154,7 +161,7 @@ export function TermsOfServiceSection({
|
|||||||
I accept the exchange terms of service
|
I accept the exchange terms of service
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
}
|
}
|
||||||
onToggle={() => {
|
onToggle={async () => {
|
||||||
onAccept(!reviewed);
|
onAccept(!reviewed);
|
||||||
if (ableToReviewTermsOfService) onReview(false);
|
if (ableToReviewTermsOfService) onReview(false);
|
||||||
}}
|
}}
|
||||||
|
@ -210,9 +210,13 @@ export function View({ state }: { state: State }): VNode {
|
|||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
<ButtonSuccess onClick={state.accept.onClick}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={state.accept.onClick}
|
||||||
|
>
|
||||||
<i18n.Translate>Accept tip</i18n.Translate>
|
<i18n.Translate>Accept tip</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
<Button onClick={state.ignore.onClick}>
|
<Button onClick={state.ignore.onClick}>
|
||||||
<i18n.Translate>Ignore</i18n.Translate>
|
<i18n.Translate>Ignore</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
|
@ -33,8 +33,6 @@ import { LogoHeader } from "../components/LogoHeader.js";
|
|||||||
import { Part } from "../components/Part.js";
|
import { Part } from "../components/Part.js";
|
||||||
import { SelectList } from "../components/SelectList.js";
|
import { SelectList } from "../components/SelectList.js";
|
||||||
import {
|
import {
|
||||||
ButtonSuccess,
|
|
||||||
ButtonWarning,
|
|
||||||
Input,
|
Input,
|
||||||
LinkSuccess,
|
LinkSuccess,
|
||||||
SubTitle,
|
SubTitle,
|
||||||
@ -43,19 +41,14 @@ import {
|
|||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
import { ButtonHandler, SelectFieldHandler } from "../mui/handlers.js";
|
||||||
import { buildTermsOfServiceState } from "../utils/index.js";
|
import { buildTermsOfServiceState } from "../utils/index.js";
|
||||||
import {
|
|
||||||
ButtonHandler,
|
|
||||||
SelectFieldHandler,
|
|
||||||
ToggleHandler,
|
|
||||||
} from "../mui/handlers.js";
|
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
import {
|
import {
|
||||||
Props as TermsOfServiceSectionProps,
|
Props as TermsOfServiceSectionProps,
|
||||||
TermsOfServiceSection,
|
TermsOfServiceSection,
|
||||||
} from "./TermsOfServiceSection.js";
|
} from "./TermsOfServiceSection.js";
|
||||||
import { startOfWeekYear } from "date-fns/esm";
|
|
||||||
import { Checkbox } from "../components/Checkbox.js";
|
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
talerWithdrawUri?: string;
|
talerWithdrawUri?: string;
|
||||||
@ -527,22 +520,24 @@ export function View({ state }: { state: State }): VNode {
|
|||||||
<section>
|
<section>
|
||||||
{(state.tosProps.terms.status === "accepted" ||
|
{(state.tosProps.terms.status === "accepted" ||
|
||||||
(state.mustAcceptFirst && state.tosProps.reviewed)) && (
|
(state.mustAcceptFirst && state.tosProps.reviewed)) && (
|
||||||
<ButtonSuccess
|
<Button
|
||||||
upperCased
|
variant="contained"
|
||||||
|
color="success"
|
||||||
disabled={!state.doWithdrawal.onClick}
|
disabled={!state.doWithdrawal.onClick}
|
||||||
onClick={state.doWithdrawal.onClick}
|
onClick={state.doWithdrawal.onClick}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Confirm withdrawal</i18n.Translate>
|
<i18n.Translate>Confirm withdrawal</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{state.tosProps.terms.status === "notfound" && (
|
{state.tosProps.terms.status === "notfound" && (
|
||||||
<ButtonWarning
|
<Button
|
||||||
upperCased
|
variant="contained"
|
||||||
|
color="warning"
|
||||||
disabled={!state.doWithdrawal.onClick}
|
disabled={!state.doWithdrawal.onClick}
|
||||||
onClick={state.doWithdrawal.onClick}
|
onClick={state.doWithdrawal.onClick}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Withdraw anyway</i18n.Translate>
|
<i18n.Translate>Withdraw anyway</i18n.Translate>
|
||||||
</ButtonWarning>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
) : (
|
) : (
|
||||||
|
@ -68,18 +68,22 @@ export const WithTitle = (): VNode => (
|
|||||||
</Wrapper>
|
</Wrapper>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const showSomething = async function (): Promise<void> {
|
||||||
|
alert("closed");
|
||||||
|
};
|
||||||
|
|
||||||
export const WithAction = (): VNode => (
|
export const WithAction = (): VNode => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
<Alert title="Warning" severity="warning" onClose={() => alert("closed")}>
|
<Alert title="Warning" severity="warning" onClose={showSomething}>
|
||||||
this is an warning
|
this is an warning
|
||||||
</Alert>
|
</Alert>
|
||||||
<Alert title="Error" severity="error" onClose={() => alert("closed")}>
|
<Alert title="Error" severity="error" onClose={showSomething}>
|
||||||
this is an error
|
this is an error
|
||||||
</Alert>
|
</Alert>
|
||||||
<Alert title="Success" severity="success" onClose={() => alert("closed")}>
|
<Alert title="Success" severity="success" onClose={showSomething}>
|
||||||
this is an success
|
this is an success
|
||||||
</Alert>
|
</Alert>
|
||||||
<Alert title="Info" severity="info" onClose={() => alert("closed")}>
|
<Alert title="Info" severity="info" onClose={showSomething}>
|
||||||
this is an info
|
this is an info
|
||||||
</Alert>
|
</Alert>
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
@ -49,7 +49,7 @@ interface Props {
|
|||||||
title?: string;
|
title?: string;
|
||||||
variant?: "filled" | "outlined" | "standard";
|
variant?: "filled" | "outlined" | "standard";
|
||||||
role?: string;
|
role?: string;
|
||||||
onClose?: () => void;
|
onClose?: () => Promise<void>;
|
||||||
// icon: VNode;
|
// icon: VNode;
|
||||||
severity?: "info" | "warning" | "success" | "error";
|
severity?: "info" | "warning" | "success" | "error";
|
||||||
children: ComponentChildren;
|
children: ComponentChildren;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { ComponentChildren, h, VNode, JSX } from "preact";
|
import { ComponentChildren, h, VNode, JSX } from "preact";
|
||||||
import { css } from "@linaria/core";
|
import { css } from "@linaria/core";
|
||||||
// eslint-disable-next-line import/extensions
|
// eslint-disable-next-line import/extensions
|
||||||
import { theme, ripple, Colors } from "./style";
|
import { theme, ripple, Colors, rippleOutlined } from "./style";
|
||||||
// eslint-disable-next-line import/extensions
|
// eslint-disable-next-line import/extensions
|
||||||
import { alpha } from "./colors/manipulation";
|
import { alpha } from "./colors/manipulation";
|
||||||
|
|
||||||
@ -31,12 +31,13 @@ interface Props {
|
|||||||
disableFocusRipple?: boolean;
|
disableFocusRipple?: boolean;
|
||||||
endIcon?: string | VNode;
|
endIcon?: string | VNode;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
|
style?: h.JSX.CSSProperties;
|
||||||
href?: string;
|
href?: string;
|
||||||
size?: "small" | "medium" | "large";
|
size?: "small" | "medium" | "large";
|
||||||
startIcon?: VNode | string;
|
startIcon?: VNode | string;
|
||||||
variant?: "contained" | "outlined" | "text";
|
variant?: "contained" | "outlined" | "text";
|
||||||
color?: Colors;
|
color?: Colors;
|
||||||
onClick?: () => void;
|
onClick?: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const button = css`
|
const button = css`
|
||||||
@ -199,6 +200,7 @@ export function Button({
|
|||||||
fullWidth,
|
fullWidth,
|
||||||
variant = "text",
|
variant = "text",
|
||||||
size = "medium",
|
size = "medium",
|
||||||
|
style: parentStyle,
|
||||||
color = "primary",
|
color = "primary",
|
||||||
onClick,
|
onClick,
|
||||||
}: Props): VNode {
|
}: Props): VNode {
|
||||||
@ -267,12 +269,15 @@ export function Button({
|
|||||||
colorVariant[variant],
|
colorVariant[variant],
|
||||||
sizeVariant[variant][size],
|
sizeVariant[variant][size],
|
||||||
].join(" ")}
|
].join(" ")}
|
||||||
|
containedRipple={variant === "contained"}
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
style={{
|
style={{
|
||||||
|
...parentStyle,
|
||||||
"--color-main": theme.palette[color].main,
|
"--color-main": theme.palette[color].main,
|
||||||
"--color-contrastText": theme.palette[color].contrastText,
|
"--color-contrastText": theme.palette[color].contrastText,
|
||||||
"--color-main-alpha-half": alpha(theme.palette[color].main, 0.5),
|
"--color-main-alpha-half": alpha(theme.palette[color].main, 0.5),
|
||||||
"--color-dark": theme.palette[color].dark,
|
"--color-dark": theme.palette[color].dark,
|
||||||
|
"--color-light": theme.palette[color].light,
|
||||||
"--color-main-alpha-opacity": alpha(
|
"--color-main-alpha-opacity": alpha(
|
||||||
theme.palette[color].main,
|
theme.palette[color].main,
|
||||||
theme.palette.action.hoverOpacity,
|
theme.palette.action.hoverOpacity,
|
||||||
@ -295,13 +300,15 @@ export function Button({
|
|||||||
|
|
||||||
interface BaseProps extends JSX.HTMLAttributes<HTMLButtonElement> {
|
interface BaseProps extends JSX.HTMLAttributes<HTMLButtonElement> {
|
||||||
class: string;
|
class: string;
|
||||||
onClick?: () => void;
|
onClick?: () => Promise<void>;
|
||||||
|
containedRipple?: boolean;
|
||||||
children?: ComponentChildren;
|
children?: ComponentChildren;
|
||||||
}
|
}
|
||||||
|
|
||||||
function ButtonBase({
|
function ButtonBase({
|
||||||
class: _class,
|
class: _class,
|
||||||
children,
|
children,
|
||||||
|
containedRipple,
|
||||||
onClick,
|
onClick,
|
||||||
dangerouslySetInnerHTML,
|
dangerouslySetInnerHTML,
|
||||||
...rest
|
...rest
|
||||||
@ -309,7 +316,11 @@ function ButtonBase({
|
|||||||
function doClick(): void {
|
function doClick(): void {
|
||||||
if (onClick) onClick();
|
if (onClick) onClick();
|
||||||
}
|
}
|
||||||
const classNames = [buttonBaseStyle, _class, ripple].join(" ");
|
const classNames = [
|
||||||
|
buttonBaseStyle,
|
||||||
|
_class,
|
||||||
|
containedRipple ? ripple : rippleOutlined,
|
||||||
|
].join(" ");
|
||||||
if (dangerouslySetInnerHTML) {
|
if (dangerouslySetInnerHTML) {
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
@ -332,7 +343,7 @@ export function IconButton({
|
|||||||
onClick,
|
onClick,
|
||||||
}: {
|
}: {
|
||||||
svg: any;
|
svg: any;
|
||||||
onClick?: () => void;
|
onClick?: () => Promise<void>;
|
||||||
}): VNode {
|
}): VNode {
|
||||||
return (
|
return (
|
||||||
<ButtonBase
|
<ButtonBase
|
||||||
|
@ -46,13 +46,33 @@ export const theme = createTheme();
|
|||||||
export const ripple = css`
|
export const ripple = css`
|
||||||
background-position: center;
|
background-position: center;
|
||||||
|
|
||||||
transition: background 0.5s;
|
transition: background 0.2s;
|
||||||
&:hover {
|
|
||||||
background: #eeeeee radial-gradient(circle, transparent 1%, #eeeeee 1%)
|
&:hover:enabled {
|
||||||
|
background: var(--color-main)
|
||||||
|
radial-gradient(circle, transparent 1%, var(--color-dark) 1%)
|
||||||
center/15000%;
|
center/15000%;
|
||||||
}
|
}
|
||||||
&:active {
|
&:active:enabled {
|
||||||
background-color: currentColor;
|
background-color: var(--color-main);
|
||||||
|
background-size: 100%;
|
||||||
|
transition: background 0s;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
export const rippleOutlined = css`
|
||||||
|
background-position: center;
|
||||||
|
|
||||||
|
transition: background 0.2s;
|
||||||
|
|
||||||
|
&:hover:enabled {
|
||||||
|
background: var(--color-contrastText)
|
||||||
|
radial-gradient(circle, transparent 1%, var(--color-light) 1%)
|
||||||
|
center/15000%;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:active:enabled {
|
||||||
|
background-color: var(--color-contrastText);
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
transition: background 0s;
|
transition: background 0s;
|
||||||
}
|
}
|
||||||
@ -680,15 +700,15 @@ function createTheme() {
|
|||||||
function getDefaultSecondary(mode = "light") {
|
function getDefaultSecondary(mode = "light") {
|
||||||
if (mode === "dark") {
|
if (mode === "dark") {
|
||||||
return {
|
return {
|
||||||
main: purple[200],
|
main: grey[200],
|
||||||
light: purple[50],
|
light: grey[50],
|
||||||
dark: purple[400],
|
dark: grey[400],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return {
|
return {
|
||||||
main: purple[500],
|
main: grey[300],
|
||||||
light: purple[300],
|
light: grey[100],
|
||||||
dark: purple[700],
|
dark: grey[600],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ export function Application(): VNode {
|
|||||||
<IoCProviderForRuntime>
|
<IoCProviderForRuntime>
|
||||||
<PendingTransactions
|
<PendingTransactions
|
||||||
goToTransaction={(txId: string) =>
|
goToTransaction={(txId: string) =>
|
||||||
route(Pages.balance_transaction.replace(":tid", txId))
|
redirectTo(Pages.balance_transaction.replace(":tid", txId))
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<Match>
|
<Match>
|
||||||
@ -74,15 +74,19 @@ export function Application(): VNode {
|
|||||||
path={Pages.balance}
|
path={Pages.balance}
|
||||||
component={BalancePage}
|
component={BalancePage}
|
||||||
goToWalletManualWithdraw={() =>
|
goToWalletManualWithdraw={() =>
|
||||||
route(
|
redirectTo(
|
||||||
Pages.balance_manual_withdraw.replace(":currency?", ""),
|
Pages.balance_manual_withdraw.replace(":currency?", ""),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
goToWalletDeposit={(currency: string) =>
|
goToWalletDeposit={(currency: string) =>
|
||||||
route(Pages.balance_deposit.replace(":currency", currency))
|
redirectTo(
|
||||||
|
Pages.balance_deposit.replace(":currency", currency),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
goToWalletHistory={(currency: string) =>
|
goToWalletHistory={(currency: string) =>
|
||||||
route(Pages.balance_history.replace(":currency?", currency))
|
redirectTo(
|
||||||
|
Pages.balance_history.replace(":currency?", currency),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -96,7 +100,7 @@ export function Application(): VNode {
|
|||||||
url={decodeURIComponent(action)}
|
url={decodeURIComponent(action)}
|
||||||
onDismiss={() => {
|
onDismiss={() => {
|
||||||
setDismissed(true);
|
setDismissed(true);
|
||||||
route(Pages.balance);
|
return redirectTo(Pages.balance);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -106,16 +110,12 @@ export function Application(): VNode {
|
|||||||
<Route
|
<Route
|
||||||
path={Pages.backup}
|
path={Pages.backup}
|
||||||
component={BackupPage}
|
component={BackupPage}
|
||||||
onAddProvider={() => {
|
onAddProvider={() => redirectTo(Pages.backup_provider_add)}
|
||||||
route(Pages.backup_provider_add);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={Pages.backup_provider_detail}
|
path={Pages.backup_provider_detail}
|
||||||
component={ProviderDetailPage}
|
component={ProviderDetailPage}
|
||||||
onBack={() => {
|
onBack={() => redirectTo(Pages.backup)}
|
||||||
route(Pages.backup);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
@ -175,6 +175,10 @@ function RedirectToWalletPage(): VNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function redirectTo(location: string): Promise<void> {
|
||||||
|
route(location);
|
||||||
|
}
|
||||||
|
|
||||||
function Redirect({ to }: { to: string }): null {
|
function Redirect({ to }: { to: string }): null {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
route(to, true);
|
route(to, true);
|
||||||
|
@ -22,17 +22,17 @@ import { JustInDevMode } from "../components/JustInDevMode.js";
|
|||||||
import { Loading } from "../components/Loading.js";
|
import { Loading } from "../components/Loading.js";
|
||||||
import { LoadingError } from "../components/LoadingError.js";
|
import { LoadingError } from "../components/LoadingError.js";
|
||||||
import { MultiActionButton } from "../components/MultiActionButton.js";
|
import { MultiActionButton } from "../components/MultiActionButton.js";
|
||||||
import { ButtonBoxPrimary, ButtonPrimary } from "../components/styled/index.js";
|
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { AddNewActionView } from "../wallet/AddNewActionView.js";
|
import { AddNewActionView } from "../wallet/AddNewActionView.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
import { NoBalanceHelp } from "./NoBalanceHelp.js";
|
import { NoBalanceHelp } from "./NoBalanceHelp.js";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
goToWalletDeposit: (currency: string) => void;
|
goToWalletDeposit: (currency: string) => Promise<void>;
|
||||||
goToWalletHistory: (currency: string) => void;
|
goToWalletHistory: (currency: string) => Promise<void>;
|
||||||
goToWalletManualWithdraw: () => void;
|
goToWalletManualWithdraw: () => Promise<void>;
|
||||||
}
|
}
|
||||||
export function BalancePage({
|
export function BalancePage({
|
||||||
goToWalletManualWithdraw,
|
goToWalletManualWithdraw,
|
||||||
@ -65,7 +65,7 @@ export function BalancePage({
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (addingAction) {
|
if (addingAction) {
|
||||||
return <AddNewActionView onCancel={() => setAddingAction(false)} />;
|
return <AddNewActionView onCancel={async () => setAddingAction(false)} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -74,16 +74,16 @@ export function BalancePage({
|
|||||||
goToWalletManualWithdraw={goToWalletManualWithdraw}
|
goToWalletManualWithdraw={goToWalletManualWithdraw}
|
||||||
goToWalletDeposit={goToWalletDeposit}
|
goToWalletDeposit={goToWalletDeposit}
|
||||||
goToWalletHistory={goToWalletHistory}
|
goToWalletHistory={goToWalletHistory}
|
||||||
goToAddAction={() => setAddingAction(true)}
|
goToAddAction={async () => setAddingAction(true)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
export interface BalanceViewProps {
|
export interface BalanceViewProps {
|
||||||
balances: Balance[];
|
balances: Balance[];
|
||||||
goToWalletManualWithdraw: () => void;
|
goToWalletManualWithdraw: () => Promise<void>;
|
||||||
goToAddAction: () => void;
|
goToAddAction: () => Promise<void>;
|
||||||
goToWalletDeposit: (currency: string) => void;
|
goToWalletDeposit: (currency: string) => Promise<void>;
|
||||||
goToWalletHistory: (currency: string) => void;
|
goToWalletHistory: (currency: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BalanceView({
|
export function BalanceView({
|
||||||
@ -113,22 +113,20 @@ export function BalanceView({
|
|||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<footer style={{ justifyContent: "space-between" }}>
|
<footer style={{ justifyContent: "space-between" }}>
|
||||||
<ButtonPrimary onClick={goToWalletManualWithdraw}>
|
<Button variant="contained" onClick={goToWalletManualWithdraw}>
|
||||||
<i18n.Translate>Withdraw</i18n.Translate>
|
<i18n.Translate>Withdraw</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
{currencyWithNonZeroAmount.length > 0 && (
|
{currencyWithNonZeroAmount.length > 0 && (
|
||||||
<MultiActionButton
|
<MultiActionButton
|
||||||
label={(s) => (
|
label={(s) => <i18n.Translate>Deposit {s}</i18n.Translate>}
|
||||||
<i18n.Translate>Deposit {<span>{s}</span>}</i18n.Translate>
|
|
||||||
)}
|
|
||||||
actions={currencyWithNonZeroAmount}
|
actions={currencyWithNonZeroAmount}
|
||||||
onClick={(c) => goToWalletDeposit(c)}
|
onClick={(c) => goToWalletDeposit(c)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
<JustInDevMode>
|
<JustInDevMode>
|
||||||
<ButtonBoxPrimary onClick={goToAddAction}>
|
<Button onClick={goToAddAction}>
|
||||||
<i18n.Translate>Enter URI</i18n.Translate>
|
<i18n.Translate>Enter URI</i18n.Translate>
|
||||||
</ButtonBoxPrimary>
|
</Button>
|
||||||
</JustInDevMode>
|
</JustInDevMode>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -8,7 +8,7 @@ import { Typography } from "../mui/Typography.js";
|
|||||||
export function NoBalanceHelp({
|
export function NoBalanceHelp({
|
||||||
goToWalletManualWithdraw,
|
goToWalletManualWithdraw,
|
||||||
}: {
|
}: {
|
||||||
goToWalletManualWithdraw: () => void;
|
goToWalletManualWithdraw: () => Promise<void>;
|
||||||
}): VNode {
|
}): VNode {
|
||||||
return (
|
return (
|
||||||
<Paper
|
<Paper
|
||||||
|
@ -28,16 +28,17 @@ import {
|
|||||||
Title,
|
Title,
|
||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
url: string;
|
url: string;
|
||||||
onDismiss: () => void;
|
onDismiss: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
||||||
const uriType = classifyTalerUri(url);
|
const uriType = classifyTalerUri(url);
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
function redirectToWallet(): void {
|
async function redirectToWallet(): Promise<void> {
|
||||||
platform.openWalletURIFromPopup(url);
|
platform.openWalletURIFromPopup(url);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
@ -51,9 +52,13 @@ export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
|||||||
<p>
|
<p>
|
||||||
<i18n.Translate>This page has pay action.</i18n.Translate>
|
<i18n.Translate>This page has pay action.</i18n.Translate>
|
||||||
</p>
|
</p>
|
||||||
<ButtonSuccess onClick={redirectToWallet}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={redirectToWallet}
|
||||||
|
>
|
||||||
<i18n.Translate>Open pay page</i18n.Translate>
|
<i18n.Translate>Open pay page</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{uriType === TalerUriType.TalerWithdraw && (
|
{uriType === TalerUriType.TalerWithdraw && (
|
||||||
@ -63,9 +68,13 @@ export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
|||||||
This page has a withdrawal action.
|
This page has a withdrawal action.
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</p>
|
</p>
|
||||||
<ButtonSuccess onClick={redirectToWallet}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={redirectToWallet}
|
||||||
|
>
|
||||||
<i18n.Translate>Open withdraw page</i18n.Translate>
|
<i18n.Translate>Open withdraw page</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{uriType === TalerUriType.TalerTip && (
|
{uriType === TalerUriType.TalerTip && (
|
||||||
@ -73,9 +82,13 @@ export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
|||||||
<p>
|
<p>
|
||||||
<i18n.Translate>This page has a tip action.</i18n.Translate>
|
<i18n.Translate>This page has a tip action.</i18n.Translate>
|
||||||
</p>
|
</p>
|
||||||
<ButtonSuccess onClick={redirectToWallet}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={redirectToWallet}
|
||||||
|
>
|
||||||
<i18n.Translate>Open tip page</i18n.Translate>
|
<i18n.Translate>Open tip page</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{uriType === TalerUriType.TalerNotifyReserve && (
|
{uriType === TalerUriType.TalerNotifyReserve && (
|
||||||
@ -85,9 +98,13 @@ export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
|||||||
This page has a notify reserve action.
|
This page has a notify reserve action.
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</p>
|
</p>
|
||||||
<ButtonSuccess onClick={redirectToWallet}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={redirectToWallet}
|
||||||
|
>
|
||||||
<i18n.Translate>Notify</i18n.Translate>
|
<i18n.Translate>Notify</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{uriType === TalerUriType.TalerRefund && (
|
{uriType === TalerUriType.TalerRefund && (
|
||||||
@ -95,9 +112,13 @@ export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
|||||||
<p>
|
<p>
|
||||||
<i18n.Translate>This page has a refund action.</i18n.Translate>
|
<i18n.Translate>This page has a refund action.</i18n.Translate>
|
||||||
</p>
|
</p>
|
||||||
<ButtonSuccess onClick={redirectToWallet}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={redirectToWallet}
|
||||||
|
>
|
||||||
<i18n.Translate>Open refund page</i18n.Translate>
|
<i18n.Translate>Open refund page</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
{uriType === TalerUriType.Unknown && (
|
{uriType === TalerUriType.Unknown && (
|
||||||
@ -113,10 +134,9 @@ export function TalerActionFound({ url, onDismiss }: Props): VNode {
|
|||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<div />
|
<div />
|
||||||
<ButtonPrimary onClick={() => onDismiss()}>
|
<Button variant="contained" onClick={onDismiss}>
|
||||||
{" "}
|
<i18n.Translate>Dismiss</i18n.Translate>
|
||||||
<i18n.Translate>Dismiss</i18n.Translate>{" "}
|
</Button>
|
||||||
</ButtonPrimary>
|
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -2,15 +2,12 @@ import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util";
|
|||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { platform } from "../platform/api.js";
|
import { platform } from "../platform/api.js";
|
||||||
import {
|
import { InputWithLabel } from "../components/styled/index.js";
|
||||||
Button,
|
|
||||||
ButtonSuccess,
|
|
||||||
InputWithLabel,
|
|
||||||
} from "../components/styled/index.js";
|
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function AddNewActionView({ onCancel }: Props): VNode {
|
export function AddNewActionView({ onCancel }: Props): VNode {
|
||||||
@ -18,7 +15,7 @@ export function AddNewActionView({ onCancel }: Props): VNode {
|
|||||||
const uriType = classifyTalerUri(url);
|
const uriType = classifyTalerUri(url);
|
||||||
const { i18n } = useTranslationContext();
|
const { i18n } = useTranslationContext();
|
||||||
|
|
||||||
function redirectToWallet(): void {
|
async function redirectToWallet(): Promise<void> {
|
||||||
platform.openWalletURIFromPopup(url);
|
platform.openWalletURIFromPopup(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,11 +38,15 @@ export function AddNewActionView({ onCancel }: Props): VNode {
|
|||||||
</InputWithLabel>
|
</InputWithLabel>
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={onCancel}>
|
<Button variant="contained" color="secondary" onClick={onCancel}>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
{uriType !== TalerUriType.Unknown && (
|
{uriType !== TalerUriType.Unknown && (
|
||||||
<ButtonSuccess onClick={redirectToWallet}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
onClick={redirectToWallet}
|
||||||
|
>
|
||||||
{(() => {
|
{(() => {
|
||||||
switch (uriType) {
|
switch (uriType) {
|
||||||
case TalerUriType.TalerNotifyReserve:
|
case TalerUriType.TalerNotifyReserve:
|
||||||
@ -61,7 +62,7 @@ export function AddNewActionView({ onCancel }: Props): VNode {
|
|||||||
}
|
}
|
||||||
return <Fragment />;
|
return <Fragment />;
|
||||||
})()}
|
})()}
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -94,7 +94,9 @@ export function Application(): VNode {
|
|||||||
>
|
>
|
||||||
<PendingTransactions
|
<PendingTransactions
|
||||||
goToTransaction={(txId: string) =>
|
goToTransaction={(txId: string) =>
|
||||||
route(Pages.balance_transaction.replace(":tid", txId))
|
redirectTo(
|
||||||
|
Pages.balance_transaction.replace(":tid", txId),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@ -123,10 +125,12 @@ export function Application(): VNode {
|
|||||||
path={Pages.balance_history}
|
path={Pages.balance_history}
|
||||||
component={HistoryPage}
|
component={HistoryPage}
|
||||||
goToWalletDeposit={(currency: string) =>
|
goToWalletDeposit={(currency: string) =>
|
||||||
route(Pages.balance_deposit.replace(":currency", currency))
|
redirectTo(
|
||||||
|
Pages.balance_deposit.replace(":currency", currency),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
goToWalletManualWithdraw={(currency?: string) =>
|
goToWalletManualWithdraw={(currency?: string) =>
|
||||||
route(
|
redirectTo(
|
||||||
Pages.balance_manual_withdraw.replace(
|
Pages.balance_manual_withdraw.replace(
|
||||||
":currency?",
|
":currency?",
|
||||||
currency || "",
|
currency || "",
|
||||||
@ -137,29 +141,31 @@ export function Application(): VNode {
|
|||||||
<Route
|
<Route
|
||||||
path={Pages.balance_transaction}
|
path={Pages.balance_transaction}
|
||||||
component={TransactionPage}
|
component={TransactionPage}
|
||||||
goToWalletHistory={(currency?: string) => {
|
goToWalletHistory={(currency?: string) =>
|
||||||
route(
|
redirectTo(
|
||||||
Pages.balance_history.replace(":currency?", currency || ""),
|
Pages.balance_history.replace(":currency?", currency || ""),
|
||||||
);
|
)
|
||||||
}}
|
}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={Pages.balance_manual_withdraw}
|
path={Pages.balance_manual_withdraw}
|
||||||
component={ManualWithdrawPage}
|
component={ManualWithdrawPage}
|
||||||
onCancel={() => {
|
onCancel={() => redirectTo(Pages.balance)}
|
||||||
route(Pages.balance);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Route
|
<Route
|
||||||
path={Pages.balance_deposit}
|
path={Pages.balance_deposit}
|
||||||
component={DepositPage}
|
component={DepositPage}
|
||||||
onCancel={(currency: string) => {
|
onCancel={(currency: string) => {
|
||||||
route(Pages.balance_history.replace(":currency?", currency));
|
redirectTo(
|
||||||
|
Pages.balance_history.replace(":currency?", currency),
|
||||||
|
);
|
||||||
}}
|
}}
|
||||||
onSuccess={(currency: string) => {
|
onSuccess={(currency: string) => {
|
||||||
route(Pages.balance_history.replace(":currency?", currency));
|
redirectTo(
|
||||||
|
Pages.balance_history.replace(":currency?", currency),
|
||||||
|
);
|
||||||
setGlobalNotification(
|
setGlobalNotification(
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
All done, your transaction is in progress
|
All done, your transaction is in progress
|
||||||
@ -178,23 +184,17 @@ export function Application(): VNode {
|
|||||||
<Route
|
<Route
|
||||||
path={Pages.backup}
|
path={Pages.backup}
|
||||||
component={BackupPage}
|
component={BackupPage}
|
||||||
onAddProvider={() => {
|
onAddProvider={() => redirectTo(Pages.backup_provider_add)}
|
||||||
route(Pages.backup_provider_add);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={Pages.backup_provider_detail}
|
path={Pages.backup_provider_detail}
|
||||||
component={ProviderDetailPage}
|
component={ProviderDetailPage}
|
||||||
onBack={() => {
|
onBack={() => redirectTo(Pages.backup)}
|
||||||
route(Pages.backup);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
<Route
|
<Route
|
||||||
path={Pages.backup_provider_add}
|
path={Pages.backup_provider_add}
|
||||||
component={ProviderAddPage}
|
component={ProviderAddPage}
|
||||||
onBack={() => {
|
onBack={() => redirectTo(Pages.backup)}
|
||||||
route(Pages.backup);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/**
|
{/**
|
||||||
@ -203,9 +203,7 @@ export function Application(): VNode {
|
|||||||
<Route
|
<Route
|
||||||
path={Pages.settings_exchange_add}
|
path={Pages.settings_exchange_add}
|
||||||
component={ExchangeAddPage}
|
component={ExchangeAddPage}
|
||||||
onBack={() => {
|
onBack={() => redirectTo(Pages.balance)}
|
||||||
route(Pages.balance);
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/**
|
{/**
|
||||||
@ -221,14 +219,14 @@ export function Application(): VNode {
|
|||||||
path={Pages.cta_pay}
|
path={Pages.cta_pay}
|
||||||
component={PayPage}
|
component={PayPage}
|
||||||
goToWalletManualWithdraw={(currency?: string) =>
|
goToWalletManualWithdraw={(currency?: string) =>
|
||||||
route(
|
redirectTo(
|
||||||
Pages.balance_manual_withdraw.replace(
|
Pages.balance_manual_withdraw.replace(
|
||||||
":currency?",
|
":currency?",
|
||||||
currency || "",
|
currency || "",
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
goBack={() => route(Pages.balance)}
|
goBack={() => redirectTo(Pages.balance)}
|
||||||
/>
|
/>
|
||||||
<Route path={Pages.cta_refund} component={RefundPage} />
|
<Route path={Pages.cta_refund} component={RefundPage} />
|
||||||
<Route path={Pages.cta_tips} component={TipPage} />
|
<Route path={Pages.cta_tips} component={TipPage} />
|
||||||
@ -258,9 +256,12 @@ export function Application(): VNode {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function redirectTo(location: string): Promise<void> {
|
||||||
|
route(location);
|
||||||
|
}
|
||||||
|
|
||||||
function Redirect({ to }: { to: string }): null {
|
function Redirect({ to }: { to: string }): null {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.log("got some wrong route", to);
|
|
||||||
route(to, true);
|
route(to, true);
|
||||||
});
|
});
|
||||||
return null;
|
return null;
|
||||||
|
@ -31,8 +31,6 @@ import { Loading } from "../components/Loading.js";
|
|||||||
import { LoadingError } from "../components/LoadingError.js";
|
import { LoadingError } from "../components/LoadingError.js";
|
||||||
import {
|
import {
|
||||||
BoldLight,
|
BoldLight,
|
||||||
ButtonPrimary,
|
|
||||||
ButtonSuccess,
|
|
||||||
Centered,
|
Centered,
|
||||||
CenteredBoldText,
|
CenteredBoldText,
|
||||||
CenteredText,
|
CenteredText,
|
||||||
@ -42,11 +40,12 @@ import {
|
|||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { Pages } from "../NavigationBar.js";
|
import { Pages } from "../NavigationBar.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
onAddProvider: () => void;
|
onAddProvider: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BackupPage({ onAddProvider }: Props): VNode {
|
export function BackupPage({ onAddProvider }: Props): VNode {
|
||||||
@ -87,7 +86,7 @@ export function BackupPage({ onAddProvider }: Props): VNode {
|
|||||||
|
|
||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
providers: ProviderInfo[];
|
providers: ProviderInfo[];
|
||||||
onAddProvider: () => void;
|
onAddProvider: () => Promise<void>;
|
||||||
onSyncAll: () => Promise<void>;
|
onSyncAll: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,9 +120,9 @@ export function BackupView({
|
|||||||
<BoldLight>
|
<BoldLight>
|
||||||
<i18n.Translate>No backup providers configured</i18n.Translate>
|
<i18n.Translate>No backup providers configured</i18n.Translate>
|
||||||
</BoldLight>
|
</BoldLight>
|
||||||
<ButtonSuccess onClick={onAddProvider}>
|
<Button variant="contained" color="success" onClick={onAddProvider}>
|
||||||
<i18n.Translate>Add provider</i18n.Translate>
|
<i18n.Translate>Add provider</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</Centered>
|
</Centered>
|
||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
@ -131,16 +130,16 @@ export function BackupView({
|
|||||||
<footer>
|
<footer>
|
||||||
<div />
|
<div />
|
||||||
<div>
|
<div>
|
||||||
<ButtonPrimary onClick={onSyncAll}>
|
<Button variant="contained" onClick={onSyncAll}>
|
||||||
{providers.length > 1 ? (
|
{providers.length > 1 ? (
|
||||||
<i18n.Translate>Sync all backups</i18n.Translate>
|
<i18n.Translate>Sync all backups</i18n.Translate>
|
||||||
) : (
|
) : (
|
||||||
<i18n.Translate>Sync now</i18n.Translate>
|
<i18n.Translate>Sync now</i18n.Translate>
|
||||||
)}
|
)}
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
<ButtonSuccess onClick={onAddProvider}>
|
<Button variant="contained" color="success" onClick={onAddProvider}>
|
||||||
<i18n.Translate>Add provider</i18n.Translate>
|
<i18n.Translate>Add provider</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
)}
|
)}
|
||||||
|
@ -21,14 +21,12 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import { AmountJson, Amounts } from "@gnu-taler/taler-util";
|
import { AmountJson, Amounts } from "@gnu-taler/taler-util";
|
||||||
import { TalerError } from "@gnu-taler/taler-wallet-core";
|
|
||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import { ErrorMessage } from "../components/ErrorMessage.js";
|
import { ErrorMessage } from "../components/ErrorMessage.js";
|
||||||
import { SelectList } from "../components/SelectList.js";
|
import { SelectList } from "../components/SelectList.js";
|
||||||
import {
|
import {
|
||||||
BoldLight,
|
BoldLight,
|
||||||
ButtonPrimary,
|
|
||||||
Centered,
|
Centered,
|
||||||
Input,
|
Input,
|
||||||
InputWithLabel,
|
InputWithLabel,
|
||||||
@ -37,6 +35,7 @@ import {
|
|||||||
SubTitle,
|
SubTitle,
|
||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { SelectFieldHandler, TextFieldHandler } from "../mui/handlers.js";
|
import { SelectFieldHandler, TextFieldHandler } from "../mui/handlers.js";
|
||||||
import { Pages } from "../NavigationBar.js";
|
import { Pages } from "../NavigationBar.js";
|
||||||
|
|
||||||
@ -270,12 +269,13 @@ export function CreateManualWithdraw({
|
|||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<div />
|
<div />
|
||||||
<ButtonPrimary
|
<Button
|
||||||
|
variant="contained"
|
||||||
disabled={!state.parsedAmount || !state.exchange.value}
|
disabled={!state.parsedAmount || !state.exchange.value}
|
||||||
onClick={() => onCreate(state.exchange.value, state.parsedAmount!)}
|
onClick={() => onCreate(state.exchange.value, state.parsedAmount!)}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Start withdrawal</i18n.Translate>
|
<i18n.Translate>Start withdrawal</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -23,8 +23,6 @@ import { Loading } from "../components/Loading.js";
|
|||||||
import { LoadingError } from "../components/LoadingError.js";
|
import { LoadingError } from "../components/LoadingError.js";
|
||||||
import { SelectList } from "../components/SelectList.js";
|
import { SelectList } from "../components/SelectList.js";
|
||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
ButtonPrimary,
|
|
||||||
ErrorText,
|
ErrorText,
|
||||||
Input,
|
Input,
|
||||||
InputWithLabel,
|
InputWithLabel,
|
||||||
@ -33,6 +31,7 @@ import {
|
|||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import {
|
import {
|
||||||
ButtonHandler,
|
ButtonHandler,
|
||||||
SelectFieldHandler,
|
SelectFieldHandler,
|
||||||
@ -275,7 +274,11 @@ export function View({ state }: ViewProps): VNode {
|
|||||||
</p>
|
</p>
|
||||||
</WarningBox>
|
</WarningBox>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={state.cancelHandler.onClick}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
onClick={state.cancelHandler.onClick}
|
||||||
|
>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
@ -345,20 +348,24 @@ export function View({ state }: ViewProps): VNode {
|
|||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={state.cancelHandler.onClick}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
onClick={state.cancelHandler.onClick}
|
||||||
|
>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
{!state.depositHandler.onClick ? (
|
{!state.depositHandler.onClick ? (
|
||||||
<ButtonPrimary disabled>
|
<Button variant="contained" disabled>
|
||||||
<i18n.Translate>Deposit</i18n.Translate>
|
<i18n.Translate>Deposit</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
) : (
|
) : (
|
||||||
<ButtonPrimary onClick={state.depositHandler.onClick}>
|
<Button variant="contained" onClick={state.depositHandler.onClick}>
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
Deposit {Amounts.stringifyValue(state.totalToDeposit)}{" "}
|
Deposit {Amounts.stringifyValue(state.totalToDeposit)}{" "}
|
||||||
{state.currency}
|
{state.currency}
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -30,6 +30,9 @@ import { Time } from "../components/Time.js";
|
|||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
import { useDiagnostics } from "../hooks/useDiagnostics.js";
|
import { useDiagnostics } from "../hooks/useDiagnostics.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
import { Grid } from "../mui/Grid.js";
|
||||||
|
import { Paper } from "../mui/Paper.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
export function DeveloperPage(): VNode {
|
export function DeveloperPage(): VNode {
|
||||||
@ -133,7 +136,6 @@ export function View({
|
|||||||
const money_by_exchange = coins.reduce(
|
const money_by_exchange = coins.reduce(
|
||||||
(prev, cur) => {
|
(prev, cur) => {
|
||||||
const denom = Amounts.parseOrThrow(cur.denom_value);
|
const denom = Amounts.parseOrThrow(cur.denom_value);
|
||||||
console.log(cur);
|
|
||||||
if (!prev[cur.exchange_base_url]) {
|
if (!prev[cur.exchange_base_url]) {
|
||||||
prev[cur.exchange_base_url] = [];
|
prev[cur.exchange_base_url] = [];
|
||||||
currencies[cur.exchange_base_url] = denom.currency;
|
currencies[cur.exchange_base_url] = denom.currency;
|
||||||
@ -154,57 +156,72 @@ export function View({
|
|||||||
[exchange_name: string]: CalculatedCoinfInfo[];
|
[exchange_name: string]: CalculatedCoinfInfo[];
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
function Item({ children }: any) {
|
||||||
|
return <div>{children}</div>;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
<i18n.Translate>Debug tools</i18n.Translate>:
|
<i18n.Translate>Debug tools</i18n.Translate>:
|
||||||
</p>
|
</p>
|
||||||
<button
|
<Grid container justifyContent="space-between" spacing={1}>
|
||||||
onClick={() =>
|
<Grid item>
|
||||||
confirmReset(
|
<Button
|
||||||
i18n.str`Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?`,
|
variant="contained"
|
||||||
wxApi.resetDb,
|
onClick={() =>
|
||||||
)
|
confirmReset(
|
||||||
}
|
i18n.str`Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?`,
|
||||||
>
|
wxApi.resetDb,
|
||||||
<i18n.Translate>reset</i18n.Translate>
|
)
|
||||||
</button>
|
}
|
||||||
<button
|
>
|
||||||
onClick={() =>
|
<i18n.Translate>reset</i18n.Translate>
|
||||||
confirmReset(
|
</Button>
|
||||||
i18n.str`TESTING: This may delete all your coin, proceed with caution`,
|
</Grid>
|
||||||
wxApi.runGarbageCollector,
|
<Grid item>
|
||||||
)
|
<Button
|
||||||
}
|
variant="contained"
|
||||||
>
|
onClick={() =>
|
||||||
<i18n.Translate>run gc</i18n.Translate>
|
confirmReset(
|
||||||
</button>
|
i18n.str`TESTING: This may delete all your coin, proceed with caution`,
|
||||||
<br />
|
wxApi.runGarbageCollector,
|
||||||
<button onClick={() => fileRef?.current?.click()}>
|
)
|
||||||
<i18n.Translate>import database</i18n.Translate>
|
}
|
||||||
</button>
|
>
|
||||||
<input
|
<i18n.Translate>run gc</i18n.Translate>
|
||||||
ref={fileRef}
|
</Button>
|
||||||
style={{ display: "none" }}
|
</Grid>
|
||||||
type="file"
|
<Grid item>
|
||||||
onChange={async (e) => {
|
<Button
|
||||||
const f: FileList | null = e.currentTarget.files;
|
variant="contained"
|
||||||
if (!f || f.length != 1) {
|
onClick={async () => fileRef?.current?.click()}
|
||||||
return Promise.reject();
|
>
|
||||||
}
|
<i18n.Translate>import database</i18n.Translate>
|
||||||
const buf = await f[0].arrayBuffer();
|
</Button>
|
||||||
const str = new Uint8Array(buf).reduce(
|
</Grid>
|
||||||
(data, byte) => data + String.fromCharCode(byte),
|
<Grid item>
|
||||||
"",
|
<input
|
||||||
);
|
ref={fileRef}
|
||||||
return onImportDatabase(str);
|
style={{ display: "none" }}
|
||||||
}}
|
type="file"
|
||||||
/>
|
onChange={async (e) => {
|
||||||
<br />
|
const f: FileList | null = e.currentTarget.files;
|
||||||
<button onClick={onExportDatabase}>
|
if (!f || f.length != 1) {
|
||||||
<i18n.Translate>export database</i18n.Translate>
|
return Promise.reject();
|
||||||
</button>
|
}
|
||||||
|
const buf = await f[0].arrayBuffer();
|
||||||
|
const str = new Uint8Array(buf).reduce(
|
||||||
|
(data, byte) => data + String.fromCharCode(byte),
|
||||||
|
"",
|
||||||
|
);
|
||||||
|
return onImportDatabase(str);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
<Button variant="contained" onClick={onExportDatabase}>
|
||||||
|
<i18n.Translate>export database</i18n.Translate>
|
||||||
|
</Button>
|
||||||
|
</Grid>
|
||||||
|
</Grid>
|
||||||
{downloadedDatabase && (
|
{downloadedDatabase && (
|
||||||
<div>
|
<div>
|
||||||
<i18n.Translate>
|
<i18n.Translate>
|
||||||
|
@ -1,21 +1,17 @@
|
|||||||
import { Fragment, h, VNode } from "preact";
|
import { Fragment, h, VNode } from "preact";
|
||||||
import { useState } from "preact/hooks";
|
import { useState } from "preact/hooks";
|
||||||
import {
|
import { Title } from "../components/styled/index.js";
|
||||||
Button,
|
|
||||||
ButtonSuccess,
|
|
||||||
ButtonWarning,
|
|
||||||
Title,
|
|
||||||
} from "../components/styled/index.js";
|
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { TermsOfServiceSection } from "../cta/TermsOfServiceSection.js";
|
import { TermsOfServiceSection } from "../cta/TermsOfServiceSection.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { buildTermsOfServiceState, TermsState } from "../utils/index.js";
|
import { buildTermsOfServiceState, TermsState } from "../utils/index.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
url: string;
|
url: string;
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
onConfirm: () => void;
|
onConfirm: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExchangeAddConfirmPage({
|
export function ExchangeAddConfirmPage({
|
||||||
@ -71,8 +67,8 @@ export interface ViewProps {
|
|||||||
url: string;
|
url: string;
|
||||||
terms: TermsState | undefined;
|
terms: TermsState | undefined;
|
||||||
onAccept: (b: boolean) => Promise<void>;
|
onAccept: (b: boolean) => Promise<void>;
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
onConfirm: () => void;
|
onConfirm: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function View({
|
export function View({
|
||||||
@ -114,30 +110,35 @@ export function View({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={onCancel}>
|
<Button variant="contained" color="secondary" onClick={onCancel}>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
{!terms && (
|
{!terms && (
|
||||||
<Button disabled>
|
<Button variant="contained" disabled>
|
||||||
<i18n.Translate>Loading terms..</i18n.Translate>
|
<i18n.Translate>Loading terms..</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{terms && (
|
{terms && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
{needsReview && !reviewed && (
|
{needsReview && !reviewed && (
|
||||||
<ButtonSuccess disabled upperCased onClick={onConfirm}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="success"
|
||||||
|
disabled
|
||||||
|
onClick={onConfirm}
|
||||||
|
>
|
||||||
<i18n.Translate>Add exchange</i18n.Translate>
|
<i18n.Translate>Add exchange</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{(terms.status === "accepted" || (needsReview && reviewed)) && (
|
{(terms.status === "accepted" || (needsReview && reviewed)) && (
|
||||||
<ButtonSuccess upperCased onClick={onConfirm}>
|
<Button variant="contained" color="success" onClick={onConfirm}>
|
||||||
<i18n.Translate>Add exchange</i18n.Translate>
|
<i18n.Translate>Add exchange</i18n.Translate>
|
||||||
</ButtonSuccess>
|
</Button>
|
||||||
)}
|
)}
|
||||||
{terms.status === "notfound" && (
|
{terms.status === "notfound" && (
|
||||||
<ButtonWarning upperCased onClick={onConfirm}>
|
<Button variant="contained" color="warning" onClick={onConfirm}>
|
||||||
<i18n.Translate>Add exchange anyway</i18n.Translate>
|
<i18n.Translate>Add exchange anyway</i18n.Translate>
|
||||||
</ButtonWarning>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
|
@ -28,7 +28,7 @@ import { ExchangeSetUrlPage } from "./ExchangeSetUrl.js";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currency?: string;
|
currency?: string;
|
||||||
onBack: () => void;
|
onBack: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ExchangeAddPage({ currency, onBack }: Props): VNode {
|
export function ExchangeAddPage({ currency, onBack }: Props): VNode {
|
||||||
|
@ -6,8 +6,6 @@ import { Fragment, h, VNode } from "preact";
|
|||||||
import { useEffect, useState } from "preact/hooks";
|
import { useEffect, useState } from "preact/hooks";
|
||||||
import { ErrorMessage } from "../components/ErrorMessage.js";
|
import { ErrorMessage } from "../components/ErrorMessage.js";
|
||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
ButtonPrimary,
|
|
||||||
Input,
|
Input,
|
||||||
LightText,
|
LightText,
|
||||||
SubTitle,
|
SubTitle,
|
||||||
@ -15,11 +13,12 @@ import {
|
|||||||
WarningBox,
|
WarningBox,
|
||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
|
|
||||||
export interface Props {
|
export interface Props {
|
||||||
initialValue?: string;
|
initialValue?: string;
|
||||||
expectedCurrency?: string;
|
expectedCurrency?: string;
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
onVerify: (s: string) => Promise<TalerConfigResponse | undefined>;
|
onVerify: (s: string) => Promise<TalerConfigResponse | undefined>;
|
||||||
onConfirm: (url: string) => Promise<string | undefined>;
|
onConfirm: (url: string) => Promise<string | undefined>;
|
||||||
withError?: string;
|
withError?: string;
|
||||||
@ -64,7 +63,7 @@ function useEndpointStatus<T>(
|
|||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
setHandler(h);
|
setHandler(h);
|
||||||
}, [value, setHandler, handler, onVerify]);
|
}, [value, setHandler, onVerify]);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
error: dirty ? error : undefined,
|
error: dirty ? error : undefined,
|
||||||
@ -172,10 +171,11 @@ export function ExchangeSetUrlPage({
|
|||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={onCancel}>
|
<Button variant="contained" color="secondary" onClick={onCancel}>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
<ButtonPrimary
|
<Button
|
||||||
|
variant="contained"
|
||||||
disabled={
|
disabled={
|
||||||
!result ||
|
!result ||
|
||||||
!!error ||
|
!!error ||
|
||||||
@ -189,7 +189,7 @@ export function ExchangeSetUrlPage({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Next</i18n.Translate>
|
<i18n.Translate>Next</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -26,7 +26,6 @@ import { Loading } from "../components/Loading.js";
|
|||||||
import { LoadingError } from "../components/LoadingError.js";
|
import { LoadingError } from "../components/LoadingError.js";
|
||||||
import {
|
import {
|
||||||
ButtonBoxPrimary,
|
ButtonBoxPrimary,
|
||||||
ButtonPrimary,
|
|
||||||
CenteredBoldText,
|
CenteredBoldText,
|
||||||
CenteredText,
|
CenteredText,
|
||||||
DateSeparator,
|
DateSeparator,
|
||||||
@ -36,13 +35,14 @@ import { Time } from "../components/Time.js";
|
|||||||
import { TransactionItem } from "../components/TransactionItem.js";
|
import { TransactionItem } from "../components/TransactionItem.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { NoBalanceHelp } from "../popup/NoBalanceHelp.js";
|
import { NoBalanceHelp } from "../popup/NoBalanceHelp.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currency?: string;
|
currency?: string;
|
||||||
goToWalletDeposit: (currency: string) => void;
|
goToWalletDeposit: (currency: string) => Promise<void>;
|
||||||
goToWalletManualWithdraw: (currency?: string) => void;
|
goToWalletManualWithdraw: (currency?: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
export function HistoryPage({
|
export function HistoryPage({
|
||||||
currency,
|
currency,
|
||||||
@ -101,8 +101,8 @@ export function HistoryView({
|
|||||||
goToWalletManualWithdraw,
|
goToWalletManualWithdraw,
|
||||||
goToWalletDeposit,
|
goToWalletDeposit,
|
||||||
}: {
|
}: {
|
||||||
goToWalletDeposit: (currency: string) => void;
|
goToWalletDeposit: (currency: string) => Promise<void>;
|
||||||
goToWalletManualWithdraw: (currency?: string) => void;
|
goToWalletManualWithdraw: (currency?: string) => Promise<void>;
|
||||||
defaultCurrency?: string;
|
defaultCurrency?: string;
|
||||||
transactions: Transaction[];
|
transactions: Transaction[];
|
||||||
balances: Balance[];
|
balances: Balance[];
|
||||||
@ -198,19 +198,22 @@ export function HistoryView({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<ButtonPrimary
|
<Button
|
||||||
style={{ marginLeft: 0, marginTop: 8 }}
|
variant="contained"
|
||||||
|
// style={{ marginLeft: 0, marginTop: 8 }}
|
||||||
onClick={() => goToWalletManualWithdraw(selectedCurrency)}
|
onClick={() => goToWalletManualWithdraw(selectedCurrency)}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Withdraw</i18n.Translate>
|
<i18n.Translate>Withdraw</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
{currencyAmount && Amounts.isNonZero(currencyAmount) && (
|
{currencyAmount && Amounts.isNonZero(currencyAmount) && (
|
||||||
<ButtonBoxPrimary
|
<Button
|
||||||
style={{ marginLeft: 0, marginTop: 8 }}
|
variant="outlined"
|
||||||
|
color="primary"
|
||||||
|
// style={{ marginLeft: 0, marginTop: 8 }}
|
||||||
onClick={() => goToWalletDeposit(selectedCurrency)}
|
onClick={() => goToWalletDeposit(selectedCurrency)}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Deposit</i18n.Translate>
|
<i18n.Translate>Deposit</i18n.Translate>
|
||||||
</ButtonBoxPrimary>
|
</Button>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,7 +34,7 @@ import { ReserveCreated } from "./ReserveCreated.js";
|
|||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currency?: string;
|
currency?: string;
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
|
export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
|
||||||
|
@ -25,8 +25,6 @@ import { useEffect, useState } from "preact/hooks";
|
|||||||
import { Checkbox } from "../components/Checkbox.js";
|
import { Checkbox } from "../components/Checkbox.js";
|
||||||
import { ErrorMessage } from "../components/ErrorMessage.js";
|
import { ErrorMessage } from "../components/ErrorMessage.js";
|
||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
ButtonPrimary,
|
|
||||||
Input,
|
Input,
|
||||||
LightText,
|
LightText,
|
||||||
SmallLightText,
|
SmallLightText,
|
||||||
@ -34,12 +32,13 @@ import {
|
|||||||
Title,
|
Title,
|
||||||
} from "../components/styled/index.js";
|
} from "../components/styled/index.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { queryToSlashConfig } from "../utils/index.js";
|
import { queryToSlashConfig } from "../utils/index.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
currency: string;
|
currency: string;
|
||||||
onBack: () => void;
|
onBack: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProviderAddPage({ onBack }: Props): VNode {
|
export function ProviderAddPage({ onBack }: Props): VNode {
|
||||||
@ -67,11 +66,13 @@ export function ProviderAddPage({ onBack }: Props): VNode {
|
|||||||
<ConfirmProviderView
|
<ConfirmProviderView
|
||||||
provider={verifying.provider}
|
provider={verifying.provider}
|
||||||
url={verifying.url}
|
url={verifying.url}
|
||||||
onCancel={() => {
|
onCancel={async () => {
|
||||||
setVerifying(undefined);
|
setVerifying(undefined);
|
||||||
}}
|
}}
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
wxApi.addBackupProvider(verifying.url, verifying.name).then(onBack);
|
return wxApi
|
||||||
|
.addBackupProvider(verifying.url, verifying.name)
|
||||||
|
.then(onBack);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -79,7 +80,7 @@ export function ProviderAddPage({ onBack }: Props): VNode {
|
|||||||
|
|
||||||
export interface SetUrlViewProps {
|
export interface SetUrlViewProps {
|
||||||
initialValue?: string;
|
initialValue?: string;
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
onVerify: (s: string) => Promise<BackupBackupProviderTerms | undefined>;
|
onVerify: (s: string) => Promise<BackupBackupProviderTerms | undefined>;
|
||||||
onConfirm: (url: string, name: string) => Promise<string | undefined>;
|
onConfirm: (url: string, name: string) => Promise<string | undefined>;
|
||||||
withError?: string;
|
withError?: string;
|
||||||
@ -161,10 +162,11 @@ export function SetUrlView({
|
|||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={onCancel}>
|
<Button variant="contained" color="secondary" onClick={onCancel}>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
<ButtonPrimary
|
<Button
|
||||||
|
variant="contained"
|
||||||
disabled={!value && !urlError}
|
disabled={!value && !urlError}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
const url = canonicalizeBaseUrl(value);
|
const url = canonicalizeBaseUrl(value);
|
||||||
@ -174,7 +176,7 @@ export function SetUrlView({
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<i18n.Translate>Next</i18n.Translate>
|
<i18n.Translate>Next</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
@ -183,8 +185,8 @@ export function SetUrlView({
|
|||||||
export interface ConfirmProviderViewProps {
|
export interface ConfirmProviderViewProps {
|
||||||
provider: BackupBackupProviderTerms;
|
provider: BackupBackupProviderTerms;
|
||||||
url: string;
|
url: string;
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
onConfirm: () => void;
|
onConfirm: () => Promise<void>;
|
||||||
}
|
}
|
||||||
export function ConfirmProviderView({
|
export function ConfirmProviderView({
|
||||||
url,
|
url,
|
||||||
@ -236,17 +238,17 @@ export function ConfirmProviderView({
|
|||||||
<Checkbox
|
<Checkbox
|
||||||
label={<i18n.Translate>Accept terms of service</i18n.Translate>}
|
label={<i18n.Translate>Accept terms of service</i18n.Translate>}
|
||||||
name="terms"
|
name="terms"
|
||||||
onToggle={() => setAccepted((old) => !old)}
|
onToggle={async () => setAccepted((old) => !old)}
|
||||||
enabled={accepted}
|
enabled={accepted}
|
||||||
/>
|
/>
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={onCancel}>
|
<Button variant="contained" color="secondary" onClick={onCancel}>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
<ButtonPrimary disabled={!accepted} onClick={onConfirm}>
|
<Button variant="contained" disabled={!accepted} onClick={onConfirm}>
|
||||||
<i18n.Translate>Add provider</i18n.Translate>
|
<i18n.Translate>Add provider</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -25,21 +25,16 @@ import { Fragment, h, VNode } from "preact";
|
|||||||
import { ErrorMessage } from "../components/ErrorMessage.js";
|
import { ErrorMessage } from "../components/ErrorMessage.js";
|
||||||
import { Loading } from "../components/Loading.js";
|
import { Loading } from "../components/Loading.js";
|
||||||
import { LoadingError } from "../components/LoadingError.js";
|
import { LoadingError } from "../components/LoadingError.js";
|
||||||
import {
|
import { PaymentStatus, SmallLightText } from "../components/styled/index.js";
|
||||||
Button,
|
|
||||||
ButtonDestructive,
|
|
||||||
ButtonPrimary,
|
|
||||||
PaymentStatus,
|
|
||||||
SmallLightText,
|
|
||||||
} from "../components/styled/index.js";
|
|
||||||
import { Time } from "../components/Time.js";
|
import { Time } from "../components/Time.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
pid: string;
|
pid: string;
|
||||||
onBack: () => void;
|
onBack: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
|
export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
|
||||||
@ -77,10 +72,10 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
|
|||||||
<ProviderView
|
<ProviderView
|
||||||
url={providerURL}
|
url={providerURL}
|
||||||
info={state.response}
|
info={state.response}
|
||||||
onSync={async () => wxApi.syncOneProvider(providerURL)}
|
onSync={() => wxApi.syncOneProvider(providerURL)}
|
||||||
onDelete={async () => wxApi.removeProvider(providerURL).then(onBack)}
|
onDelete={() => wxApi.removeProvider(providerURL).then(onBack)}
|
||||||
onBack={onBack}
|
onBack={onBack}
|
||||||
onExtend={() => {
|
onExtend={async () => {
|
||||||
null;
|
null;
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -90,10 +85,10 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
|
|||||||
export interface ViewProps {
|
export interface ViewProps {
|
||||||
url: string;
|
url: string;
|
||||||
info: ProviderInfo | null;
|
info: ProviderInfo | null;
|
||||||
onDelete: () => void;
|
onDelete: () => Promise<void>;
|
||||||
onSync: () => void;
|
onSync: () => Promise<void>;
|
||||||
onBack: () => void;
|
onBack: () => Promise<void>;
|
||||||
onExtend: () => void;
|
onExtend: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProviderView({
|
export function ProviderView({
|
||||||
@ -116,7 +111,7 @@ export function ProviderView({
|
|||||||
</p>
|
</p>
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={onBack}>
|
<Button variant="contained" color="secondary" onClick={onBack}>
|
||||||
<i18n.Translate>See providers</i18n.Translate>
|
<i18n.Translate>See providers</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
<div />
|
<div />
|
||||||
@ -149,9 +144,9 @@ export function ProviderView({
|
|||||||
</b>{" "}
|
</b>{" "}
|
||||||
<Time timestamp={lb} format="dd MMMM yyyy" />
|
<Time timestamp={lb} format="dd MMMM yyyy" />
|
||||||
</p>
|
</p>
|
||||||
<ButtonPrimary onClick={onSync}>
|
<Button variant="contained" onClick={onSync}>
|
||||||
<i18n.Translate>Back up</i18n.Translate>
|
<i18n.Translate>Back up</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
{info.terms && (
|
{info.terms && (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<p>
|
<p>
|
||||||
@ -164,9 +159,9 @@ export function ProviderView({
|
|||||||
</Fragment>
|
</Fragment>
|
||||||
)}
|
)}
|
||||||
<p>{descriptionByStatus(info.paymentStatus, i18n)}</p>
|
<p>{descriptionByStatus(info.paymentStatus, i18n)}</p>
|
||||||
<ButtonPrimary disabled onClick={onExtend}>
|
<Button variant="contained" disabled onClick={onExtend}>
|
||||||
<i18n.Translate>Extend</i18n.Translate>
|
<i18n.Translate>Extend</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
|
|
||||||
{info.paymentStatus.type === ProviderPaymentType.TermsChanged && (
|
{info.paymentStatus.type === ProviderPaymentType.TermsChanged && (
|
||||||
<div>
|
<div>
|
||||||
@ -212,13 +207,13 @@ export function ProviderView({
|
|||||||
)}
|
)}
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={onBack}>
|
<Button variant="contained" color="secondary" onClick={onBack}>
|
||||||
<i18n.Translate>See providers</i18n.Translate>
|
<i18n.Translate>See providers</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
<div>
|
<div>
|
||||||
<ButtonDestructive onClick={onDelete}>
|
<Button variant="contained" color="error" onClick={onDelete}>
|
||||||
<i18n.Translate>Remove provider</i18n.Translate>
|
<i18n.Translate>Remove provider</i18n.Translate>
|
||||||
</ButtonDestructive>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
@ -4,18 +4,15 @@ import { Amount } from "../components/Amount.js";
|
|||||||
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js";
|
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType.js";
|
||||||
import { ErrorMessage } from "../components/ErrorMessage.js";
|
import { ErrorMessage } from "../components/ErrorMessage.js";
|
||||||
import { QR } from "../components/QR.js";
|
import { QR } from "../components/QR.js";
|
||||||
import {
|
import { Title, WarningBox } from "../components/styled/index.js";
|
||||||
ButtonDestructive,
|
|
||||||
Title,
|
|
||||||
WarningBox,
|
|
||||||
} from "../components/styled/index.js";
|
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
export interface Props {
|
export interface Props {
|
||||||
reservePub: string;
|
reservePub: string;
|
||||||
paytoURI: PaytoUri | undefined;
|
paytoURI: PaytoUri | undefined;
|
||||||
exchangeBaseUrl: string;
|
exchangeBaseUrl: string;
|
||||||
amount: AmountJson;
|
amount: AmountJson;
|
||||||
onCancel: () => void;
|
onCancel: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ReserveCreated({
|
export function ReserveCreated({
|
||||||
@ -82,9 +79,9 @@ export function ReserveCreated({
|
|||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<div />
|
<div />
|
||||||
<ButtonDestructive onClick={onCancel}>
|
<Button variant="contained" color="error" onClick={onCancel}>
|
||||||
<i18n.Translate>Cancel withdrawal</i18n.Translate>
|
<i18n.Translate>Cancel withdrawal</i18n.Translate>
|
||||||
</ButtonDestructive>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
);
|
);
|
||||||
|
@ -66,7 +66,7 @@ export interface ViewProps {
|
|||||||
setDeviceName: (s: string) => Promise<void>;
|
setDeviceName: (s: string) => Promise<void>;
|
||||||
permissionToggle: ToggleHandler;
|
permissionToggle: ToggleHandler;
|
||||||
developerMode: boolean;
|
developerMode: boolean;
|
||||||
toggleDeveloperMode: () => void;
|
toggleDeveloperMode: () => Promise<void>;
|
||||||
knownExchanges: Array<ExchangeListItem>;
|
knownExchanges: Array<ExchangeListItem>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,7 +21,6 @@ import {
|
|||||||
Location,
|
Location,
|
||||||
NotificationType,
|
NotificationType,
|
||||||
parsePaytoUri,
|
parsePaytoUri,
|
||||||
parsePayUri,
|
|
||||||
PaytoUri,
|
PaytoUri,
|
||||||
stringifyPaytoUri,
|
stringifyPaytoUri,
|
||||||
TalerProtocolTimestamp,
|
TalerProtocolTimestamp,
|
||||||
@ -47,17 +46,11 @@ import { Loading } from "../components/Loading.js";
|
|||||||
import { LoadingError } from "../components/LoadingError.js";
|
import { LoadingError } from "../components/LoadingError.js";
|
||||||
import { Kind, Part, PartCollapsible, PartPayto } from "../components/Part.js";
|
import { Kind, Part, PartCollapsible, PartPayto } from "../components/Part.js";
|
||||||
import {
|
import {
|
||||||
Button,
|
|
||||||
ButtonBox,
|
|
||||||
ButtonDestructive,
|
|
||||||
ButtonPrimary,
|
|
||||||
CenteredDialog,
|
CenteredDialog,
|
||||||
HistoryRow,
|
|
||||||
InfoBox,
|
InfoBox,
|
||||||
ListOfProducts,
|
ListOfProducts,
|
||||||
Overlay,
|
Overlay,
|
||||||
Row,
|
Row,
|
||||||
RowBorderGray,
|
|
||||||
SmallLightText,
|
SmallLightText,
|
||||||
SubTitle,
|
SubTitle,
|
||||||
WarningBox,
|
WarningBox,
|
||||||
@ -65,12 +58,13 @@ import {
|
|||||||
import { Time } from "../components/Time.js";
|
import { Time } from "../components/Time.js";
|
||||||
import { useTranslationContext } from "../context/translation.js";
|
import { useTranslationContext } from "../context/translation.js";
|
||||||
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
|
||||||
|
import { Button } from "../mui/Button.js";
|
||||||
import { Pages } from "../NavigationBar.js";
|
import { Pages } from "../NavigationBar.js";
|
||||||
import * as wxApi from "../wxApi.js";
|
import * as wxApi from "../wxApi.js";
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
tid: string;
|
tid: string;
|
||||||
goToWalletHistory: (currency?: string) => void;
|
goToWalletHistory: (currency?: string) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getTransaction(tid: string): Promise<Transaction> {
|
async function getTransaction(tid: string): Promise<Transaction> {
|
||||||
@ -122,7 +116,7 @@ export function TransactionPage({ tid, goToWalletHistory }: Props): VNode {
|
|||||||
onRetry={() =>
|
onRetry={() =>
|
||||||
wxApi.retryTransaction(tid).then(() => goToWalletHistory(currency))
|
wxApi.retryTransaction(tid).then(() => goToWalletHistory(currency))
|
||||||
}
|
}
|
||||||
onRefund={(id) => wxApi.applyRefundFromPurchaseId(id)}
|
onRefund={(id) => wxApi.applyRefundFromPurchaseId(id).then()}
|
||||||
onBack={() => goToWalletHistory(currency)}
|
onBack={() => goToWalletHistory(currency)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@ -130,10 +124,10 @@ export function TransactionPage({ tid, goToWalletHistory }: Props): VNode {
|
|||||||
|
|
||||||
export interface WalletTransactionProps {
|
export interface WalletTransactionProps {
|
||||||
transaction: Transaction;
|
transaction: Transaction;
|
||||||
onDelete: () => void;
|
onDelete: () => Promise<void>;
|
||||||
onRetry: () => void;
|
onRetry: () => Promise<void>;
|
||||||
onRefund: (id: string) => void;
|
onRefund: (id: string) => Promise<void>;
|
||||||
onBack: () => void;
|
onBack: () => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PurchaseDetailsTable = styled.table`
|
const PurchaseDetailsTable = styled.table`
|
||||||
@ -152,7 +146,7 @@ export function TransactionView({
|
|||||||
}: WalletTransactionProps): VNode {
|
}: WalletTransactionProps): VNode {
|
||||||
const [confirmBeforeForget, setConfirmBeforeForget] = useState(false);
|
const [confirmBeforeForget, setConfirmBeforeForget] = useState(false);
|
||||||
|
|
||||||
function doCheckBeforeForget(): void {
|
async function doCheckBeforeForget(): Promise<void> {
|
||||||
if (
|
if (
|
||||||
transaction.pending &&
|
transaction.pending &&
|
||||||
transaction.type === TransactionType.Withdrawal
|
transaction.type === TransactionType.Withdrawal
|
||||||
@ -198,13 +192,17 @@ export function TransactionView({
|
|||||||
<div />
|
<div />
|
||||||
<div>
|
<div>
|
||||||
{showRetry ? (
|
{showRetry ? (
|
||||||
<ButtonPrimary onClick={onRetry}>
|
<Button variant="contained" onClick={onRetry}>
|
||||||
<i18n.Translate>Retry</i18n.Translate>
|
<i18n.Translate>Retry</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
) : null}
|
) : null}
|
||||||
<ButtonDestructive onClick={doCheckBeforeForget}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="error"
|
||||||
|
onClick={doCheckBeforeForget}
|
||||||
|
>
|
||||||
<i18n.Translate>Forget</i18n.Translate>
|
<i18n.Translate>Forget</i18n.Translate>
|
||||||
</ButtonDestructive>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</Fragment>
|
</Fragment>
|
||||||
@ -229,13 +227,17 @@ export function TransactionView({
|
|||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</section>
|
</section>
|
||||||
<footer>
|
<footer>
|
||||||
<Button onClick={() => setConfirmBeforeForget(false)}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
color="secondary"
|
||||||
|
onClick={async () => setConfirmBeforeForget(false)}
|
||||||
|
>
|
||||||
<i18n.Translate>Cancel</i18n.Translate>
|
<i18n.Translate>Cancel</i18n.Translate>
|
||||||
</Button>
|
</Button>
|
||||||
|
|
||||||
<ButtonDestructive onClick={onDelete}>
|
<Button variant="contained" color="error" onClick={onDelete}>
|
||||||
<i18n.Translate>Confirm</i18n.Translate>
|
<i18n.Translate>Confirm</i18n.Translate>
|
||||||
</ButtonDestructive>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</CenteredDialog>
|
</CenteredDialog>
|
||||||
</Overlay>
|
</Overlay>
|
||||||
@ -387,9 +389,12 @@ export function TransactionView({
|
|||||||
<div>
|
<div>
|
||||||
<div />
|
<div />
|
||||||
<div>
|
<div>
|
||||||
<ButtonPrimary onClick={() => onRefund(transaction.proposalId)}>
|
<Button
|
||||||
|
variant="contained"
|
||||||
|
onClick={() => onRefund(transaction.proposalId)}
|
||||||
|
>
|
||||||
<i18n.Translate>Accept</i18n.Translate>
|
<i18n.Translate>Accept</i18n.Translate>
|
||||||
</ButtonPrimary>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</InfoBox>
|
</InfoBox>
|
||||||
|
Loading…
Reference in New Issue
Block a user