From e9bb85a212dbd9b86875e89a0aca5d805e2ad61b Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 13 Aug 2021 18:04:05 -0300 Subject: new wallet UI and more tests --- .../taler-wallet-webextension/src/wallet/Pay.tsx | 287 ++++++++++++--------- 1 file changed, 158 insertions(+), 129 deletions(-) (limited to 'packages/taler-wallet-webextension/src/wallet/Pay.tsx') diff --git a/packages/taler-wallet-webextension/src/wallet/Pay.tsx b/packages/taler-wallet-webextension/src/wallet/Pay.tsx index bd06656c7..a5849bb28 100644 --- a/packages/taler-wallet-webextension/src/wallet/Pay.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Pay.tsx @@ -29,7 +29,7 @@ import * as wxApi from "../wxApi"; import { useState, useEffect } from "preact/hooks"; -import { getJsonI18n, i18n } from "@gnu-taler/taler-util"; +import { ConfirmPayResultDone, getJsonI18n, i18n } from "@gnu-taler/taler-util"; import { PreparePayResult, ConfirmPayResult, @@ -45,13 +45,54 @@ interface Props { talerPayUri?: string } +export function AlreadyPaid({ payStatus }: { payStatus: PreparePayResult }) { + const fulfillmentUrl = payStatus.contractTerms.fulfillment_url; + let message; + if (fulfillmentUrl) { + message = ( + + You have already paid for this article. Click{" "} + here to view it again. + + ); + } else { + message = + You have already paid for this article:{" "} + + {payStatus.contractTerms.fulfillment_message ?? "no message given"} + + ; + } + return
+

GNU Taler Wallet

+
+ {message} +
+
+} + +const doPayment = async (payStatus: PreparePayResult): Promise => { + if (payStatus.status !== "payment-possible") { + throw Error(`invalid state: ${payStatus.status}`); + } + const proposalId = payStatus.proposalId; + const res = await wxApi.confirmPay(proposalId, undefined); + if (res.type !== ConfirmPayResultType.Done) { + throw Error("payment pending"); + } + const fu = res.contractTerms.fulfillment_url; + if (fu) { + document.location.href = fu; + } + return res; +}; + + + export function PayPage({ talerPayUri }: Props): JSX.Element { const [payStatus, setPayStatus] = useState(undefined); const [payResult, setPayResult] = useState(undefined); const [payErrMsg, setPayErrMsg] = useState(""); - const [numTries, setNumTries] = useState(0); - const [loading, setLoading] = useState(false); - let totalFees: AmountJson | undefined = undefined; useEffect(() => { if (!talerPayUri) return; @@ -60,53 +101,67 @@ export function PayPage({ talerPayUri }: Props): JSX.Element { setPayStatus(p); }; doFetch(); - }, [numTries, talerPayUri]); + }, [talerPayUri]); if (!talerPayUri) { return missing pay uri } - + if (!payStatus) { return Loading payment information ...; } - let insufficientBalance = false; - if (payStatus.status == PreparePayResultType.InsufficientBalance) { - insufficientBalance = true; - } - - if (payStatus.status === PreparePayResultType.PaymentPossible) { - const amountRaw = Amounts.parseOrThrow(payStatus.amountRaw); - const amountEffective: AmountJson = Amounts.parseOrThrow( - payStatus.amountEffective, - ); - totalFees = Amounts.sub(amountEffective, amountRaw).amount; - } - - if ( - payStatus.status === PreparePayResultType.AlreadyConfirmed && - numTries === 0 - ) { - const fulfillmentUrl = payStatus.contractTerms.fulfillment_url; - if (fulfillmentUrl) { + if (payResult && payResult.type === ConfirmPayResultType.Done) { + if (payResult.contractTerms.fulfillment_message) { + const obj = { + fulfillment_message: payResult.contractTerms.fulfillment_message, + fulfillment_message_i18n: + payResult.contractTerms.fulfillment_message_i18n, + }; + const msg = getJsonI18n(obj, "fulfillment_message"); return ( - - You have already paid for this article. Click{" "} - here to view it again. - +
+

Payment succeeded.

+

{msg}

+
); } else { - - You have already paid for this article:{" "} - - {payStatus.contractTerms.fulfillment_message ?? "no message given"} - - ; + return Redirecting ...; } } + const onClick = async () => { + try { + const res = await doPayment(payStatus) + setPayResult(res); + } catch (e) { + console.error(e); + setPayErrMsg(e.message); + } + + } + + return ; +} + +export interface PaymentRequestViewProps { + payStatus: PreparePayResult; + onClick: () => void; + payErrMsg?: string; + +} +export function PaymentRequestView({ payStatus, onClick, payErrMsg }: PaymentRequestViewProps) { + let totalFees: AmountJson | undefined = undefined; + let insufficientBalance = false; + const [loading, setLoading] = useState(false); const contractTerms: ContractTerms = payStatus.contractTerms; + if ( + payStatus.status === PreparePayResultType.AlreadyConfirmed + ) { + return + } + if (!contractTerms) { return ( @@ -115,6 +170,18 @@ export function PayPage({ talerPayUri }: Props): JSX.Element { ); } + if (payStatus.status == PreparePayResultType.InsufficientBalance) { + insufficientBalance = true; + } + + if (payStatus.status === PreparePayResultType.PaymentPossible) { + const amountRaw = Amounts.parseOrThrow(payStatus.amountRaw); + const amountEffective: AmountJson = Amounts.parseOrThrow( + payStatus.amountEffective, + ); + totalFees = Amounts.sub(amountEffective, amountRaw).amount; + } + let merchantName: VNode; if (contractTerms.merchant && contractTerms.merchant.name) { merchantName = {contractTerms.merchant.name}; @@ -126,99 +193,61 @@ export function PayPage({ talerPayUri }: Props): JSX.Element { {renderAmount(Amounts.parseOrThrow(contractTerms.amount))} ); - const doPayment = async (): Promise => { - if (payStatus.status !== "payment-possible") { - throw Error(`invalid state: ${payStatus.status}`); - } - const proposalId = payStatus.proposalId; - setNumTries(numTries + 1); - try { - setLoading(true); - const res = await wxApi.confirmPay(proposalId, undefined); - if (res.type !== ConfirmPayResultType.Done) { - throw Error("payment pending"); - } - const fu = res.contractTerms.fulfillment_url; - if (fu) { - document.location.href = fu; - } - setPayResult(res); - } catch (e) { - console.error(e); - setPayErrMsg(e.message); - } - }; - - if (payResult && payResult.type === ConfirmPayResultType.Done) { - if (payResult.contractTerms.fulfillment_message) { - const obj = { - fulfillment_message: payResult.contractTerms.fulfillment_message, - fulfillment_message_i18n: - payResult.contractTerms.fulfillment_message_i18n, - }; - const msg = getJsonI18n(obj, "fulfillment_message"); - return ( -
-

Payment succeeded.

-

{msg}

-
- ); - } else { - return Redirecting ...; - } - } - - return ( -
-

- - The merchant {merchantName} offers you to purchase: - -

- {contractTerms.summary} -
- {totalFees ? ( + return
+

GNU Taler Wallet

+
+
+

- The total price is {amount} - (plus {renderAmount(totalFees)} fees). - + The merchant {merchantName} offers you to purchase: + +

+ {contractTerms.summary} +
+ {totalFees ? ( + + The total price is {amount} + (plus {renderAmount(totalFees)} fees). + + ) : ( + + The total price is {amount}. + + )} +

+ + {insufficientBalance ? ( +
+

+ Unable to pay: Your balance is insufficient. +

+
+ ) : null} + + {payErrMsg ? ( +
+

Payment failed: {payErrMsg}

+ +
) : ( - - The total price is {amount}. - - )} -

- - {insufficientBalance ? ( -
-

- Unable to pay: Your balance is insufficient. -

-
- ) : null} - - {payErrMsg ? ( -
-

Payment failed: {payErrMsg}

- -
- ) : ( -
- doPayment()} - > - {i18n.str`Confirm payment`} - -
- )} -
- ); -} - +
+ + {i18n.str`Confirm payment`} + +
+ )} +
+ + + + +} \ No newline at end of file -- cgit v1.2.3