From fb22009ec4799a624f00c228fbd7435b44c1cbac Mon Sep 17 00:00:00 2001 From: Sebastian Date: Mon, 10 Jan 2022 16:04:53 -0300 Subject: deposit design from belen, feature missing: kyc --- .../src/cta/Deposit.stories.tsx | 168 ++++++++++++++ .../taler-wallet-webextension/src/cta/Deposit.tsx | 251 +++++++++++++++++++++ packages/taler-wallet-webextension/src/cta/Pay.tsx | 29 +-- 3 files changed, 421 insertions(+), 27 deletions(-) create mode 100644 packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx create mode 100644 packages/taler-wallet-webextension/src/cta/Deposit.tsx (limited to 'packages/taler-wallet-webextension/src/cta') diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx new file mode 100644 index 000000000..df5947bb1 --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/Deposit.stories.tsx @@ -0,0 +1,168 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU Taler is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + GNU Taler; see the file COPYING. If not, see + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import { ContractTerms, PreparePayResultType } from "@gnu-taler/taler-util"; +import { createExample } from "../test-utils"; +import { PaymentRequestView as TestedComponent } from "./Deposit"; + +export default { + title: "cta/deposit", + component: TestedComponent, + argTypes: {}, +}; + +export const NoBalance = createExample(TestedComponent, { + payStatus: { + status: PreparePayResultType.InsufficientBalance, + noncePriv: "", + proposalId: "proposal1234", + contractTerms: { + merchant: { + name: "someone", + }, + summary: "some beers", + amount: "USD:10", + } as Partial as any, + amountRaw: "USD:10", + }, +}); + +export const NoEnoughBalance = createExample(TestedComponent, { + payStatus: { + status: PreparePayResultType.InsufficientBalance, + noncePriv: "", + proposalId: "proposal1234", + contractTerms: { + merchant: { + name: "someone", + }, + summary: "some beers", + amount: "USD:10", + } as Partial as any, + amountRaw: "USD:10", + }, + balance: { + currency: "USD", + fraction: 40000000, + value: 9, + }, +}); + +export const PaymentPossible = createExample(TestedComponent, { + uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + payStatus: { + status: PreparePayResultType.PaymentPossible, + amountEffective: "USD:10", + amountRaw: "USD:10", + noncePriv: "", + contractTerms: { + nonce: "123213123", + merchant: { + name: "someone", + }, + amount: "USD:10", + summary: "some beers", + } as Partial as any, + contractTermsHash: "123456", + proposalId: "proposal1234", + }, +}); + +export const PaymentPossibleWithFee = createExample(TestedComponent, { + uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", + payStatus: { + status: PreparePayResultType.PaymentPossible, + amountEffective: "USD:10.20", + amountRaw: "USD:10", + noncePriv: "", + contractTerms: { + nonce: "123213123", + merchant: { + name: "someone", + }, + amount: "USD:10", + summary: "some beers", + } as Partial as any, + contractTermsHash: "123456", + proposalId: "proposal1234", + }, +}); + +export const AlreadyConfirmedWithFullfilment = createExample(TestedComponent, { + payStatus: { + status: PreparePayResultType.AlreadyConfirmed, + amountEffective: "USD:10", + amountRaw: "USD:10", + contractTerms: { + merchant: { + name: "someone", + }, + fulfillment_message: + "congratulations! you are looking at the fulfillment message! ", + summary: "some beers", + amount: "USD:10", + } as Partial as any, + contractTermsHash: "123456", + proposalId: "proposal1234", + paid: false, + }, +}); + +export const AlreadyConfirmedWithoutFullfilment = createExample( + TestedComponent, + { + payStatus: { + status: PreparePayResultType.AlreadyConfirmed, + amountEffective: "USD:10", + amountRaw: "USD:10", + contractTerms: { + merchant: { + name: "someone", + }, + summary: "some beers", + amount: "USD:10", + } as Partial as any, + contractTermsHash: "123456", + proposalId: "proposal1234", + paid: false, + }, + }, +); + +export const AlreadyPaid = createExample(TestedComponent, { + payStatus: { + status: PreparePayResultType.AlreadyConfirmed, + amountEffective: "USD:10", + amountRaw: "USD:10", + contractTerms: { + merchant: { + name: "someone", + }, + fulfillment_message: + "congratulations! you are looking at the fulfillment message! ", + summary: "some beers", + amount: "USD:10", + } as Partial as any, + contractTermsHash: "123456", + proposalId: "proposal1234", + paid: true, + }, +}); diff --git a/packages/taler-wallet-webextension/src/cta/Deposit.tsx b/packages/taler-wallet-webextension/src/cta/Deposit.tsx new file mode 100644 index 000000000..3696b0c2d --- /dev/null +++ b/packages/taler-wallet-webextension/src/cta/Deposit.tsx @@ -0,0 +1,251 @@ +/* + This file is part of TALER + (C) 2015 GNUnet e.V. + + TALER is free software; you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation; either version 3, or (at your option) any later version. + + TALER is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR + A PARTICULAR PURPOSE. See the GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along with + TALER; see the file COPYING. If not, see + */ + +/** + * Page shown to the user to confirm entering + * a contract. + */ + +/** + * Imports. + */ +// import * as i18n from "../i18n"; + +import { + AmountJson, + Amounts, + amountToPretty, + ConfirmPayResult, + ConfirmPayResultDone, + ConfirmPayResultType, + ContractTerms, + i18n, + NotificationType, + PreparePayResult, + PreparePayResultType, +} from "@gnu-taler/taler-util"; +import { OperationFailedError } from "@gnu-taler/taler-wallet-core"; +import { Fragment, h, VNode } from "preact"; +import { useEffect, useState } from "preact/hooks"; +import { ErrorTalerOperation } from "../components/ErrorTalerOperation"; +import { LogoHeader } from "../components/LogoHeader"; +import { Part } from "../components/Part"; +import { + ErrorBox, + SuccessBox, + WalletAction, + WarningBox, +} from "../components/styled"; +import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; +import * as wxApi from "../wxApi"; + +interface Props { + talerPayUri?: string; + goBack: () => void; +} + +export function DepositPage({ talerPayUri, goBack }: Props): VNode { + const [payStatus, setPayStatus] = useState( + undefined, + ); + const [payResult, setPayResult] = useState( + undefined, + ); + const [payErrMsg, setPayErrMsg] = useState< + OperationFailedError | 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; + + useEffect(() => { + if (!talerPayUri) return; + const doFetch = async (): Promise => { + try { + const p = await wxApi.preparePay(talerPayUri); + setPayStatus(p); + } catch (e) { + console.log("Got error while trying to pay", e); + if (e instanceof OperationFailedError) { + setPayErrMsg(e); + } + if (e instanceof Error) { + setPayErrMsg(e.message); + } + } + }; + doFetch(); + }, [talerPayUri, foundAmountStr]); + + if (!talerPayUri) { + return missing pay uri; + } + + if (!payStatus) { + if (payErrMsg instanceof OperationFailedError) { + return ( + + +

{i18n.str`Digital cash payment`}

+
+ +
+
+ ); + } + if (payErrMsg) { + return ( + + +

{i18n.str`Digital cash payment`}

+
+

Could not get the payment information for this order

+ {payErrMsg} +
+
+ ); + } + return Loading payment information ...; + } + + const onClick = async (): Promise => { + // try { + // const res = await doPayment(payStatus); + // setPayResult(res); + // } catch (e) { + // console.error(e); + // if (e instanceof Error) { + // setPayErrMsg(e.message); + // } + // } + }; + + return ( + + ); +} + +export interface PaymentRequestViewProps { + payStatus: PreparePayResult; + payResult?: ConfirmPayResult; + onClick: () => void; + payErrMsg?: string; + uri: string; + balance: AmountJson | undefined; +} +export function PaymentRequestView({ + uri, + payStatus, + payResult, + onClick, + balance, +}: PaymentRequestViewProps): VNode { + let totalFees: AmountJson = Amounts.getZero(payStatus.amountRaw); + const contractTerms: ContractTerms = payStatus.contractTerms; + + return ( + + + +

{i18n.str`Digital cash deposit`}

+ {payStatus.status === PreparePayResultType.AlreadyConfirmed && + (payStatus.paid ? ( + Already paid + ) : ( + Already claimed + ))} + {payResult && payResult.type === ConfirmPayResultType.Done && ( + +

Payment complete

+

+ {!payResult.contractTerms.fulfillment_message + ? "You will now be sent back to the merchant you came from." + : payResult.contractTerms.fulfillment_message} +

+
+ )} +
+ {payStatus.status !== PreparePayResultType.InsufficientBalance && + Amounts.isNonZero(totalFees) && ( + + )} + + {Amounts.isNonZero(totalFees) && ( + + + + )} + + + {contractTerms.order_id && ( + + )} +
+
+ ); +} diff --git a/packages/taler-wallet-webextension/src/cta/Pay.tsx b/packages/taler-wallet-webextension/src/cta/Pay.tsx index d7419d410..e61d3a9d6 100644 --- a/packages/taler-wallet-webextension/src/cta/Pay.tsx +++ b/packages/taler-wallet-webextension/src/cta/Pay.tsx @@ -57,35 +57,10 @@ import * as wxApi from "../wxApi"; interface Props { talerPayUri?: string; - goToWalletManualWithdraw: () => void; + goToWalletManualWithdraw: (currency?: string) => void; + goBack: () => void; } -// 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 => { -- cgit v1.2.3