diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/Deposit.tsx')
-rw-r--r-- | packages/taler-wallet-webextension/src/cta/Deposit.tsx | 239 |
1 files changed, 31 insertions, 208 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.tsx index 541bc733b..23c557b0c 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit.tsx +++ b/packages/taler-wallet-webextension/src/cta/Deposit.tsx @@ -39,6 +39,8 @@ import { TalerError } from "@gnu-taler/taler-wallet-core"; import { Fragment, h, VNode } from "preact"; import { useEffect, useState } from "preact/hooks"; import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js"; +import { Loading } from "../components/Loading.js"; +import { LoadingError } from "../components/LoadingError.js"; import { LogoHeader } from "../components/LogoHeader.js"; import { Part } from "../components/Part.js"; import { @@ -49,157 +51,50 @@ import { WarningBox, } from "../components/styled/index.js"; import { useTranslationContext } from "../context/translation.js"; -import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; +import { HookError, useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; import * as wxApi from "../wxApi.js"; interface Props { - talerPayUri?: string; + talerDepositUri?: string; goBack: () => void; } -export function DepositPage({ talerPayUri, goBack }: Props): VNode { - const { i18n } = useTranslationContext(); - const [payStatus, setPayStatus] = useState<PreparePayResult | undefined>( - undefined, - ); - const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>( - undefined, - ); - const [payErrMsg, setPayErrMsg] = useState<TalerError | string | undefined>( - undefined, - ); - - const balance = useAsyncAsHook(wxApi.getBalance, [ - NotificationType.CoinWithdrawn, - ]); - 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; - // We use a string here so that dependency tracking for useEffect works properly - const foundAmountStr = foundAmount - ? Amounts.stringify(foundAmount) - : undefined; +type State = Loading | Ready; +interface Loading { + status: "loading"; + hook: HookError | undefined; +} +interface Ready { + status: "ready"; +} - useEffect(() => { - if (!talerPayUri) return; - const doFetch = async (): Promise<void> => { - try { - const p = await wxApi.preparePay(talerPayUri); - setPayStatus(p); - } catch (e) { - console.log("Got error while trying to pay", e); - if (e instanceof TalerError) { - setPayErrMsg(e); - } - if (e instanceof Error) { - setPayErrMsg(e.message); - } - } - }; - doFetch(); - }, [talerPayUri, foundAmountStr]); +function useComponentState(uri: string | undefined): State { + return { + status: "loading", + hook: undefined, + }; +} - if (!talerPayUri) { - return ( - <span> - <i18n.Translate>missing pay uri</i18n.Translate> - </span> - ); - } +export function DepositPage({ talerDepositUri, goBack }: Props): VNode { + const { i18n } = useTranslationContext(); - if (!payStatus) { - if (payErrMsg instanceof TalerError) { - return ( - <WalletAction> - <LogoHeader /> - <SubTitle> - <i18n.Translate>Digital cash payment</i18n.Translate> - </SubTitle> - <section> - <ErrorTalerOperation - title={ - <i18n.Translate> - Could not get the payment information for this order - </i18n.Translate> - } - error={payErrMsg?.errorDetail} - /> - </section> - </WalletAction> - ); - } - if (payErrMsg) { - return ( - <WalletAction> - <LogoHeader /> - <SubTitle> - <i18n.Translate>Digital cash payment</i18n.Translate> - </SubTitle> - <section> - <p> - <i18n.Translate> - Could not get the payment information for this order - </i18n.Translate> - </p> - <ErrorBox>{payErrMsg}</ErrorBox> - </section> - </WalletAction> - ); - } + const state = useComponentState(talerDepositUri); + if (state.status === "loading") { + if (!state.hook) return <Loading />; return ( - <span> - <i18n.Translate>Loading payment information</i18n.Translate> ... - </span> + <LoadingError + title={<i18n.Translate>Could not load pay status</i18n.Translate>} + error={state.hook} + /> ); } - - const onClick = async (): Promise<void> => { - // try { - // const res = await doPayment(payStatus); - // setPayResult(res); - // } catch (e) { - // console.error(e); - // if (e instanceof Error) { - // setPayErrMsg(e.message); - // } - // } - }; - - return ( - <PaymentRequestView - uri={talerPayUri} - payStatus={payStatus} - payResult={payResult} - onClick={onClick} - balance={foundAmount} - /> - ); + return <View state={state} />; } -export interface PaymentRequestViewProps { - payStatus: PreparePayResult; - payResult?: ConfirmPayResult; - onClick: () => void; - payErrMsg?: string; - uri: string; - balance: AmountJson | undefined; +export interface ViewProps { + state: State; } -export function PaymentRequestView({ - payStatus, - payResult, -}: PaymentRequestViewProps): VNode { - const totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw); - const contractTerms: ContractTerms = payStatus.contractTerms; +export function View({ state }: ViewProps): VNode { const { i18n } = useTranslationContext(); return ( @@ -209,78 +104,6 @@ export function PaymentRequestView({ <SubTitle> <i18n.Translate>Digital cash deposit</i18n.Translate> </SubTitle> - {payStatus.status === PreparePayResultType.AlreadyConfirmed && - (payStatus.paid ? ( - <SuccessBox> - <i18n.Translate>Already paid</i18n.Translate> - </SuccessBox> - ) : ( - <WarningBox> - <i18n.Translate>Already claimed</i18n.Translate> - </WarningBox> - ))} - {payResult && payResult.type === ConfirmPayResultType.Done && ( - <SuccessBox> - <h3> - <i18n.Translate>Payment complete</i18n.Translate> - </h3> - <p> - {!payResult.contractTerms.fulfillment_message ? ( - <i18n.Translate> - You will now be sent back to the merchant you came from. - </i18n.Translate> - ) : ( - payResult.contractTerms.fulfillment_message - )} - </p> - </SuccessBox> - )} - <section> - {payStatus.status !== PreparePayResultType.InsufficientBalance && - Amounts.isNonZero(totalFees) && ( - <Part - big - title={<i18n.Translate>Total to pay</i18n.Translate>} - text={amountToPretty( - Amounts.parseOrThrow(payStatus.amountEffective), - )} - kind="negative" - /> - )} - <Part - big - title={<i18n.Translate>Purchase amount</i18n.Translate>} - text={amountToPretty(Amounts.parseOrThrow(payStatus.amountRaw))} - kind="neutral" - /> - {Amounts.isNonZero(totalFees) && ( - <Fragment> - <Part - big - title={<i18n.Translate>Fee</i18n.Translate>} - text={amountToPretty(totalFees)} - kind="negative" - /> - </Fragment> - )} - <Part - title={<i18n.Translate>Merchant</i18n.Translate>} - text={contractTerms.merchant.name} - kind="neutral" - /> - <Part - title={<i18n.Translate>Purchase</i18n.Translate>} - text={contractTerms.summary} - kind="neutral" - /> - {contractTerms.order_id && ( - <Part - title={<i18n.Translate>Receipt</i18n.Translate>} - text={`#${contractTerms.order_id}`} - kind="neutral" - /> - )} - </section> </WalletAction> ); } |