diff options
author | Sebastian <sebasjm@gmail.com> | 2023-01-04 11:24:58 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-01-04 11:38:00 -0300 |
commit | 24cac493dded00ef40e0e30a0d2263e4f35c3e29 (patch) | |
tree | 1bbd1fb4f9149af349358491c3720750d031d255 /packages/taler-wallet-webextension/src/components/PaymentButtons.tsx | |
parent | 7d02e4212346b7b7b88197259a7e74554e1b10a3 (diff) | |
download | wallet-core-24cac493dded00ef40e0e30a0d2263e4f35c3e29.tar.xz |
fix #7522
Diffstat (limited to 'packages/taler-wallet-webextension/src/components/PaymentButtons.tsx')
-rw-r--r-- | packages/taler-wallet-webextension/src/components/PaymentButtons.tsx | 153 |
1 files changed, 153 insertions, 0 deletions
diff --git a/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx b/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx new file mode 100644 index 000000000..def1e16eb --- /dev/null +++ b/packages/taler-wallet-webextension/src/components/PaymentButtons.tsx @@ -0,0 +1,153 @@ +/* + This file is part of GNU Taler + (C) 2022 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 <http://www.gnu.org/licenses/> + */ + +import { + AmountJson, + Amounts, + PreparePayResult, + PreparePayResultType, +} from "@gnu-taler/taler-util"; +import { Fragment, h, VNode } from "preact"; +import { useState } from "preact/hooks"; +import { Amount } from "./Amount.js"; +import { Part } from "./Part.js"; +import { QR } from "./QR.js"; +import { LinkSuccess, WarningBox } from "./styled/index.js"; +import { useTranslationContext } from "../context/translation.js"; +import { Button } from "../mui/Button.js"; +import { ButtonHandler } from "../mui/handlers.js"; +import { assertUnreachable } from "../utils/index.js"; + +interface Props { + payStatus: PreparePayResult; + payHandler: ButtonHandler | undefined; + balance: AmountJson | undefined; + uri: string; + amount: AmountJson; + goToWalletManualWithdraw: (currency: string) => Promise<void>; +} + +export function PaymentButtons({ + payStatus, + uri, + payHandler, + balance, + amount, + goToWalletManualWithdraw, +}: Props): VNode { + const { i18n } = useTranslationContext(); + if (payStatus.status === PreparePayResultType.PaymentPossible) { + const privateUri = `${uri}&n=${payStatus.noncePriv}`; + + return ( + <Fragment> + <section> + <Button + variant="contained" + color="success" + onClick={payHandler?.onClick} + > + <i18n.Translate> + Pay + {<Amount value={amount} />} + </i18n.Translate> + </Button> + </section> + <PayWithMobile uri={privateUri} /> + </Fragment> + ); + } + + if (payStatus.status === PreparePayResultType.InsufficientBalance) { + let BalanceMessage = ""; + if (!balance) { + BalanceMessage = i18n.str`You have no balance for this currency. Withdraw digital cash first.`; + } else { + const balanceShouldBeEnough = Amounts.cmp(balance, amount) !== -1; + if (balanceShouldBeEnough) { + BalanceMessage = i18n.str`Could not find enough coins to pay. Even if you have enough ${balance.currency} some restriction may apply.`; + } else { + BalanceMessage = i18n.str`Your current balance is not enough.`; + } + } + const uriPrivate = `${uri}&n=${payStatus.noncePriv}`; + + return ( + <Fragment> + <section> + <WarningBox>{BalanceMessage}</WarningBox> + </section> + <section> + <Button + variant="contained" + color="success" + onClick={() => goToWalletManualWithdraw(Amounts.stringify(amount))} + > + <i18n.Translate>Get digital cash</i18n.Translate> + </Button> + </section> + <PayWithMobile uri={uriPrivate} /> + </Fragment> + ); + } + if (payStatus.status === PreparePayResultType.AlreadyConfirmed) { + return ( + <Fragment> + <section> + {payStatus.paid && payStatus.contractTerms.fulfillment_message && ( + <Part + title={<i18n.Translate>Merchant message</i18n.Translate>} + text={payStatus.contractTerms.fulfillment_message} + kind="neutral" + /> + )} + </section> + {!payStatus.paid && <PayWithMobile uri={uri} />} + </Fragment> + ); + } + + assertUnreachable(payStatus); +} + +function PayWithMobile({ uri }: { uri: string }): VNode { + const { i18n } = useTranslationContext(); + + const [showQR, setShowQR] = useState<boolean>(false); + + return ( + <section> + <LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}> + {!showQR ? ( + <i18n.Translate>Pay with a mobile phone</i18n.Translate> + ) : ( + <i18n.Translate>Hide QR</i18n.Translate> + )} + </LinkSuccess> + {showQR && ( + <div> + <QR text={uri} /> + <i18n.Translate> + Scan the QR code or + <a href={uri}> + <i18n.Translate>click here</i18n.Translate> + </a> + </i18n.Translate> + </div> + )} + </section> + ); +} |