summaryrefslogtreecommitdiff
path: root/packages/taler-wallet-webextension/src/cta/Deposit.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/Deposit.tsx')
-rw-r--r--packages/taler-wallet-webextension/src/cta/Deposit.tsx239
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>
);
}