diff options
author | Sebastian <sebasjm@gmail.com> | 2022-08-08 14:09:28 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-08-08 14:09:36 -0300 |
commit | 7a600514c6d43bbaeba6b962533415e59fc46057 (patch) | |
tree | d96c02537cda29f1637787a8fb8e659a37ea8c1f /packages/taler-wallet-webextension/src/cta/Payment/views.tsx | |
parent | 4409d8384b77401489c2a92d3de20f79959ae34a (diff) | |
download | wallet-core-7a600514c6d43bbaeba6b962533415e59fc46057.tar.xz |
fixing #6096
merchant details and contract terms details factored out, to be used by other components
tests and stories updated
payment completed != confirmed (confirmed if paid by someone else)
Diffstat (limited to 'packages/taler-wallet-webextension/src/cta/Payment/views.tsx')
-rw-r--r-- | packages/taler-wallet-webextension/src/cta/Payment/views.tsx | 178 |
1 files changed, 113 insertions, 65 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx index a8c9a640a..4c2ddc0f2 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx @@ -15,6 +15,7 @@ */ import { + AbsoluteTime, Amounts, ConfirmPayResultType, ContractTerms, @@ -38,8 +39,10 @@ import { WalletAction, WarningBox, } from "../../components/styled/index.js"; +import { Time } from "../../components/Time.js"; import { useTranslationContext } from "../../context/translation.js"; import { Button } from "../../mui/Button.js"; +import { MerchantDetails, PurchaseDetails } from "../../wallet/Transaction.js"; import { State } from "./index.js"; export function LoadingUriView({ error }: State.LoadingUriError): VNode { @@ -56,6 +59,7 @@ export function LoadingUriView({ error }: State.LoadingUriError): VNode { type SupportedStates = | State.Ready | State.Confirmed + | State.Completed | State.NoBalanceForCurrency | State.NoEnoughBalance; @@ -63,6 +67,15 @@ export function BaseView(state: SupportedStates): VNode { const { i18n } = useTranslationContext(); const contractTerms: ContractTerms = state.payStatus.contractTerms; + const price = { + raw: state.amount, + effective: + "amountEffective" in state.payStatus + ? Amounts.parseOrThrow(state.payStatus.amountEffective) + : state.amount, + }; + const totalFees = Amounts.sub(price.effective, price.raw).amount; + return ( <WalletAction> <LogoHeader /> @@ -73,9 +86,9 @@ export function BaseView(state: SupportedStates): VNode { <ShowImportantMessage state={state} /> - <section> - {state.payStatus.status !== PreparePayResultType.InsufficientBalance && - Amounts.isNonZero(state.totalFees) && ( + <section style={{ textAlign: "left" }}> + {/* {state.payStatus.status !== PreparePayResultType.InsufficientBalance && + Amounts.isNonZero(totalFees) && ( <Part big title={<i18n.Translate>Total to pay</i18n.Translate>} @@ -89,24 +102,43 @@ export function BaseView(state: SupportedStates): VNode { text={<Amount value={state.payStatus.amountRaw} />} kind="neutral" /> - {Amounts.isNonZero(state.totalFees) && ( + {Amounts.isNonZero(totalFees) && ( <Fragment> <Part big title={<i18n.Translate>Fee</i18n.Translate>} - text={<Amount value={state.totalFees} />} + text={<Amount value={totalFees} />} kind="negative" /> </Fragment> - )} + )} */} + <Part + title={<i18n.Translate>Purchase</i18n.Translate>} + text={contractTerms.summary} + kind="neutral" + /> <Part title={<i18n.Translate>Merchant</i18n.Translate>} - text={contractTerms.merchant.name} + text={<MerchantDetails merchant={contractTerms.merchant} />} kind="neutral" /> + {/* <pre>{JSON.stringify(price)}</pre> + <hr /> + <pre>{JSON.stringify(state.payStatus, undefined, 2)}</pre> */} <Part - title={<i18n.Translate>Purchase</i18n.Translate>} - text={contractTerms.summary} + title={<i18n.Translate>Details</i18n.Translate>} + text={ + <PurchaseDetails + price={price} + info={{ + ...contractTerms, + orderId: contractTerms.order_id, + contractTermsHash: "", + products: contractTerms.products!, + }} + proposalId={state.payStatus.proposalId} + /> + } kind="neutral" /> {contractTerms.order_id && ( @@ -116,8 +148,19 @@ export function BaseView(state: SupportedStates): VNode { kind="neutral" /> )} - {contractTerms.products && contractTerms.products.length > 0 && ( - <ProductList products={contractTerms.products} /> + {contractTerms.pay_deadline && ( + <Part + title={<i18n.Translate>Valid until</i18n.Translate>} + text={ + <Time + timestamp={AbsoluteTime.fromTimestamp( + contractTerms.pay_deadline, + )} + format="dd MMMM yyyy, HH:mm" + /> + } + kind="neutral" + /> )} </section> <ButtonsSection @@ -232,7 +275,7 @@ function ShowImportantMessage({ state }: { state: SupportedStates }): VNode { ); } - if (state.status == "confirmed") { + if (state.status == "completed") { const { payResult, payHandler } = state; if (payHandler.error) { return <ErrorTalerOperation error={payHandler.error.errorDetail} />; @@ -264,7 +307,7 @@ function ShowImportantMessage({ state }: { state: SupportedStates }): VNode { return <Fragment />; } -function PayWithMobile({ state }: { state: State.Ready }): VNode { +function PayWithMobile({ state }: { state: SupportedStates }): VNode { const { i18n } = useTranslationContext(); const [showQR, setShowQR] = useState<boolean>(false); @@ -286,7 +329,7 @@ function PayWithMobile({ state }: { state: State.Ready }): VNode { <div> <QR text={privateUri} /> <i18n.Translate> - Scan the QR code or + Scan the QR code or <a href={privateUri}> <i18n.Translate>click here</i18n.Translate> </a> @@ -306,61 +349,66 @@ function ButtonsSection({ }): VNode { const { i18n } = useTranslationContext(); if (state.status === "ready") { - const { payStatus } = state; - if (payStatus.status === PreparePayResultType.PaymentPossible) { - return ( - <Fragment> - <section> - <Button - variant="contained" - color="success" - onClick={state.payHandler.onClick} - > - <i18n.Translate> - Pay {<Amount value={payStatus.amountEffective} />} - </i18n.Translate> - </Button> - </section> - <PayWithMobile state={state} /> - </Fragment> - ); - } - if (payStatus.status === PreparePayResultType.InsufficientBalance) { - let BalanceMessage = ""; - if (!state.balance) { - BalanceMessage = i18n.str`You have no balance for this currency. Withdraw digital cash first.`; + return ( + <Fragment> + <section> + <Button + variant="contained" + color="success" + onClick={state.payHandler.onClick} + > + <i18n.Translate> + Pay + {<Amount value={state.payStatus.amountEffective} />} + </i18n.Translate> + </Button> + </section> + <PayWithMobile state={state} /> + </Fragment> + ); + } + if ( + state.status === "no-enough-balance" || + state.status === "no-balance-for-currency" + ) { + // if (state.payStatus.status === PreparePayResultType.InsufficientBalance) { + let BalanceMessage = ""; + if (!state.balance) { + BalanceMessage = i18n.str`You have no balance for this currency. Withdraw digital cash first.`; + } else { + const balanceShouldBeEnough = + Amounts.cmp(state.balance, state.amount) !== -1; + if (balanceShouldBeEnough) { + BalanceMessage = i18n.str`Could not find enough coins to pay this order. Even if you have enough ${state.balance.currency} some restriction may apply.`; } else { - const balanceShouldBeEnough = - Amounts.cmp(state.balance, state.amount) !== -1; - if (balanceShouldBeEnough) { - BalanceMessage = i18n.str`Could not find enough coins to pay this order. Even if you have enough ${state.balance.currency} some restriction may apply.`; - } else { - BalanceMessage = i18n.str`Your current balance is not enough for this order.`; - } + BalanceMessage = i18n.str`Your current balance is not enough for this order.`; } - return ( - <Fragment> - <section> - <WarningBox>{BalanceMessage}</WarningBox> - </section> - <section> - <Button - variant="contained" - color="success" - onClick={() => goToWalletManualWithdraw(state.amount.currency)} - > - <i18n.Translate>Withdraw digital cash</i18n.Translate> - </Button> - </section> - <PayWithMobile state={state} /> - </Fragment> - ); } - if (payStatus.status === PreparePayResultType.AlreadyConfirmed) { + return ( + <Fragment> + <section> + <WarningBox>{BalanceMessage}</WarningBox> + </section> + <section> + <Button + variant="contained" + color="success" + onClick={() => goToWalletManualWithdraw(state.amount.currency)} + > + <i18n.Translate>Withdraw digital cash</i18n.Translate> + </Button> + </section> + <PayWithMobile state={state} /> + </Fragment> + ); + // } + } + if (state.status === "confirmed") { + if (state.payStatus.status === PreparePayResultType.AlreadyConfirmed) { return ( <Fragment> <section> - {payStatus.paid && + {state.payStatus.paid && state.payStatus.contractTerms.fulfillment_message && ( <Part title={<i18n.Translate>Merchant message</i18n.Translate>} @@ -369,13 +417,13 @@ function ButtonsSection({ /> )} </section> - {!payStatus.paid && <PayWithMobile state={state} />} + {!state.payStatus.paid && <PayWithMobile state={state} />} </Fragment> ); } } - if (state.status === "confirmed") { + if (state.status === "completed") { if (state.payResult.type === ConfirmPayResultType.Pending) { return ( <section> |