diff options
4 files changed, 95 insertions, 44 deletions
diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx index 66d47c180..7fb8dad8b 100644 --- a/packages/taler-wallet-webextension/src/NavigationBar.tsx +++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx @@ -173,10 +173,11 @@ export const Pages = { ctaInvoicePay: "/cta/invoice/pay", ctaTransferPickup: "/cta/transfer/pickup", - ctaWithdrawManual: pageDefinition<{ + ctaWithdrawManualForScope: pageDefinition<{ scope: CrockEncodedString; amount?: string; - }>("/cta/manual-withdraw/:scope/:amount?"), + }>("/cta/scope-withdraw/:scope/:amount?"), + ctaWithdrawManual: pageDefinition<{amount?: string;}>("/cta/manual-withdraw/:amount?"), paytoQrs: pageDefinition<{ payto: CrockEncodedString }>("/payto/qrs/:payto?"), paytoBanks: pageDefinition<{ payto: CrockEncodedString }>( "/payto/banks/:payto?", diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index 91bde9369..8d4ad0bde 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -47,8 +47,8 @@ export interface PropsFromURI { export interface PropsFromParams { talerExchangeWithdrawUri: string | undefined; - scope: ScopeInfo; - amount: string | undefined; + scope: ScopeInfo | undefined; + amount: AmountJson | undefined; cancel: () => Promise<void>; onSuccess: (txid: string) => Promise<void>; } diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index 8a862d200..232bfe9e2 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -37,14 +37,14 @@ import { PropsFromParams, PropsFromURI, State } from "./index.js"; export function useComponentStateFromParams({ talerExchangeWithdrawUri: maybeTalerUri, - amount, scope, + amount: paramsAmount, cancel, onSuccess, }: PropsFromParams): RecursiveState<State> { const api = useBackendContext(); const { i18n } = useTranslationContext(); - const paramsAmount = amount ? Amounts.parse(amount) : undefined; + // const paramsAmount = amount ? Amounts.parse(amount) : undefined; const [updatedExchangeByUser, setUpdatedExchangeByUser] = useState<string>(); const uriInfoHook = useAsyncAsHook(async () => { const exchanges = await api.wallet.call( @@ -75,6 +75,10 @@ export function useComponentStateFromParams({ return { amount: chosenAmount, exchanges, exchange: ex }; }); + useEffect(() => { + uriInfoHook?.retry(); + }, [paramsAmount]); + if (!uriInfoHook) return { status: "loading", error: undefined }; if (uriInfoHook.hasError) { @@ -88,14 +92,22 @@ export function useComponentStateFromParams({ }; } - useEffect(() => { - uriInfoHook?.retry(); - }, [amount]); + const currency = uriInfoHook.response.exchange?.currency ?? scope?.currency; const exchangeByTalerUri = uriInfoHook.response.exchange?.exchangeBaseUrl; const exchangeList = uriInfoHook.response.exchanges.exchanges; const maybeAmount = uriInfoHook.response.amount ?? paramsAmount; + if (!currency) { + return { + status: "error", + error: alertFromError( + i18n, + i18n.str`Could not load the list of exchanges`, + {} as any, + ), + }; + } // if (!maybeAmount) { // const exchangeBaseUrl = @@ -156,7 +168,7 @@ export function useComponentStateFromParams({ // }; // }; // } - const chosenAmount = maybeAmount ?? Amounts.zeroOfCurrency(scope.currency); + const chosenAmount = maybeAmount ?? Amounts.zeroOfCurrency(currency); async function doManualWithdraw( exchange: string, diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index 474f5acdb..783935143 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -354,7 +354,7 @@ export function Application(): VNode { scope={s} goToWalletManualWithdraw={(s) => redirectTo( - Pages.ctaWithdrawManual({ + Pages.ctaWithdrawManualForScope({ scope: encodeCrockForURI(stringifyScopeInfoShort(s)), }), ) @@ -592,7 +592,7 @@ export function Application(): VNode { component={({ talerUri }: { talerUri: string }) => ( <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> <WithdrawPageFromURI - talerWithdrawUri={decodeCrockFromURI(talerUri)} + talerWithdrawUri={!talerUri ? undefined : decodeCrockFromURI(talerUri)} cancel={() => redirectTo(Pages.balance)} onSuccess={(tid: string) => redirectTo(Pages.balanceTransaction({ tid })) @@ -604,14 +604,38 @@ export function Application(): VNode { <Route path={Pages.ctaWithdrawManual.pattern} component={({ - scope, + // scope, amount, talerUri, }: { - scope: string; + // scope: string; amount: string; talerUri: string; }) => { + return ( + <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> + <WithdrawPageFromParams + scope={undefined} + talerExchangeWithdrawUri={!talerUri ? undefined : decodeCrockFromURI(talerUri)} + amount={Amounts.parse(amount)} + cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + ); + }} + /> + <Route + path={Pages.ctaWithdrawManualForScope.pattern} + component={({ + scope, + amount, + }: { + scope: string; + amount: string; + }) => { if (!scope) return <Redirect to={Pages.balanceHistory({})} />; const s = parseScopeInfoShort(decodeCrockFromURI(scope)); if (!s) return <Redirect to={Pages.balanceHistory({})} />; @@ -619,9 +643,9 @@ export function Application(): VNode { return ( <CallToActionTemplate title={i18n.str`Digital cash withdrawal`}> <WithdrawPageFromParams + talerExchangeWithdrawUri={undefined} scope={s} - talerExchangeWithdrawUri={talerUri} - amount={amount} + amount={Amounts.parse(amount)} cancel={() => redirectTo(Pages.balance)} onSuccess={(tid: string) => redirectTo(Pages.balanceTransaction({ tid })) @@ -693,42 +717,56 @@ export function Application(): VNode { /> <Route path={Pages.ctaInvoicePay} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash invoice`}> - <InvoicePayPage - talerPayPullUri={decodeCrockFromURI(talerUri)} - goToWalletManualWithdraw={(_amount?: string) => - // FIXME: use receiveCashForInvoice - redirectTo(Pages.receiveCash({})) - } - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} + component={({ talerUri }: { talerUri: string }) => { + const uri = (decodeCrockFromURI(talerUri)); + if (!uri) { + return <div>missing taler uri</div>; + } + + return ( + <CallToActionTemplate title={i18n.str`Digital cash invoice`}> + <InvoicePayPage + talerPayPullUri={uri} + goToWalletManualWithdraw={(_amount?: string) => + // FIXME: use receiveCashForInvoice + redirectTo(Pages.receiveCash({})) + } + onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + ) + }} /> <Route path={Pages.ctaTransferPickup} - component={({ talerUri }: { talerUri: string }) => ( - <CallToActionTemplate title={i18n.str`Digital cash transfer`}> - <TransferPickupPage - talerPayPushUri={decodeCrockFromURI(talerUri)} - onClose={() => redirectTo(Pages.balance)} - onSuccess={(tid: string) => - redirectTo(Pages.balanceTransaction({ tid })) - } - /> - </CallToActionTemplate> - )} + component={({ talerUri }: { talerUri: string }) => { + const uri = (decodeCrockFromURI(talerUri)); + if (!uri) { + return <div>missing taler uri</div>; + } + + return ( + <CallToActionTemplate title={i18n.str`Digital cash transfer`}> + <TransferPickupPage + talerPayPushUri={uri} + onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid: string) => + redirectTo(Pages.balanceTransaction({ tid })) + } + /> + </CallToActionTemplate> + ) + }} /> <Route path={Pages.ctaRecovery} component={({ talerRecoveryUri }: { talerRecoveryUri: string }) => ( <CallToActionTemplate title={i18n.str`Digital cash recovery`}> <RecoveryPage - talerRecoveryUri={decodeCrockFromURI(talerRecoveryUri)} + talerRecoveryUri={!talerRecoveryUri ? undefined : decodeCrockFromURI(talerRecoveryUri)} onCancel={() => redirectTo(Pages.balance)} onSuccess={() => redirectTo(Pages.backup)} /> @@ -740,7 +778,7 @@ export function Application(): VNode { component={({ talerUri }: { talerUri: string }) => ( <CallToActionTemplate title={i18n.str`Development experiment`}> <DevExperimentPage - talerExperimentUri={decodeCrockFromURI(talerUri)} + talerExperimentUri={!talerUri ? undefined : decodeCrockFromURI(talerUri)} onCancel={() => redirectTo(Pages.balanceHistory({}))} onSuccess={() => redirectTo(Pages.balanceHistory({}))} /> |