taler-typescript-core

Wallet core logic and WebUIs for various components
Log | Files | Refs | Submodules | README | LICENSE

commit 9489b6aa37f646d25b86caec54cc536e2f14220d
parent ab3b88ceca80e49c335cfbe16b8ff8631ce54d40
Author: Sebastian <sebasjm@gmail.com>
Date:   Wed,  4 Sep 2024 11:38:27 -0300

fix #8958

Diffstat:
Mpackages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx | 103++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mpackages/taler-wallet-webextension/src/components/Modal.tsx | 2+-
Apackages/taler-wallet-webextension/src/components/ShowBanksForPaytoPopup.tsx | 61+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Apackages/taler-wallet-webextension/src/components/ShowQRsForPaytoPopup.tsx | 94+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 206 insertions(+), 54 deletions(-)

diff --git a/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx b/packages/taler-wallet-webextension/src/components/BankDetailsByPaytoType.tsx @@ -42,6 +42,9 @@ import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { useBackendContext } from "../context/backend.js"; import { QR } from "./QR.js"; import { Pages } from "../NavigationBar.js"; +import { ShowQRsForPaytoPopup } from "./ShowQRsForPaytoPopup.js"; +import { SafeHandler } from "../mui/handlers.js"; +import { ShowBanksForPaytoPopup } from "./ShowBanksForPaytoPopup.js"; export interface BankDetailsProps { subject: string; @@ -144,24 +147,6 @@ export function BankDetailsByPaytoType({ defaultCurrency={amount.currency} > <IBANAccountInfoTable payto={payto} subject={subject} /> - <div> - <a - href={`#${Pages.paytoBanks({ - payto: encodeCrockForURI(selectedAccount.paytoUri), - })}`} - > - Continue with banking app or website - </a> - </div> - <div> - <a - href={`#${Pages.paytoQrs({ - payto: encodeCrockForURI(selectedAccount.paytoUri), - })}`} - > - Show QR code - </a> - </div> </Frame> ); } @@ -174,23 +159,25 @@ function IBANAccountInfoTable({ payto: PaytoUriUnknown | PaytoUriIBAN | PaytoUriTalerBank; }) { const { i18n } = useTranslationContext(); - // const api = useBackendContext(); - - // const hook = useAsyncAsHook(async () => { - // const qrs = await api.wallet.call(WalletApiOperation.GetQrCodesForPayto, { - // paytoUri: stringifyPaytoUri(payto), - // }); - // const banks = await api.wallet.call( - // WalletApiOperation.GetBankingChoicesForPayto, - // { - // paytoUri: stringifyPaytoUri(payto), - // }, - // ); - // return { qrs, banks }; - // }, []); - - // const qrCodes = !hook || hook.hasError ? [] : hook.response.qrs.codes; - // const banksSites = !hook || hook.hasError ? [] : hook.response.banks.choices; + const api = useBackendContext(); + const [showBanks, setShowBanks] = useState(false) + const [showQrs, setShowQrs] = useState(false) + + const hook = useAsyncAsHook(async () => { + const qrs = await api.wallet.call(WalletApiOperation.GetQrCodesForPayto, { + paytoUri: stringifyPaytoUri(payto), + }); + const banks = await api.wallet.call( + WalletApiOperation.GetBankingChoicesForPayto, + { + paytoUri: stringifyPaytoUri(payto), + }, + ); + return { qrs, banks }; + }, []); + + const qrCodes = !hook || hook.hasError ? [] : hook.response.qrs.codes; + const banksSites = !hook || hook.hasError ? [] : hook.response.banks.choices; const accountPart = !payto.isKnown ? ( <Fragment> @@ -300,24 +287,34 @@ function IBANAccountInfoTable({ </td> </tr> - {/* {qrCodes.map((qr, idx) => { - return ( - <tr key={idx}> - <td colSpan={3} width="100%"> - <QR text={qr.qrContent} /> - </td> - </tr> - ); - })} - {banksSites.map((bank, idx) => { - return ( - <tr key={idx}> - <td colSpan={3} width="100%"> - {bank.label} : {bank.uri} - </td> - </tr> - ); - })} */} + {banksSites.length < 1 ? undefined : <Fragment> + <div> + <a href="#" onClick={(e) => { + setShowBanks(true); + e.preventDefault(); + }}> + <i18n.Translate>Continue with banking app or website</i18n.Translate> + </a> + </div> + + {showBanks ? <ShowBanksForPaytoPopup banks={banksSites} onClose={{ + onClick: (async () => setShowBanks(false)) as SafeHandler<void> + }} /> : undefined} + </Fragment>} + + {qrCodes.length < 1 ? undefined : <Fragment> + <div> + <a href="#" onClick={(e) => { + setShowQrs(true); + e.preventDefault(); + }}> + <i18n.Translate>Show QR code</i18n.Translate> + </a> + </div> + {showQrs ? <ShowQRsForPaytoPopup qrs={qrCodes} onClose={{ + onClick: (async () => setShowQrs(false)) as SafeHandler<void> + }} /> : undefined} + </Fragment>} </tbody> </table> ); diff --git a/packages/taler-wallet-webextension/src/components/Modal.tsx b/packages/taler-wallet-webextension/src/components/Modal.tsx @@ -52,7 +52,7 @@ const Body = styled.div` export function Modal({ title, children, onClose }: Props): VNode { return ( - <div style={{ top: 0, position: "fixed", width: "100%", height: "100%" }}> + <div style={{ top: 0, left: 0, position: "fixed", width: "100%", height: "100%" }}> <FullSize onClick={onClose?.onClick}> <div onClick={(e) => e.stopPropagation()} diff --git a/packages/taler-wallet-webextension/src/components/ShowBanksForPaytoPopup.tsx b/packages/taler-wallet-webextension/src/components/ShowBanksForPaytoPopup.tsx @@ -0,0 +1,61 @@ +/* + 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 { + BankingChoiceSpec +} from "@gnu-taler/taler-util"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { styled } from "@linaria/react"; +import { Fragment, h, VNode } from "preact"; +import { ButtonHandler } from "../mui/handlers.js"; +import { Modal } from "./Modal.js"; + +const BanksTable = styled.table` + width: 100%; + border-spacing: 0px; + & > tr > td { + padding: 5px; + } + & > tr > td:nth-child(2n) { + text-align: right; + overflow-wrap: anywhere; + } + & > tr:nth-child(2n) { + background: #ebebeb; + } +`; + +interface Props { banks: BankingChoiceSpec[], onClose: ButtonHandler }; + +export function ShowBanksForPaytoPopup({ banks, onClose }: Props): VNode { + const { i18n } = useTranslationContext(); + + return ( + <Modal title="Supported banks" onClose={onClose}> + <div style={{ overflowY: "auto", height: "95%", padding: 5 }}> + <BanksTable> + {banks.map((b, idx) => { + + return <tr key={idx}> + <td> + <a href={b.uri}>{b.label}</a> + </td> + </tr> + })} + </BanksTable> + </div> + </Modal> + ); +} diff --git a/packages/taler-wallet-webextension/src/components/ShowQRsForPaytoPopup.tsx b/packages/taler-wallet-webextension/src/components/ShowQRsForPaytoPopup.tsx @@ -0,0 +1,94 @@ +/* + 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 { + QrCodeSpec +} from "@gnu-taler/taler-util"; +import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { styled } from "@linaria/react"; +import { Fragment, h, VNode } from "preact"; +import { ButtonHandler } from "../mui/handlers.js"; +import { Modal } from "./Modal.js"; +import { QR } from "./QR.js"; +import { useState } from "preact/hooks"; + +const QRsTable = styled.table` + width: 100%; + & > tr > td { + padding: 5px; + } + & > tr > td { + border-spacing: 0px; + border-radius: 4px; + border: 1px black solid; + } + & > tr > td:nth-child(2n) { + text-align: right; + overflow-wrap: anywhere; + } +`; + +const AccordionCss = styled.div` +& > .accordion { + color: #444; + cursor: pointer; + padding: 8px; + font-size: large; + width: 100%; + text-align: left; + border: none; + outline: none; + transition: 0.4s; +} + +& > .panel { + padding: 0 18px; + background-color: white; + display: none; + overflow: hidden; +}` + +interface Props { qrs: QrCodeSpec[], onClose: ButtonHandler }; + +function Accordion({ section, content }: { section: string, content: string }): VNode { + const [opened, setOpened] = useState(false) + return <AccordionCss> + <button class={opened ? "accordion active" : "accordion"} onClick={() => { setOpened(!opened) }}>{section}</button> + <div class="panel" style={{ display: opened ? "block" : "none" }}> + <QR text={content} /> + </div> + </AccordionCss> +} + +export function ShowQRsForPaytoPopup({ qrs, onClose }: Props): VNode { + const { i18n } = useTranslationContext(); + + return ( + <Modal title="Qrs" onClose={onClose}> + <div style={{ overflowY: "auto", height: "95%", padding: 5 }}> + <QRsTable> + {qrs.map((q, idx) => { + + return <tr key={idx}> + <td> + <Accordion section={q.type} content={q.qrContent} /> + </td> + </tr> + })} + </QRsTable> + </div> + </Modal> + ); +}