diff options
Diffstat (limited to 'packages/merchant-backend/src/pages')
11 files changed, 0 insertions, 1545 deletions
diff --git a/packages/merchant-backend/src/pages/DepletedTip.stories.tsx b/packages/merchant-backend/src/pages/DepletedTip.stories.tsx deleted file mode 100644 index c20f6dc..0000000 --- a/packages/merchant-backend/src/pages/DepletedTip.stories.tsx +++ /dev/null @@ -1,40 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ - -import { h, VNode, FunctionalComponent } from 'preact'; -import { DepletedTip as TestedComponent } from './DepletedTip'; - - -export default { - title: 'DepletedTip', - component: TestedComponent, - argTypes: { - }, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -export const Example = createExample(TestedComponent, { -}); diff --git a/packages/merchant-backend/src/pages/DepletedTip.tsx b/packages/merchant-backend/src/pages/DepletedTip.tsx deleted file mode 100644 index 756b08d..0000000 --- a/packages/merchant-backend/src/pages/DepletedTip.tsx +++ /dev/null @@ -1,60 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ -import { Fragment, h, render, VNode } from 'preact'; -import { render as renderToString } from 'preact-render-to-string'; -import { Footer } from '../components/Footer'; -import "../css/pure-min.css"; -import "../css/style.css"; -import { Page } from '../styled'; - -function Head(): VNode { - return <title>Status of your tip</title> -} - -export function DepletedTip(): VNode { - return <Page> - <section> - <h1>Tip already collected</h1> - <div> - You have already collected this tip. - </div> - </section> - <Footer /> - </Page> -} - -export function mount(): void { - try { - render(<DepletedTip />, document.body); - } catch (e) { - console.error("got error", e); - if (e instanceof Error) { - document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`; - } - } -} - -export function buildTimeRendering(): { head: string, body: string } { - return { - head: renderToString(<Head />), - body: renderToString(<DepletedTip />) - } -} diff --git a/packages/merchant-backend/src/pages/OfferRefund.stories.tsx b/packages/merchant-backend/src/pages/OfferRefund.stories.tsx deleted file mode 100644 index 92694f8..0000000 --- a/packages/merchant-backend/src/pages/OfferRefund.stories.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ - -import { h, VNode, FunctionalComponent } from 'preact'; -import { createSVG } from '../components/QR'; -import { OfferRefund as TestedComponent } from './OfferRefund'; - - -export default { - title: 'OfferRefund', - component: TestedComponent, - argTypes: { - }, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -const REFUND_URI_EXAMPLE = 'taler://pay/backend.demo.taler.net/instances/blog/2021.249-022NW2KG88QGA/def537eb-00c2-4a8b-8a17-0be034d118d3?c=2Y4N4PMST7KYAPS83428GTPCD4' - -export const Example = createExample(TestedComponent, { - refundURI: REFUND_URI_EXAMPLE, - qr_code: createSVG(REFUND_URI_EXAMPLE) -}); diff --git a/packages/merchant-backend/src/pages/OfferRefund.tsx b/packages/merchant-backend/src/pages/OfferRefund.tsx deleted file mode 100644 index 14c9372..0000000 --- a/packages/merchant-backend/src/pages/OfferRefund.tsx +++ /dev/null @@ -1,154 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ -import { Fragment, h, render, VNode } from 'preact'; -import { render as renderToString } from 'preact-render-to-string'; -import { useEffect } from 'preact/hooks'; -import { Footer } from '../components/Footer'; -import { QR } from '../components/QR'; -import "../css/pure-min.css"; -import "../css/style.css"; -import { Page, QRPlaceholder, WalletLink } from '../styled'; - -/** - * This page creates a refund offer QR code - * - * It will build into a mustache html template for server side rendering - * - * server side rendering params: - * - order_status_url - * - taler_refund_qrcode_svg - * - taler_refund_uri - * - * request params: - * - refund_uri - * - order_status_url - */ - -interface Props { - refundURI?: string; - order_status_url?: string; - qr_code?: string; -} - -function Head({ order_summary }: { order_summary?: string }): VNode { - return <Fragment> - <meta charSet="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <noscript> - <meta http-equiv="refresh" content="1" /> - </noscript> - <title>Refund available for {order_summary ? order_summary : `{{ order_summary }}`}</title> - </Fragment> -} - -export function OfferRefund({ refundURI, qr_code, order_status_url }: Props): VNode { - useEffect(() => { - let checkUrl: URL; - try { - checkUrl = new URL(order_status_url ? order_status_url : "{{& order_status_url }}"); - } catch (e) { - return; - } - checkUrl.searchParams.set("await_refund_obtained", "yes"); - const delayMs = 500; - function check() { - let retried = false; - function retryOnce() { - if (!retried) { - retried = true; - check(); - } - } - const req = new XMLHttpRequest(); - req.onreadystatechange = function () { - if (req.readyState === XMLHttpRequest.DONE) { - if (req.status === 200) { - try { - const resp = JSON.parse(req.responseText); - if (!resp.refund_pending) { - window.location.reload(); - } - } catch (e) { - console.error("could not parse response:", e); - } - } - setTimeout(retryOnce, delayMs); - } - }; - req.onerror = function () { - setTimeout(retryOnce, delayMs); - } - req.open("GET", checkUrl.href); - req.send(); - } - - setTimeout(check, delayMs); - }) - return <Page> - <section> - <h1>Collect Taler refund</h1> - <p> - Scan this QR code with your Taler mobile wallet: - </p> - <QRPlaceholder dangerouslySetInnerHTML={{ __html: qr_code ? qr_code : `{{{ taler_refund_qrcode_svg }}}` }} /> - <p> - <WalletLink href={refundURI ? refundURI : `{{ taler_refund_uri }}`}> - Or open your Taller wallet - </WalletLink> - </p> - <p> - <a href="https://wallet.taler.net/">Don't have a Taler wallet yet? Install it!</a> - </p> - </section> - <Footer /> - </Page> -} - -export function mount(): void { - try { - const fromLocation = new URL(window.location.href).searchParams - const os = fromLocation.get('order_summary') || undefined; - if (os) { - render(<Head order_summary={os} />, document.head); - } - - const uri = fromLocation.get('refund_uri') || undefined; - const osu = fromLocation.get('order_status_url') || undefined; - const qr_code = uri ? renderToString(<QR text={uri} />) : undefined; - - render(<OfferRefund - refundURI={uri} order_status_url={osu} - qr_code={qr_code} - />, document.body); - } catch (e) { - console.error("got error", e); - if (e instanceof Error) { - document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`; - } - } -} - -export function buildTimeRendering(): { head: string, body: string } { - return { - head: renderToString(<Head />), - body: renderToString(<OfferRefund />) - } -} diff --git a/packages/merchant-backend/src/pages/OfferTip.stories.tsx b/packages/merchant-backend/src/pages/OfferTip.stories.tsx deleted file mode 100644 index dfbf71f..0000000 --- a/packages/merchant-backend/src/pages/OfferTip.stories.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ - -import { h, VNode, FunctionalComponent } from 'preact'; -import { createSVG } from '../components/QR'; -import { OfferTip as TestedComponent } from './OfferTip'; - - -export default { - title: 'OfferTip', - component: TestedComponent, - argTypes: { - }, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -const TIP_URI_EXAMPLE = 'taler+http://tip/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0' - -export const Example = createExample(TestedComponent, { - tipURI: TIP_URI_EXAMPLE, - qr_code: createSVG(TIP_URI_EXAMPLE) -}); diff --git a/packages/merchant-backend/src/pages/OfferTip.tsx b/packages/merchant-backend/src/pages/OfferTip.tsx deleted file mode 100644 index ace1059..0000000 --- a/packages/merchant-backend/src/pages/OfferTip.tsx +++ /dev/null @@ -1,141 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ -import { Fragment, h, render, VNode } from 'preact'; -import { render as renderToString } from 'preact-render-to-string'; -import { useEffect } from 'preact/hooks'; -import { Footer } from '../components/Footer'; -import { QR } from '../components/QR'; -import "../css/pure-min.css"; -import "../css/style.css"; -import { Page, QRPlaceholder, WalletLink } from '../styled'; -import { ShowOrderDetails } from './ShowOrderDetails'; - - -/** - * This page creates a tip offer QR code - * - * It will build into a mustache html template for server side rendering - * - * server side rendering params: - * - tip_status_url - * - taler_tip_qrcode_svg - * - taler_tip_uri - * - * request params: - * - tip_uri - * - tip_status_url - */ - -interface Props { - tipURI?: string, - tip_status_url?: string, - qr_code?: string, -} - -export function Head(): VNode { - return <Fragment> - <meta charSet="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <noscript> - <meta http-equiv="refresh" content="1" /> - </noscript> - <title>Tip available</title> - </Fragment> -} - -export function OfferTip({ tipURI, qr_code, tip_status_url }: Props): VNode { - useEffect(() => { - let checkUrl: URL; - try { - checkUrl = new URL(tip_status_url ? tip_status_url : "{{& tip_status_url }}"); - } catch (e) { - return; - } - - const delayMs = 500; - function check() { - let retried = false; - function retryOnce() { - if (!retried) { - retried = true; - check(); - } - } - const req = new XMLHttpRequest(); - req.onreadystatechange = function () { - if (req.readyState === XMLHttpRequest.DONE) { - if (req.status === 410) { - window.location.reload(); - } - setTimeout(retryOnce, delayMs); - } - }; - req.onerror = function () { - setTimeout(retryOnce, delayMs); - } - req.open("GET", checkUrl.href); - req.send(); - } - - setTimeout(check, delayMs); - }) - return <Page> - <section> - <h1 >Collect Taler tip</h1> - <p> - Scan this QR code with your Taler mobile wallet: - </p> - <QRPlaceholder dangerouslySetInnerHTML={{ __html: qr_code ? qr_code : `{{{ taler_tip_qrcode_svg }}}` }} /> - <p> - <WalletLink href={tipURI ? tipURI : `{{ taler_tip_uri }}`}> - Or open your Taller wallet - </WalletLink> - </p> - <p> - <a href="https://wallet.taler.net/">Don't have a Taler wallet yet? Install it!</a> - </p> - </section> - <Footer /> - </Page> -} - -export function mount(): void { - try { - const fromLocation = new URL(window.location.href).searchParams - - const uri = fromLocation.get('tip_uri') || undefined - const tsu = fromLocation.get('tip_status_url') || undefined - - render(<OfferTip tipURI={uri} tip_status_url={tsu} />, document.body); - } catch (e) { - console.error("got error", e); - if (e instanceof Error) { - document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`; - } - } -} - -export function buildTimeRendering(): { head: string, body: string } { - return { - head: renderToString(<Head />), - body: renderToString(<ShowOrderDetails />) - } -} diff --git a/packages/merchant-backend/src/pages/RequestPayment.stories.tsx b/packages/merchant-backend/src/pages/RequestPayment.stories.tsx deleted file mode 100644 index 5d6d79a..0000000 --- a/packages/merchant-backend/src/pages/RequestPayment.stories.tsx +++ /dev/null @@ -1,45 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ - -import { FunctionalComponent, h } from 'preact'; -import { createSVG } from '../components/QR'; -import { RequestPayment as TestedComponent } from './RequestPayment'; - - -export default { - title: 'RequestPayment', - component: TestedComponent, - argTypes: { - }, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -const PAYTO_URI_EXAMPLE = 'taler+http://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0' - -export const Example = createExample(TestedComponent, { - payURI: 'taler+http://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0', - qr_code: createSVG(PAYTO_URI_EXAMPLE) -}); diff --git a/packages/merchant-backend/src/pages/RequestPayment.tsx b/packages/merchant-backend/src/pages/RequestPayment.tsx deleted file mode 100644 index 050755d..0000000 --- a/packages/merchant-backend/src/pages/RequestPayment.tsx +++ /dev/null @@ -1,196 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ -import { Fragment, h, render, VNode } from "preact"; -import { render as renderToString } from "preact-render-to-string"; -import { useEffect } from "preact/hooks"; -import { Footer } from "../components/Footer"; -import "../css/pure-min.css"; -import "../css/style.css"; -import { QR } from "../components/QR"; -import { Page, QRPlaceholder, WalletLink } from "../styled"; - -/** - * This page creates a payment request QR code - * - * It will build into a mustache html template for server side rendering - * - * server side rendering params: - * - order_status_url - * - taler_pay_qrcode_svg - * - taler_pay_uri - * - order_summary - * - * request params: - * - pay_uri - * - order_summary - * - order_status_url - */ - -interface Props { - payURI?: string; - order_status_url?: string; - qr_code?: string; -} - -function Head({ order_summary }: { order_summary?: string }): VNode { - return ( - <Fragment> - <meta charSet="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <noscript> - <meta http-equiv="refresh" content="1" /> - </noscript> - <title> - Payment requested for{" "} - {order_summary ? order_summary : `{{ order_summary }}`} - </title> - </Fragment> - ); -} - -export function RequestPayment({ - payURI, - qr_code, - order_status_url, -}: Props): VNode { - useEffect(() => { - const longpollDelayMs = 60 * 1000; - let checkUrl: URL; - try { - checkUrl = new URL( - order_status_url ? order_status_url : "{{& order_status_url }}" - ); - } catch (e) { - return; - } - checkUrl.searchParams.set("timeout_s", longpollDelayMs.toString()); - function check() { - let retried = false; - function retryOnce() { - if (!retried) { - retried = true; - check(); - } - } - const req = new XMLHttpRequest(); - req.onreadystatechange = function () { - if (req.readyState === XMLHttpRequest.DONE) { - if (req.status === 200) { - try { - const resp = JSON.parse(req.responseText); - if (resp.fulfillment_url) { - window.location.replace(resp.fulfillment_url); - } - } catch (e) { - console.error("could not parse response:", e); - } - } - if (req.status === 202) { - try { - const resp = JSON.parse(req.responseText); - if (resp.fulfillment_url) { - window.location.replace(resp.fulfillment_url); - } - } catch (e) { - console.error("could not parse response:", e); - } - } - if (req.status === 402) { - try { - const resp = JSON.parse(req.responseText); - if (resp.already_paid_order_id && resp.fulfillment_url) { - window.location.replace(resp.fulfillment_url); - } - } catch (e) { - console.error("could not parse response:", e); - } - } - setTimeout(retryOnce, 500); - } - }; - req.onerror = function () { - setTimeout(retryOnce, 500); - }; - req.ontimeout = function () { - setTimeout(retryOnce, 500); - }; - req.timeout = longpollDelayMs; - req.open("GET", checkUrl.href); - req.send(); - } - setTimeout(check, 500); - }); - return ( - <Page> - <section> - <h1>Pay with Taler</h1> - <p>Scan this QR code with your mobile wallet:</p> - <QRPlaceholder - dangerouslySetInnerHTML={{ - __html: qr_code ? qr_code : `{{{ taler_pay_qrcode_svg }}}`, - }} - /> - <p> - <WalletLink href={payURI ? payURI : `{{ taler_pay_uri }}`}> - Or open your Taller wallet - </WalletLink> - </p> - <p> - <a href="https://wallet.taler.net/"> - Don't have a Taler wallet yet? Install it! - </a> - </p> - </section> - <Footer /> - </Page> - ); -} - -export function mount(): void { - try { - const fromLocation = new URL(window.location.href).searchParams; - const os = fromLocation.get("order_summary") || undefined; - if (os) { - render(<Head order_summary={os} />, document.head); - } - - const uri = fromLocation.get("pay_uri") || undefined; - const osu = fromLocation.get("order_status_url") || undefined; - const qr_code = uri ? renderToString(<QR text={uri} />) : undefined; - - render( - <RequestPayment payURI={uri} order_status_url={osu} qr_code={qr_code} />, - document.body - ); - } catch (e) { - console.error("got error", e); - if (e instanceof Error) { - document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`; - } - } -} - -export function buildTimeRendering(): { head: string; body: string } { - return { - head: renderToString(<Head />), - body: renderToString(<RequestPayment />), - }; -} diff --git a/packages/merchant-backend/src/pages/ShowOrderDetails.examples.ts b/packages/merchant-backend/src/pages/ShowOrderDetails.examples.ts deleted file mode 100644 index ba68397..0000000 --- a/packages/merchant-backend/src/pages/ShowOrderDetails.examples.ts +++ /dev/null @@ -1,219 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ - -import { MerchantBackend } from '../declaration'; -import { Props } from './ShowOrderDetails'; - - -const defaultContractTerms: MerchantBackend.ContractTerms = { - order_id: 'XRS8876388373', - amount: 'USD:10', - summary: 'this is a short summary', - pay_deadline: { - t_s: new Date().getTime() + 6 * 24 * 60 * 60 * 1000 - }, - merchant: { - name: 'the merchant (inc)', - address: { - country_subdivision: 'Buenos Aires', - town: 'CABA', - country: 'Argentina' - }, - jurisdiction: { - country_subdivision: 'Cordoba', - town: 'Capital', - country: 'Argentina' - }, - }, - max_fee: 'USD:0.1', - max_wire_fee: 'USD:0.2', - wire_fee_amortization: 1, - products: [], - timestamp: { - t_s: new Date().getTime() - }, - auditors: [], - exchanges: [], - h_wire: '', - merchant_base_url: 'http://merchant.base.url/', - merchant_pub: 'QWEASDQWEASD', - nonce: 'NONCE', - refund_deadline: { - t_s: new Date().getTime() + 6 * 24 * 60 * 60 * 1000 - }, - wire_method: 'x-taler-bank', - wire_transfer_deadline: { - t_s: new Date().getTime() + 3 * 24 * 60 * 60 * 1000 - }, -}; - -const inSixDays = new Date().getTime() + 6 * 24 * 60 * 60 * 1000 -const in10Minutes = new Date().getTime() + 10 * 60 * 1000 -const in15Minutes = new Date().getTime() + 15 * 60 * 1000 -const in20Minutes = new Date().getTime() + 20 * 60 * 1000 - -export const exampleData: { [name: string]: Props } = { - Simplest: { - order_summary: 'here goes the order summary', - contract_terms: defaultContractTerms, - }, - WithRefundAmount: { - order_summary: 'here goes the order summary', - refund_amount: 'USD:10', - contract_terms: defaultContractTerms, - }, - WithDeliveryDate: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - delivery_date: { - t_s: inSixDays - }, - }, - }, - WithDeliveryLocation: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - delivery_location: { - address_lines: ['addr line 1', 'addr line 2', 'addr line 3', 'addr line 4', 'addr line 5', 'addr line 6', 'addr line 7'], - building_name: 'building-name', - building_number: 'building-number', - country: 'country', - country_subdivision: 'country sub', - district: 'district', - post_code: 'post-code', - street: 'street', - town: 'town', - town_location: 'town loc', - }, - }, - }, - WithDeliveryLocationAndDate: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - delivery_location: { - address_lines: ['addr1', 'addr2', 'addr3', 'addr4', 'addr5', 'addr6', 'addr7'], - building_name: 'building-name', - building_number: 'building-number', - country: 'country', - country_subdivision: 'country sub', - district: 'district', - post_code: 'post-code', - street: 'street', - town: 'town', - town_location: 'town loc', - }, - delivery_date: { - t_s: inSixDays - }, - }, - }, - WithThreeProducts: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - products: [{ - description: 'description of the first product', - price: '5:USD', - quantity: 1, - delivery_date: { t_s: in10Minutes }, - product_id: '12333', - }, { - description: 'another description', - price: '10:USD', - quantity: 5, - unit: 't-shirt', - }, { - description: 'one last description', - price: '10:USD', - quantity: 5 - }] - } as MerchantBackend.ContractTerms - }, - WithProductWithTaxes: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - products: [{ - description: 'description of the first product', - price: '5:USD', - quantity: 1, - unit: 'beer', - delivery_date: { t_s: in10Minutes }, - product_id: '456', - taxes: [{ - name: 'VAT', tax: 'USD:1' - }], - }, { - description: 'one last description', - price: '10:USD', - quantity: 5, - product_id: '123', - unit: 'beer', - taxes: [{ - name: 'VAT', tax: 'USD:1' - }], - }] - } as MerchantBackend.ContractTerms - }, - WithExchangeList: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - exchanges: [{ - master_pub: 'ABCDEFGHIJKLMNO', - url: 'http://exchange0.taler.net' - }, { - master_pub: 'AAAAAAAAAAAAAAA', - url: 'http://exchange1.taler.net' - }, { - master_pub: 'BBBBBBBBBBBBBBB', - url: 'http://exchange2.taler.net' - }] - }, - }, - WithAuditorList: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - auditors: [{ - auditor_pub: 'ABCDEFGHIJKLMNO', - name: 'the USD auditor', - url: 'http://auditor-usd.taler.net' - }, { - auditor_pub: 'OPQRSTUVWXYZABCD', - name: 'the EUR auditor', - url: 'http://auditor-eur.taler.net' - }] - }, - }, - WithAutoRefund: { - order_summary: 'here goes the order summary', - contract_terms: { - ...defaultContractTerms, - auto_refund: { - d_us: 1000 * 60 * 60 * 26 + 1000 * 60 * 30 - } - }, - }, -} diff --git a/packages/merchant-backend/src/pages/ShowOrderDetails.stories.tsx b/packages/merchant-backend/src/pages/ShowOrderDetails.stories.tsx deleted file mode 100644 index 6a902cc..0000000 --- a/packages/merchant-backend/src/pages/ShowOrderDetails.stories.tsx +++ /dev/null @@ -1,49 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** -* -* @author Sebastian Javier Marchano (sebasjm) -*/ - -import { FunctionalComponent, h } from 'preact'; -import { ShowOrderDetails as TestedComponent } from './ShowOrderDetails'; -import { exampleData } from './ShowOrderDetails.examples'; - -export default { - title: 'ShowOrderDetails', - component: TestedComponent, - argTypes: { - }, - excludeStories: /.*Data$/, -}; - -function createExample<Props>(Component: FunctionalComponent<Props>, props: Partial<Props>) { - const r = (args: any) => <Component {...args} /> - r.args = props - return r -} - -export const Simplest = createExample(TestedComponent, exampleData.Simplest); -export const WithRefundAmount = createExample(TestedComponent, exampleData.WithRefundAmount); -export const WithDeliveryDate = createExample(TestedComponent, exampleData.WithDeliveryDate); -export const WithDeliveryLocation = createExample(TestedComponent, exampleData.WithDeliveryLocation); -export const WithDeliveryLocationAndDate = createExample(TestedComponent, exampleData.WithDeliveryLocationAndDate); -export const WithThreeProducts = createExample(TestedComponent, exampleData.WithThreeProducts); -export const WithAuditorList = createExample(TestedComponent, exampleData.WithAuditorList); -export const WithExchangeList = createExample(TestedComponent, exampleData.WithExchangeList); -export const WithAutoRefund = createExample(TestedComponent, exampleData.WithAutoRefund); -export const WithProductWithTaxes = createExample(TestedComponent, exampleData.WithProductWithTaxes); diff --git a/packages/merchant-backend/src/pages/ShowOrderDetails.tsx b/packages/merchant-backend/src/pages/ShowOrderDetails.tsx deleted file mode 100644 index aa62c29..0000000 --- a/packages/merchant-backend/src/pages/ShowOrderDetails.tsx +++ /dev/null @@ -1,551 +0,0 @@ -/* - 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 <http://www.gnu.org/licenses/> - */ - -/** - * - * @author Sebastian Javier Marchano (sebasjm) - */ -import { format, formatDuration } from "date-fns"; -import { intervalToDuration } from "date-fns/esm"; -import { Fragment, h, render, VNode } from "preact"; -import { render as renderToString } from "preact-render-to-string"; -import { Footer } from "../components/Footer"; -import "../css/pure-min.css"; -import "../css/style.css"; -import { MerchantBackend } from "../declaration"; -import { Page, InfoBox, TableExpanded, TableSimple } from "../styled"; - -/** - * This page creates a payment request QR code - * - * It will build into a mustache html template for server side rendering - * - * server side rendering params: - * - order_summary - * - contract_terms - * - refund_amount - * - * request params: - * - refund_amount - * - contract_terms - * - order_summary - */ - -export interface Props { - btr?: boolean; // build time rendering flag - order_summary?: string; - refund_amount?: string; - contract_terms?: MerchantBackend.ContractTerms; -} - -function Head({ order_summary }: { order_summary?: string }): VNode { - return ( - <Fragment> - <meta charSet="UTF-8" /> - <meta name="viewport" content="width=device-width, initial-scale=1.0" /> - <noscript> - <meta http-equiv="refresh" content="1" /> - </noscript> - <title> - Status of your order for{" "} - {order_summary ? order_summary : `{{ order_summary }}`} - </title> - <script>{` - var contractTermsStr = '{{{contract_terms_json}}}'; - `}</script> - </Fragment> - ); -} - -function Location({ - templateName, - location, - btr, -}: { - templateName: string; - location: MerchantBackend.Location | undefined; - btr?: boolean; -}) { - //FIXME: mustache strings show be constructed in a way that ends in the final output of the html but is not present in the - // javascript code, otherwise when mustache render engine run over the html it will also replace string in the javascript code - // that is made to run when the browser has javascript enable leading into undefined behavior. - // that's why in the next fields we are using concatenations to build the mustache placeholder. - return ( - <Fragment> - {btr && `{{` + `#${templateName}.building_name}}`} - <dd> - {location?.building_name || - (btr && `{{ ${templateName}.building_name }}`)}{" "} - {location?.building_number || - (btr && `{{ ${templateName}.building_number }}`)} - </dd> - {btr && `{{` + `/${templateName}.building_name}}`} - - {btr && `{{` + `#${templateName}.country}}`} - <dd> - {location?.country || (btr && `{{ ${templateName}.country }}`)}{" "} - {location?.country_subdivision || - (btr && `{{ ${templateName}.country_subdivision }}`)} - </dd> - {btr && `{{` + `/${templateName}.country}}`} - - {btr && `{{` + `#${templateName}.district}}`} - <dd>{location?.district || (btr && `{{ ${templateName}.district }}`)}</dd> - {btr && `{{` + `/${templateName}.district}}`} - - {btr && `{{` + `#${templateName}.post_code}}`} - <dd> - {location?.post_code || (btr && `{{ ${templateName}.post_code }}`)} - </dd> - {btr && `{{` + `/${templateName}.post_code}}`} - - {btr && `{{` + `#${templateName}.street}}`} - <dd>{location?.street || (btr && `{{ ${templateName}.street }}`)}</dd> - {btr && `{{` + `/${templateName}.street}}`} - - {btr && `{{` + `#${templateName}.town}}`} - <dd>{location?.town || (btr && `{{ ${templateName}.town }}`)}</dd> - {btr && `{{` + `/${templateName}.town}}`} - - {btr && `{{` + `#${templateName}.town_location}}`} - <dd> - {location?.town_location || - (btr && `{{ ${templateName}.town_location }}`)} - </dd> - {btr && `{{` + `/${templateName}.town_location}}`} - </Fragment> - ); -} - -export function ShowOrderDetails({ - order_summary, - refund_amount, - contract_terms, - btr, -}: Props): VNode { - const productList = btr - ? [{} as MerchantBackend.Product] - : contract_terms?.products || []; - const auditorsList = btr - ? [{} as MerchantBackend.Auditor] - : contract_terms?.auditors || []; - const exchangesList = btr - ? [{} as MerchantBackend.Exchange] - : contract_terms?.exchanges || []; - const hasDeliveryInfo = - btr || - !!contract_terms?.delivery_date || - !!contract_terms?.delivery_location; - - return ( - <Page> - <header> - <h1> - Details of order{" "} - {contract_terms?.order_id || `{{ contract_terms.order_id }}`} - </h1> - </header> - - <section> - {btr && `{{#refund_amount}}`} - {(btr || refund_amount) && ( - <section> - <InfoBox> - <b>Refunded:</b> The merchant refunded you{" "} - <b>{refund_amount || `{{ refund_amount }}`}</b>. - </InfoBox> - </section> - )} - {btr && `{{/refund_amount}}`} - - <section> - <TableExpanded> - <dt>Order summary:</dt> - <dd>{contract_terms?.summary || `{{ contract_terms.summary }}`}</dd> - <dt>Amount paid:</dt> - <dd>{contract_terms?.amount || `{{ contract_terms.amount }}`}</dd> - <dt>Order date:</dt> - <dd> - {contract_terms?.timestamp - ? contract_terms?.timestamp.t_s != "never" - ? format( - contract_terms?.timestamp.t_s, - "dd MMM yyyy HH:mm:ss" - ) - : "never" - : `{{ contract_terms.timestamp_str }}`}{" "} - </dd> - <dt>Merchant name:</dt> - <dd> - {contract_terms?.merchant.name || - `{{ contract_terms.merchant.name }}`} - </dd> - </TableExpanded> - </section> - - {btr && `{{#contract_terms.hasProducts}}`} - {!productList.length ? null : ( - <section> - <h2>Products purchased</h2> - <TableSimple> - {btr && "{{" + "#contract_terms.products" + "}}"} - {productList.map((p, i) => { - const taxList = btr - ? [{} as MerchantBackend.Tax] - : p.taxes || []; - - return ( - <Fragment key={i}> - <p>{p.description || `{{description}}`}</p> - <dl> - <dt>Quantity:</dt> - <dd>{p.quantity || `{{quantity}}`}</dd> - - <dt>Price:</dt> - <dd>{p.price || `{{price}}`}</dd> - - {btr && `{{#hasTaxes}}`} - {!taxList.length ? null : ( - <Fragment> - {btr && "{{" + "#taxes" + "}}"} - {taxList.map((t, i) => { - return ( - <Fragment key={i}> - <dt>{t.name || `{{name}}`}</dt> - <dd>{t.tax || `{{tax}}`}</dd> - </Fragment> - ); - })} - {btr && "{{" + "/taxes" + "}}"} - </Fragment> - )} - {btr && `{{/hasTaxes}}`} - - {btr && `{{#delivery_date}}`} - {(btr || p.delivery_date) && ( - <Fragment> - <dt>Delivered on:</dt> - <dd> - {p.delivery_date - ? p.delivery_date.t_s != "never" - ? format( - p.delivery_date.t_s, - "dd MMM yyyy HH:mm:ss" - ) - : "never" - : `{{ delivery_date_str }}`}{" "} - </dd> - </Fragment> - )} - {btr && `{{/delivery_date}}`} - - {btr && `{{#unit}}`} - {(btr || p.unit) && ( - <Fragment> - <dt>Product unit:</dt> - <dd>{p.unit || `{{.}}`}</dd> - </Fragment> - )} - {btr && `{{/unit}}`} - - {btr && `{{#product_id}}`} - {(btr || p.product_id) && ( - <Fragment> - <dt>Product ID:</dt> - <dd>{p.product_id || `{{.}}`}</dd> - </Fragment> - )} - {btr && `{{/product_id}}`} - </dl> - </Fragment> - ); - })} - {btr && "{{" + "/contract_terms.products" + "}}"} - </TableSimple> - </section> - )} - {btr && `{{/contract_terms.hasProducts}}`} - - {btr && `{{#contract_terms.has_delivery_info}}`} - {!hasDeliveryInfo ? null : ( - <section> - <h2>Delivery information</h2> - <TableExpanded> - {btr && `{{#contract_terms.delivery_date}}`} - {(btr || contract_terms?.delivery_date) && ( - <Fragment> - <dt>Delivery date:</dt> - <dd> - {contract_terms?.delivery_date - ? contract_terms?.delivery_date.t_s != "never" - ? format( - contract_terms?.delivery_date.t_s, - "dd MMM yyyy HH:mm:ss" - ) - : "never" - : `{{ contract_terms.delivery_date_str }}`}{" "} - </dd> - </Fragment> - )} - {btr && `{{/contract_terms.delivery_date}}`} - - {btr && `{{#contract_terms.delivery_location}}`} - {(btr || contract_terms?.delivery_location) && ( - <Fragment> - <dt>Delivery address:</dt> - <Location - btr={btr} - location={contract_terms?.delivery_location} - templateName="contract_terms.delivery_location" - /> - </Fragment> - )} - {btr && `{{/contract_terms.delivery_location}}`} - </TableExpanded> - </section> - )} - {btr && `{{/contract_terms.has_delivery_info}}`} - - <section> - <h2>Full payment information</h2> - <TableExpanded> - <dt>Amount paid:</dt> - <dd>{contract_terms?.amount || `{{ contract_terms.amount }}`}</dd> - <dt>Wire transfer method:</dt> - <dd> - {contract_terms?.wire_method || - `{{ contract_terms.wire_method }}`} - </dd> - <dt>Payment deadline:</dt> - <dd> - {contract_terms?.pay_deadline - ? contract_terms?.pay_deadline.t_s != "never" - ? format( - contract_terms?.pay_deadline.t_s, - "dd MMM yyyy HH:mm:ss" - ) - : "never" - : `{{ contract_terms.pay_deadline_str }}`}{" "} - </dd> - <dt>Exchange transfer deadline:</dt> - <dd> - {contract_terms?.wire_transfer_deadline - ? contract_terms?.wire_transfer_deadline.t_s != "never" - ? format( - contract_terms?.wire_transfer_deadline.t_s, - "dd MMM yyyy HH:mm:ss" - ) - : "never" - : `{{ contract_terms.wire_transfer_deadline_str }}`}{" "} - </dd> - <dt>Maximum deposit fee:</dt> - <dd>{contract_terms?.max_fee || `{{ contract_terms.max_fee }}`}</dd> - <dt>Maximum wire fee:</dt> - <dd> - {contract_terms?.max_wire_fee || - `{{ contract_terms.max_wire_fee }}`} - </dd> - <dt>Wire fee amortization:</dt> - <dd> - {contract_terms?.wire_fee_amortization || - `{{ contract_terms.wire_fee_amortization }}`}{" "} - transactions - </dd> - </TableExpanded> - </section> - - <section> - <h2>Refund information</h2> - <TableExpanded> - <dt>Refund deadline:</dt> - <dd> - {contract_terms?.refund_deadline - ? contract_terms?.refund_deadline.t_s != "never" - ? format( - contract_terms?.refund_deadline.t_s, - "dd MMM yyyy HH:mm:ss" - ) - : "never" - : `{{ contract_terms.refund_deadline_str }}`}{" "} - </dd> - - {btr && `{{#contract_terms.auto_refund}}`} - {(btr || contract_terms?.auto_refund) && ( - <Fragment> - <dt>Attempt autorefund for:</dt> - <dd> - {contract_terms?.auto_refund - ? contract_terms?.auto_refund.d_us != "forever" - ? formatDuration( - intervalToDuration({ - start: 0, - end: contract_terms?.auto_refund.d_us, - }) - ) - : "forever" - : `{{ contract_terms.auto_refund_str }}`}{" "} - </dd> - </Fragment> - )} - {btr && `{{/contract_terms.auto_refund}}`} - </TableExpanded> - </section> - - <section> - <h2>Additional order details</h2> - <TableExpanded> - <dt>Public reorder URL:</dt> - <dd> -- not defined yet -- </dd> - {btr && `{{#contract_terms.fulfillment_url}}`} - {(btr || contract_terms?.fulfillment_url) && ( - <Fragment> - <dt>Fulfillment URL:</dt> - <dd> - {contract_terms?.fulfillment_url || - (btr && `{{ contract_terms.fulfillment_url }}`)} - </dd> - </Fragment> - )} - {btr && `{{/contract_terms.fulfillment_url}}`} - {/* <dt>Fulfillment message:</dt> - <dd> -- not defined yet -- </dd> */} - </TableExpanded> - </section> - - <section> - <h2>Full merchant information</h2> - <TableExpanded> - <dt>Merchant name:</dt> - <dd> - {contract_terms?.merchant.name || - `{{ contract_terms.merchant.name }}`} - </dd> - <dt>Merchant address:</dt> - <Location - btr={btr} - location={contract_terms?.merchant.address} - templateName="contract_terms.merchant.address" - /> - <dt>Merchant's jurisdiction:</dt> - <Location - btr={btr} - location={contract_terms?.merchant.jurisdiction} - templateName="contract_terms.merchant.jurisdiction" - /> - <dt>Merchant URI:</dt> - <dd> - {contract_terms?.merchant_base_url || - `{{ contract_terms.merchant_base_url }}`} - </dd> - <dt>Merchant's public key:</dt> - <dd> - {contract_terms?.merchant_pub || - `{{ contract_terms.merchant_pub }}`} - </dd> - {/* <dt>Merchant's hash:</dt> - <dd> -- not defined yet -- </dd> */} - </TableExpanded> - </section> - - {btr && `{{#contract_terms.hasAuditors}}`} - {!auditorsList.length ? null : ( - <section> - <h2>Auditors accepted by the merchant</h2> - <TableExpanded> - {btr && "{{" + "#contract_terms.auditors" + "}}"} - {auditorsList.map((p, i) => { - return ( - <Fragment key={i}> - <p>{p.name || `{{name}}`}</p> - <dt>Auditor's public key:</dt> - <dd>{p.auditor_pub || `{{auditor_pub}}`}</dd> - <dt>Auditor's URL:</dt> - <dd>{p.url || `{{url}}`}</dd> - </Fragment> - ); - })} - {btr && "{{" + "/contract_terms.auditors" + "}}"} - </TableExpanded> - </section> - )} - {btr && `{{/contract_terms.hasAuditors}}`} - - {btr && `{{#contract_terms.hasExchanges}}`} - {!exchangesList.length ? null : ( - <section> - <h2>Exchanges accepted by the merchant</h2> - <TableExpanded> - {btr && "{{" + "#contract_terms.exchanges" + "}}"} - {exchangesList.map((p, i) => { - return ( - <Fragment key={i}> - <dt>Exchange's URL:</dt> - <dd>{p.url || `{{url}}`}</dd> - <dt>Public key:</dt> - <dd>{p.master_pub || `{{master_pub}}`}</dd> - </Fragment> - ); - })} - {btr && "{{" + "/contract_terms.exchanges" + "}}"} - </TableExpanded> - </section> - )} - {btr && `{{/contract_terms.hasExchanges}}`} - </section> - - <Footer /> - </Page> - ); -} - -export function mount(): void { - try { - const fromLocation = new URL(window.location.href).searchParams; - const os = fromLocation.get("order_summary") || undefined; - if (os) { - render(<Head order_summary={os} />, document.head); - } - - const ra = fromLocation.get("refund_amount") || undefined; - const ct = fromLocation.get("contract_terms") || undefined; - - let contractTerms: MerchantBackend.ContractTerms | undefined; - try { - contractTerms = JSON.parse((window as any).contractTermsStr); - } catch {} - - render( - <ShowOrderDetails - contract_terms={contractTerms} - order_summary={os} - refund_amount={ra} - />, - document.body - ); - } catch (e) { - console.error("got error", e); - if (e instanceof Error) { - document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`; - } - } -} - -export function buildTimeRendering(): { head: string; body: string } { - return { - head: renderToString(<Head />), - body: renderToString(<ShowOrderDetails btr />), - }; -} |