aboutsummaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-10-11 15:59:55 -0300
committerSebastian <sebasjm@gmail.com>2021-10-11 15:59:55 -0300
commitbe8e3f4b1d090a536967f132a7fd4742bbcd5343 (patch)
treed184ba3cf40510009e4121c6daa5653e0be475b0 /packages/taler-wallet-webextension/src/cta
parent78fb5f79a8690ee490c96b271dadd37f4c9442d6 (diff)
downloadwallet-core-be8e3f4b1d090a536967f132a7fd4742bbcd5343.tar.xz
fixing withdrawal process
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta')
-rw-r--r--packages/taler-wallet-webextension/src/cta/Pay.tsx31
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx148
-rw-r--r--packages/taler-wallet-webextension/src/cta/Withdraw.tsx171
3 files changed, 247 insertions, 103 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx
index 8e02cf6bb..675b14ff9 100644
--- a/packages/taler-wallet-webextension/src/cta/Pay.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx
@@ -88,7 +88,7 @@ export function PayPage({ talerPayUri }: Props): JSX.Element {
const [payErrMsg, setPayErrMsg] = useState<string | undefined>(undefined);
const balance = useBalances()
- const balanceWithoutError = balance?.error ? [] : (balance?.response.balances || [])
+ const balanceWithoutError = balance?.hasError ? [] : (balance?.response.balances || [])
const foundBalance = balanceWithoutError.find(b => payStatus && Amounts.parseOrThrow(b.available).currency === Amounts.parseOrThrow(payStatus?.amountRaw).currency)
const foundAmount = foundBalance ? Amounts.parseOrThrow(foundBalance.available) : undefined
@@ -143,17 +143,21 @@ export function PayPage({ talerPayUri }: Props): JSX.Element {
}
- return <PaymentRequestView uri={talerPayUri} payStatus={payStatus} onClick={onClick} payErrMsg={payErrMsg} balance={foundAmount} />;
+ return <PaymentRequestView uri={talerPayUri}
+ payStatus={payStatus} payResult={payResult}
+ onClick={onClick} payErrMsg={payErrMsg}
+ balance={foundAmount} />;
}
export interface PaymentRequestViewProps {
payStatus: PreparePayResult;
+ payResult?: ConfirmPayResult;
onClick: () => void;
payErrMsg?: string;
uri: string;
balance: AmountJson | undefined;
}
-export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance }: PaymentRequestViewProps) {
+export function PaymentRequestView({ uri, payStatus, payResult, onClick, payErrMsg, balance }: PaymentRequestViewProps) {
let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw);
const contractTerms: ContractTerms = payStatus.contractTerms;
@@ -195,6 +199,16 @@ export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance
}
function ButtonsSection() {
+ if (payResult) {
+ if (payResult.type === ConfirmPayResultType.Pending) {
+ return <section>
+ <div>
+ <p>Processing...</p>
+ </div>
+ </section>
+ }
+ return null
+ }
if (payErrMsg) {
return <section>
<div>
@@ -208,7 +222,7 @@ export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance
if (payStatus.status === PreparePayResultType.PaymentPossible) {
return <Fragment>
<section>
- <ButtonSuccess upperCased>
+ <ButtonSuccess upperCased onClick={onClick}>
{i18n.str`Pay`} {amountToString(payStatus.amountEffective)}
</ButtonSuccess>
</section>
@@ -252,6 +266,15 @@ export function PaymentRequestView({ uri, payStatus, onClick, payErrMsg, balance
{payStatus.status === PreparePayResultType.AlreadyConfirmed &&
(payStatus.paid ? <SuccessBox> Already paid </SuccessBox> : <WarningBox> Already claimed </WarningBox>)
}
+ {payResult && payResult.type === ConfirmPayResultType.Done && (
+ <SuccessBox>
+ <h3>Payment complete</h3>
+ <p>{!payResult.contractTerms.fulfillment_message ?
+ "You will now be sent back to the merchant you came from." :
+ payResult.contractTerms.fulfillment_message
+ }</p>
+ </SuccessBox>
+ )}
<section>
{payStatus.status !== PreparePayResultType.InsufficientBalance && Amounts.isNonZero(totalFees) &&
<Part big title="Total to pay" text={amountToString(payStatus.amountEffective)} kind='negative' />
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx
index 94fdea8fb..69073f500 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw.stories.tsx
@@ -31,6 +31,7 @@ export default {
title: 'cta/withdraw',
component: TestedComponent,
argTypes: {
+ onSwitchExchange: { action: 'onRetry' },
},
};
@@ -381,6 +382,15 @@ const termsXml = `<?xml version="1.0" encoding="utf-8"?>
`;
export const WithdrawNewTermsXML = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -391,9 +401,15 @@ export const WithdrawNewTermsXML = createExample(TestedComponent, {
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+
+ onSwitchExchange: async () => { },
terms: {
- value : {
+ value: {
type: 'xml',
document: new DOMParser().parseFromString(termsXml, "text/xml"),
},
@@ -402,6 +418,15 @@ export const WithdrawNewTermsXML = createExample(TestedComponent, {
})
export const WithdrawNewTermsReviewingXML = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -412,9 +437,15 @@ export const WithdrawNewTermsReviewingXML = createExample(TestedComponent, {
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+
+ onSwitchExchange: async () => { },
terms: {
- value : {
+ value: {
type: 'xml',
document: new DOMParser().parseFromString(termsXml, "text/xml"),
},
@@ -424,6 +455,15 @@ export const WithdrawNewTermsReviewingXML = createExample(TestedComponent, {
})
export const WithdrawNewTermsAcceptedXML = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -434,9 +474,14 @@ export const WithdrawNewTermsAcceptedXML = createExample(TestedComponent, {
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+ onSwitchExchange: async () => { },
terms: {
- value : {
+ value: {
type: 'xml',
document: new DOMParser().parseFromString(termsXml, "text/xml"),
},
@@ -446,6 +491,15 @@ export const WithdrawNewTermsAcceptedXML = createExample(TestedComponent, {
})
export const WithdrawNewTermsShowAfterAcceptedXML = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -456,9 +510,15 @@ export const WithdrawNewTermsShowAfterAcceptedXML = createExample(TestedComponen
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+
+ onSwitchExchange: async () => { },
terms: {
- value : {
+ value: {
type: 'xml',
document: new DOMParser().parseFromString(termsXml, "text/xml"),
},
@@ -469,6 +529,15 @@ export const WithdrawNewTermsShowAfterAcceptedXML = createExample(TestedComponen
})
export const WithdrawChangedTermsXML = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -479,9 +548,15 @@ export const WithdrawChangedTermsXML = createExample(TestedComponent, {
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+
+ onSwitchExchange: async () => { },
terms: {
- value : {
+ value: {
type: 'xml',
document: new DOMParser().parseFromString(termsXml, "text/xml"),
},
@@ -490,6 +565,15 @@ export const WithdrawChangedTermsXML = createExample(TestedComponent, {
})
export const WithdrawNotFoundTermsXML = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -500,13 +584,28 @@ export const WithdrawNotFoundTermsXML = createExample(TestedComponent, {
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+
+ onSwitchExchange: async () => { },
terms: {
status: 'notfound'
},
})
export const WithdrawAcceptedTermsXML = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -517,7 +616,13 @@ export const WithdrawAcceptedTermsXML = createExample(TestedComponent, {
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+
+ onSwitchExchange: async () => { },
terms: {
status: 'accepted'
},
@@ -525,6 +630,15 @@ export const WithdrawAcceptedTermsXML = createExample(TestedComponent, {
export const WithdrawAcceptedTermsWithoutFee = createExample(TestedComponent, {
+ knownExchanges: [{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.demo.taler.net',
+ paytoUris: ['asd'],
+ },{
+ currency: 'USD',
+ exchangeBaseUrl: 'exchange.test.taler.net',
+ paytoUris: ['asd'],
+ }],
details: {
exchangeInfo: {
baseUrl: 'exchange.demo.taler.net'
@@ -535,9 +649,15 @@ export const WithdrawAcceptedTermsWithoutFee = createExample(TestedComponent, {
value: 0
},
} as ExchangeWithdrawDetails,
- amount: 'USD:2',
+ amount: {
+ currency: 'USD',
+ value: 2,
+ fraction: 10000000
+ },
+
+ onSwitchExchange: async () => { },
terms: {
- value : {
+ value: {
type: 'xml',
document: new DOMParser().parseFromString(termsXml, "text/xml"),
},
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
index 46451e72c..52295f1af 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw.tsx
@@ -21,18 +21,21 @@
* @author Florian Dold
*/
-import { AmountLike, Amounts, i18n, WithdrawUriInfoResponse } from '@gnu-taler/taler-util';
+import { AmountJson, Amounts, ExchangeListItem, i18n, WithdrawUriInfoResponse } from '@gnu-taler/taler-util';
import { ExchangeWithdrawDetails } from '@gnu-taler/taler-wallet-core/src/operations/withdraw';
-import { useEffect, useState } from "preact/hooks";
+import { useState } from "preact/hooks";
+import { Fragment } from 'preact/jsx-runtime';
import { CheckboxOutlined } from '../components/CheckboxOutlined';
import { ExchangeXmlTos } from '../components/ExchangeToS';
import { LogoHeader } from '../components/LogoHeader';
import { Part } from '../components/Part';
-import { ButtonDestructive, ButtonSuccess, ButtonWarning, LinkSuccess, LinkWarning, TermsOfService, WalletAction } from '../components/styled';
+import { SelectList } from '../components/SelectList';
+import { ButtonSuccess, ButtonWarning, LinkSuccess, LinkWarning, TermsOfService, WalletAction } from '../components/styled';
+import { useAsyncAsHook } from '../hooks/useAsyncAsHook';
import {
- acceptWithdrawal, getExchangeWithdrawalInfo, getWithdrawalDetailsForUri, onUpdateNotification, setExchangeTosAccepted
+ acceptWithdrawal, getExchangeWithdrawalInfo, getWithdrawalDetailsForUri, setExchangeTosAccepted, listExchanges
} from "../wxApi";
-import { h } from 'preact';
+import { wxMain } from '../wxBackend.js';
interface Props {
talerWithdrawUri?: string;
@@ -40,7 +43,8 @@ interface Props {
export interface ViewProps {
details: ExchangeWithdrawDetails;
- amount: string;
+ amount: AmountJson;
+ onSwitchExchange: (ex: string) => void;
onWithdraw: () => Promise<void>;
onReview: (b: boolean) => void;
onAccept: (b: boolean) => void;
@@ -50,7 +54,8 @@ export interface ViewProps {
terms: {
value?: TermsDocument;
status: TermsStatus;
- }
+ },
+ knownExchanges: ExchangeListItem[]
};
@@ -68,15 +73,18 @@ interface TermsDocumentHtml {
href: string,
}
-function amountToString(text: AmountLike) {
+function amountToString(text: AmountJson) {
const aj = Amounts.jsonifyAmount(text)
const amount = Amounts.stringifyValue(aj)
return `${amount} ${aj.currency}`
}
-export function View({ details, amount, onWithdraw, terms, reviewing, onReview, onAccept, accepted, confirmed }: ViewProps) {
+export function View({ details, knownExchanges, amount, onWithdraw, onSwitchExchange, terms, reviewing, onReview, onAccept, accepted, confirmed }: ViewProps) {
const needsReview = terms.status === 'changed' || terms.status === 'new'
+ const [switchingExchange, setSwitchingExchange] = useState<string | undefined>(undefined)
+ const exchanges = knownExchanges.reduce((prev, ex) => ({ ...prev, [ex.exchangeBaseUrl]: ex.exchangeBaseUrl }), {})
+
return (
<WalletAction>
<LogoHeader />
@@ -84,7 +92,7 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
{i18n.str`Digital cash withdrawal`}
</h2>
<section>
- <Part title="Total to withdraw" text={amountToString(Amounts.sub(Amounts.parseOrThrow(amount), details.withdrawFee).amount)} kind='positive' />
+ <Part title="Total to withdraw" text={amountToString(Amounts.sub(amount, details.withdrawFee).amount)} kind='positive' />
<Part title="Chosen amount" text={amountToString(amount)} kind='neutral' />
{Amounts.isNonZero(details.withdrawFee) &&
<Part title="Exchange fee" text={amountToString(details.withdrawFee)} kind='negative' />
@@ -93,11 +101,21 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
</section>
{!reviewing &&
<section>
- <LinkSuccess
- upperCased
- >
- {i18n.str`Edit exchange`}
- </LinkSuccess>
+ {switchingExchange !== undefined ? <Fragment>
+ <div>
+ <SelectList label="Known exchanges" list={exchanges} name="" onChange={onSwitchExchange} />
+ </div>
+ <p>
+ This is the list of known exchanges
+ </p>
+ <LinkSuccess upperCased onClick={() => onSwitchExchange(switchingExchange)}>
+ {i18n.str`Confirm exchange selection`}
+ </LinkSuccess>
+ </Fragment>
+ : <LinkSuccess upperCased onClick={() => setSwitchingExchange("")}>
+ {i18n.str`Switch exchange`}
+ </LinkSuccess>}
+
</section>
}
{!reviewing && accepted &&
@@ -140,6 +158,9 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
</section>
}
+ {/**
+ * Main action section
+ */}
<section>
{terms.status === 'new' && !accepted && !reviewing &&
<ButtonSuccess
@@ -178,80 +199,55 @@ export function View({ details, amount, onWithdraw, terms, reviewing, onReview,
)
}
-export function WithdrawPage({ talerWithdrawUri, ...rest }: Props): JSX.Element {
- const [uriInfo, setUriInfo] = useState<WithdrawUriInfoResponse | undefined>(undefined);
- const [details, setDetails] = useState<ExchangeWithdrawDetails | undefined>(undefined);
- const [cancelled, setCancelled] = useState(false);
- const [selecting, setSelecting] = useState(false);
- const [error, setError] = useState<boolean>(false);
- const [updateCounter, setUpdateCounter] = useState(1);
+export function WithdrawPageWithParsedURI({ uri, uriInfo }: { uri: string, uriInfo: WithdrawUriInfoResponse }) {
+ const [customExchange, setCustomExchange] = useState<string | undefined>(undefined)
+ const [errorAccepting, setErrorAccepting] = useState<string | undefined>(undefined)
+
const [reviewing, setReviewing] = useState<boolean>(false)
const [accepted, setAccepted] = useState<boolean>(false)
const [confirmed, setConfirmed] = useState<boolean>(false)
- useEffect(() => {
- return onUpdateNotification(() => {
- console.log('updating...')
- setUpdateCounter(updateCounter + 1);
- });
- }, []);
-
- useEffect(() => {
- console.log('on effect yes', talerWithdrawUri)
- if (!talerWithdrawUri) return
- const fetchData = async (): Promise<void> => {
- try {
- const res = await getWithdrawalDetailsForUri({ talerWithdrawUri });
- setUriInfo(res);
- } catch (e) {
- console.error('error', JSON.stringify(e, undefined, 2))
- setError(true)
- }
- };
- fetchData();
- }, [selecting, talerWithdrawUri, updateCounter]);
+ const knownExchangesHook = useAsyncAsHook(() => listExchanges())
- useEffect(() => {
- async function fetchData() {
- if (!uriInfo || !uriInfo.defaultExchangeBaseUrl) return
- try {
- const res = await getExchangeWithdrawalInfo({
- exchangeBaseUrl: uriInfo.defaultExchangeBaseUrl,
- amount: Amounts.parseOrThrow(uriInfo.amount),
- tosAcceptedFormat: ['text/json', 'text/xml', 'text/pdf']
- })
- setDetails(res)
- } catch (e) {
- setError(true)
- }
- }
- fetchData()
- }, [uriInfo])
+ const knownExchanges = !knownExchangesHook || knownExchangesHook.hasError ? [] : knownExchangesHook.response.exchanges
+ const withdrawAmount = Amounts.parseOrThrow(uriInfo.amount)
+ const thisCurrencyExchanges = knownExchanges.filter(ex => ex.currency === withdrawAmount.currency)
- if (!talerWithdrawUri) {
- return <span><i18n.Translate>missing withdraw uri</i18n.Translate></span>;
+ const exchange = customExchange || uriInfo.defaultExchangeBaseUrl || thisCurrencyExchanges[0]?.exchangeBaseUrl
+ const detailsHook = useAsyncAsHook(async () => {
+ if (!exchange) throw Error('no default exchange')
+ return getExchangeWithdrawalInfo({
+ exchangeBaseUrl: exchange,
+ amount: withdrawAmount,
+ tosAcceptedFormat: ['text/json', 'text/xml', 'text/pdf']
+ })
+ })
+
+ if (!detailsHook) {
+ return <span><i18n.Translate>Getting withdrawal details.</i18n.Translate></span>;
+ }
+ if (detailsHook.hasError) {
+ return <span><i18n.Translate>Problems getting details: {detailsHook.message}</i18n.Translate></span>;
}
+ const details = detailsHook.response
+
const onAccept = async (): Promise<void> => {
- if (!details) {
- throw Error("can't accept, no exchange selected");
- }
try {
- await setExchangeTosAccepted(details.exchangeDetails.exchangeBaseUrl, details.tosRequested?.tosEtag)
+ await setExchangeTosAccepted(details.exchangeInfo.baseUrl, details.tosRequested?.tosEtag)
setAccepted(true)
} catch (e) {
- setError(true)
+ if (e instanceof Error) {
+ setErrorAccepting(e.message)
+ }
}
}
const onWithdraw = async (): Promise<void> => {
- if (!details) {
- throw Error("can't accept, no exchange selected");
- }
setConfirmed(true)
- console.log("accepting exchange", details.exchangeInfo.baseUrl);
+ console.log("accepting exchange", details.exchangeDetails.exchangeBaseUrl);
try {
- const res = await acceptWithdrawal(talerWithdrawUri, details.exchangeInfo.baseUrl);
+ const res = await acceptWithdrawal(uri, details.exchangeInfo.baseUrl);
console.log("accept withdrawal response", res);
if (res.confirmTransferUrl) {
document.location.href = res.confirmTransferUrl;
@@ -261,19 +257,6 @@ export function WithdrawPage({ talerWithdrawUri, ...rest }: Props): JSX.Element
}
};
- if (cancelled) {
- return <span><i18n.Translate>Withdraw operation has been cancelled.</i18n.Translate></span>;
- }
- if (error) {
- return <span><i18n.Translate>This URI is not valid anymore.</i18n.Translate></span>;
- }
- if (!uriInfo) {
- return <span><i18n.Translate>Loading...</i18n.Translate></span>;
- }
- if (!details) {
- return <span><i18n.Translate>Getting withdrawal details.</i18n.Translate></span>;
- }
-
let termsContent: TermsDocument | undefined = undefined;
if (details.tosRequested) {
if (details.tosRequested.tosContentType === 'text/xml') {
@@ -295,14 +278,32 @@ export function WithdrawPage({ talerWithdrawUri, ...rest }: Props): JSX.Element
return <View onWithdraw={onWithdraw}
// setCancelled={setCancelled} setSelecting={setSelecting}
- details={details} amount={uriInfo.amount}
+ details={details} amount={withdrawAmount}
terms={{
status, value: termsContent
}}
+ onSwitchExchange={setCustomExchange}
+ knownExchanges={knownExchanges}
confirmed={confirmed}
accepted={accepted} onAccept={onAccept}
reviewing={reviewing} onReview={setReviewing}
// terms={[]}
/>
}
+export function WithdrawPage({ talerWithdrawUri }: Props): JSX.Element {
+ const uriInfoHook = useAsyncAsHook(() => !talerWithdrawUri ? Promise.reject(undefined) :
+ getWithdrawalDetailsForUri({ talerWithdrawUri })
+ )
+
+ if (!talerWithdrawUri) {
+ return <span><i18n.Translate>missing withdraw uri</i18n.Translate></span>;
+ }
+ if (!uriInfoHook) {
+ return <span><i18n.Translate>Loading...</i18n.Translate></span>;
+ }
+ if (uriInfoHook.hasError) {
+ return <span><i18n.Translate>This URI is not valid anymore: {uriInfoHook.message}</i18n.Translate></span>;
+ }
+ return <WithdrawPageWithParsedURI uri={talerWithdrawUri} uriInfo={uriInfoHook.response} />
+}