diff options
author | Sebastian <sebasjm@gmail.com> | 2021-08-27 15:41:41 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2021-08-27 15:41:41 -0300 |
commit | d8750f7a066cd047ff9f71c13f67a3f8b012bc62 (patch) | |
tree | ac49f01a9f4adc9e7bc56f7c19228516543b698b | |
parent | eae88828683ec05d438dd4908d86b73e67e9707d (diff) | |
download | merchant-backoffice-d8750f7a066cd047ff9f71c13f67a3f8b012bc62.tar.gz merchant-backoffice-d8750f7a066cd047ff9f71c13f67a3f8b012bc62.tar.bz2 merchant-backoffice-d8750f7a066cd047ff9f71c13f67a3f8b012bc62.zip |
built time rendering
-rw-r--r-- | packages/backend/rollup.config.js | 10 | ||||
-rw-r--r-- | packages/backend/src/components/Footer.tsx | 29 | ||||
-rw-r--r-- | packages/backend/src/components/QR.tsx | 36 | ||||
-rw-r--r-- | packages/backend/src/pages/DepletedTip.tsx | 24 | ||||
-rw-r--r-- | packages/backend/src/pages/OfferRefund.tsx | 55 | ||||
-rw-r--r-- | packages/backend/src/pages/OfferTip.stories.tsx | 1 | ||||
-rw-r--r-- | packages/backend/src/pages/OfferTip.tsx | 34 | ||||
-rw-r--r-- | packages/backend/src/pages/RequestPayment.stories.tsx | 1 | ||||
-rw-r--r-- | packages/backend/src/pages/RequestPayment.tsx | 66 | ||||
-rw-r--r-- | packages/backend/src/pages/ShowOrderDetails.stories.tsx | 1 | ||||
-rw-r--r-- | packages/backend/src/pages/ShowOrderDetails.tsx | 13 |
11 files changed, 189 insertions, 81 deletions
diff --git a/packages/backend/rollup.config.js b/packages/backend/rollup.config.js index 9051adc..fd8da74 100644 --- a/packages/backend/rollup.config.js +++ b/packages/backend/rollup.config.js @@ -33,6 +33,8 @@ const template = async ({ }) => { const scripts = (files.js || []).map(({ code }) => `<script>${code}</script>`).join('\n'); const css = (files.css || []).map(({ source }) => `<style>${source}</style>`).join('\n'); + const ssr = (files.js || []).map(({ code }) => code).join('\n'); + const page = new Function(`${ssr}; return page.buildTimeRendering();`)() return ` <!doctype html> <html> @@ -40,9 +42,15 @@ const template = async ({ <title>${title}</title> ${css} </head> + <script id="built_time_data" /> <body> + <div id="built_time_data"/> + <div id="container_without_js"> + ${page} + </div> + <div id="container_with_js"/> ${scripts} - <script>page.mountIntoBody()</script> + <script>page.mount()</script> </body> </html>`; }; diff --git a/packages/backend/src/components/Footer.tsx b/packages/backend/src/components/Footer.tsx new file mode 100644 index 0000000..f585025 --- /dev/null +++ b/packages/backend/src/components/Footer.tsx @@ -0,0 +1,29 @@ +/* + 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 } from 'preact'; + +export function Footer(): VNode { + return <div class="talerbar"> + <p>You can learn more about GNU Taler on our <a href="https://taler.net/">website</a>.<br /> + Copyright © 2014—2021 Taler Systems SA</p> + </div> +} + diff --git a/packages/backend/src/components/QR.tsx b/packages/backend/src/components/QR.tsx new file mode 100644 index 0000000..95aee36 --- /dev/null +++ b/packages/backend/src/components/QR.tsx @@ -0,0 +1,36 @@ +/* + 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/> + */ + + import { h, VNode } from "preact"; + import { useEffect, useRef } from "preact/hooks"; + import qrcode from "qrcode-generator"; + + export function QR({ text }: { text: string; }):VNode { + const divRef = useRef<HTMLDivElement>(null); + useEffect(() => { + const qr = qrcode(0, 'L'); + qr.addData(text); + qr.make(); + divRef.current.innerHTML = qr.createSvgTag({ + scalable: true, + }); + }); + + return <div style={{ width: '100%', display: 'flex', flexDirection: 'column', alignItems: 'center' }}> + <div style={{ width: '50%', minWidth: 200, maxWidth: 300 }} ref={divRef} /> + </div>; + } +
\ No newline at end of file diff --git a/packages/backend/src/pages/DepletedTip.tsx b/packages/backend/src/pages/DepletedTip.tsx index f9cf9bb..d8eae75 100644 --- a/packages/backend/src/pages/DepletedTip.tsx +++ b/packages/backend/src/pages/DepletedTip.tsx @@ -18,12 +18,21 @@ * * @author Sebastian Javier Marchano (sebasjm) */ -import { h, render, VNode } from 'preact'; +import { h, render, Fragment, VNode } from 'preact'; +import { Footer } from '../components/Footer'; +import { ShowOrderDetails } from './ShowOrderDetails'; +import { render as renderToString } from 'preact-render-to-string'; export function DepletedTip(): VNode { - return <div> - You have already collected this tip. - </div> + return <Fragment> + <section id="main" class="content"> + <h1 style={{ textAlign: 'center' }}>Tip already collected</h1> + <div style={{ textAlign: 'center' }}> + You have already collected this tip. + </div> + </section> + <Footer /> + </Fragment> } export function Title(): VNode { @@ -31,11 +40,11 @@ export function Title(): VNode { } -export function mountIntoBody(): void { +export function mount(): void { try { const params = new URL(window.location.href).searchParams render(<DepletedTip - // taler_refund_uri={params.get('taler_refund_uri') || undefined} + // taler_refund_uri={params.get('taler_refund_uri') || undefined} />, document.body); } catch (e) { console.error("got error", e); @@ -43,3 +52,6 @@ export function mountIntoBody(): void { } } +export function buildTimeRendering(): string { + return renderToString(<ShowOrderDetails />) +} diff --git a/packages/backend/src/pages/OfferRefund.tsx b/packages/backend/src/pages/OfferRefund.tsx index 6c6b77e..7b35a54 100644 --- a/packages/backend/src/pages/OfferRefund.tsx +++ b/packages/backend/src/pages/OfferRefund.tsx @@ -18,8 +18,11 @@ * * @author Sebastian Javier Marchano (sebasjm) */ -import { render, h, VNode } from 'preact'; +import { render, h, Fragment, VNode } from 'preact'; import { useEffect } from 'preact/hooks'; +import { Footer } from '../components/Footer'; +import { ShowOrderDetails } from './ShowOrderDetails'; +import { render as renderToString } from 'preact-render-to-string'; export function OfferRefund(): VNode { useEffect(() => { @@ -59,39 +62,40 @@ export function OfferRefund(): VNode { setTimeout(check, delayMs); }) - return <section id="main" class="content"> - <h1 >Collect Taler refund</h1> - <div class="taler-installed-hide"> - <p> - Scan this QR code with your Taler mobile wallet: - </p> - <div class="qr"> - {/* {{{taler_refund_qrcode_svg}}} */} + return <Fragment> + <section id="main" class="content"> + <h1 style={{ textAlign: 'center' }}>Collect Taler refund</h1> + <div style={{ textAlign: 'center' }} class="taler-installed-hide"> + <p> + Scan this QR code with your Taler mobile wallet: + </p> + <div class="qr"> + {/* {{{taler_refund_qrcode_svg}}} */} + </div> + <p> + <a class="pure-button pure-button-active success" href='{{taler_refund_uri}}'> + Or open your Taller wallet + </a> + </p> + <p> + <a href="https://wallet.taler.net/">Don't have a Taler wallet yet? Install it!</a> + </p> </div> - <p> - <button onClick={() => { - window.location.href = '{{taler_refund_uri}}' - }}> - Or open your Taller wallet - </button> - </p> - <p> - <a href="https://wallet.taler.net/">Don't have a Taler wallet yet? Install it!</a> - </p> - </div> - <hr /> - </section> + <hr /> + </section> + <Footer /> + </Fragment> } export function Title(): VNode { return <title>Refund available for {`{order_summary}`}</title> } -export function mountIntoBody(): void { +export function mount(): void { try { const params = new URL(window.location.href).searchParams render(<OfferRefund - // taler_refund_uri={params.get('taler_refund_uri') || undefined} + // taler_refund_uri={params.get('taler_refund_uri') || undefined} />, document.body); } catch (e) { console.error("got error", e); @@ -99,5 +103,8 @@ export function mountIntoBody(): void { } } +export function buildTimeRendering(): string { + return renderToString(<ShowOrderDetails />) +} diff --git a/packages/backend/src/pages/OfferTip.stories.tsx b/packages/backend/src/pages/OfferTip.stories.tsx index 09bffb8..6b35f5e 100644 --- a/packages/backend/src/pages/OfferTip.stories.tsx +++ b/packages/backend/src/pages/OfferTip.stories.tsx @@ -37,4 +37,5 @@ function createExample<Props>(Component: FunctionalComponent<Props>, props: Part } export const Example = createExample(TestedComponent, { + }); diff --git a/packages/backend/src/pages/OfferTip.tsx b/packages/backend/src/pages/OfferTip.tsx index fd14354..95e0c41 100644 --- a/packages/backend/src/pages/OfferTip.tsx +++ b/packages/backend/src/pages/OfferTip.tsx @@ -23,6 +23,10 @@ import { useEffect } from 'preact/hooks'; import { styled } from "@linaria/react" import "../css/pure-min.css" import "../css/style.css" +import { Footer } from '../components/Footer'; +import { ShowOrderDetails } from './ShowOrderDetails'; +import { render as renderToString } from 'preact-render-to-string'; +import { QR } from '../components/QR'; interface Props { taler_refund_uri?: string, @@ -60,20 +64,18 @@ export function OfferTip({ taler_refund_uri, tip_status_url, taler_tip_qrcode_sv }) return <Fragment> <section id="main" class="content"> - <h1>Collect Taler tip</h1> - <div class="taler-installed-hide"> + <h1 style={{ textAlign: 'center' }}>Collect Taler tip</h1> + <div style={{ textAlign: 'center' }} class="taler-installed-hide"> <p> Scan this QR code with your Taler mobile wallet: </p> <div class="qr"> - {taler_tip_qrcode_svg} + {taler_tip_qrcode_svg ? <QR text={taler_tip_qrcode_svg} /> : `{{taler_tip_qrcode_svg}}`} </div> <p> - <button onClick={() => { - window.location.href = tip_status_url || '#' - }}> + <a class="pure-button pure-button-active success" href='{{taler_refund_uri}}'> Or open your Taller wallet - </button> + </a> </p> <p> <a href="https://wallet.taler.net/">Don't have a Taler wallet yet? Install it!</a> @@ -85,25 +87,18 @@ export function OfferTip({ taler_refund_uri, tip_status_url, taler_tip_qrcode_sv </Fragment> } -function Footer() { - return <div class="talerbar"> - <p>You can learn more about GNU Taler on our <a href="https://taler.net/">website</a>.<br /> - Copyright © 2014—2021 Taler Systems SA</p> - </div> -} - export function Title(): VNode { return <title>Tip available</title> } -export function mountIntoBody(): void { +export function mount(): void { try { const params = new URL(window.location.href).searchParams render(<OfferTip - taler_refund_uri={params.get('taler_refund_uri') || undefined} - taler_tip_qrcode_svg={params.get('taler_tip_qrcode_svg') || undefined} - tip_status_url={params.get('tip_status_url') || undefined} + taler_refund_uri={params.get('taler_refund_uri') || undefined} + taler_tip_qrcode_svg={params.get('taler_tip_qrcode_svg') || undefined} + tip_status_url={params.get('tip_status_url') || undefined} />, document.body); } catch (e) { console.error("got error", e); @@ -111,3 +106,6 @@ export function mountIntoBody(): void { } } +export function buildTimeRendering(): string { + return renderToString(<ShowOrderDetails />) +} diff --git a/packages/backend/src/pages/RequestPayment.stories.tsx b/packages/backend/src/pages/RequestPayment.stories.tsx index 1aed570..6a757d2 100644 --- a/packages/backend/src/pages/RequestPayment.stories.tsx +++ b/packages/backend/src/pages/RequestPayment.stories.tsx @@ -37,4 +37,5 @@ function createExample<Props>(Component: FunctionalComponent<Props>, props: Part } export const Example = createExample(TestedComponent, { + taler_pay_qrcode_svg: 'this is an example' }); diff --git a/packages/backend/src/pages/RequestPayment.tsx b/packages/backend/src/pages/RequestPayment.tsx index d1fb8d4..7ebddcd 100644 --- a/packages/backend/src/pages/RequestPayment.tsx +++ b/packages/backend/src/pages/RequestPayment.tsx @@ -18,10 +18,16 @@ * * @author Sebastian Javier Marchano (sebasjm) */ -import { h, render, VNode } from 'preact'; +import { h, render, Fragment, VNode } from 'preact'; import { useEffect } from 'preact/hooks'; +import { Footer } from '../components/Footer'; +import { render as renderToString } from 'preact-render-to-string'; +import { QR } from '../components/QR'; -export function RequestPayment(): VNode { +interface Props { + taler_pay_qrcode_svg?: string, +} +export function RequestPayment({ taler_pay_qrcode_svg }: Props): VNode { useEffect(() => { const longpollDelayMs = 60000; const checkUrl = new URL("{{& order_status_url }}"); @@ -82,39 +88,40 @@ export function RequestPayment(): VNode { } setTimeout(check, 500); }) - return <section id="main" class="content"> - <h1>Pay with Taler</h1> - <div class="taler-installed-hide"> - <p> - Scan this QR code with your mobile wallet: - </p> - <div class="qr"> - {/* {{{taler_pay_qrcode_svg}}} */} - </div> - <p> - <button onClick={() => { - window.location.href = '{{taler_refund_uri}}' - }}> - Or open your Taller wallet - </button> - </p> - <p> - <a href="https://wallet.taler.net/">Don't have a Taler wallet yet? Install it!</a> - </p> - </div> - <hr /> - </section> - + return <Fragment> + <section id="main" class="content"> + <h1 style={{ textAlign: 'center' }}>Pay with Taler</h1> + <div style={{ textAlign: 'center' }} class="taler-installed-hide"> + <p> + Scan this QR code with your mobile wallet: + </p> + <div class="qr"> + {taler_pay_qrcode_svg ? <QR text={taler_pay_qrcode_svg} /> : `{{taler_pay_qrcode_svg}}`} + </div> + <p> + <a class="pure-button pure-button-active success" href={`{{ taler_refund_uri }}`}> + Or open your Taller wallet + </a> + </p> + <p> + <a href="https://wallet.taler.net/">Don't have a Taler wallet yet? Install it!</a> + </p> + </div> + <hr /> + </section> + <Footer /> + </Fragment> + } export function Title(): VNode { - return <title>Payment requested for {`{order_summary}`}</title> + return <title>Payment requested for {`{{ order_summary }}`}</title> } -export function mountIntoBody(): void { +export function mount(): void { try { const params = new URL(window.location.href).searchParams render(<RequestPayment - // taler_refund_uri={params.get('taler_refund_uri') || undefined} + taler_pay_qrcode_svg={params.get('taler_pay_qrcode_svg') || undefined} />, document.body); } catch (e) { console.error("got error", e); @@ -122,4 +129,7 @@ export function mountIntoBody(): void { } } +export function buildTimeRendering(): string { + return renderToString(<RequestPayment />) +} diff --git a/packages/backend/src/pages/ShowOrderDetails.stories.tsx b/packages/backend/src/pages/ShowOrderDetails.stories.tsx index 88fa393..7550ab4 100644 --- a/packages/backend/src/pages/ShowOrderDetails.stories.tsx +++ b/packages/backend/src/pages/ShowOrderDetails.stories.tsx @@ -37,4 +37,5 @@ function createExample<Props>(Component: FunctionalComponent<Props>, props: Part } export const Example = createExample(TestedComponent, { + taler_pay_qrcode_svg: 'this is an example' }); diff --git a/packages/backend/src/pages/ShowOrderDetails.tsx b/packages/backend/src/pages/ShowOrderDetails.tsx index 4aae556..591b7ea 100644 --- a/packages/backend/src/pages/ShowOrderDetails.tsx +++ b/packages/backend/src/pages/ShowOrderDetails.tsx @@ -20,6 +20,7 @@ */ import { Fragment, render, h, VNode } from 'preact'; import { useEffect } from 'preact/hooks'; +import { render as renderToString } from 'preact-render-to-string'; export function ShowOrderDetails(): VNode { useEffect(() => { @@ -87,13 +88,13 @@ export function ShowOrderDetails(): VNode { <h1>Order details</h1> <div> - This is the default status page for your order for <b>{`{ order_summary }`}</b>. + This is the default status page for your order for <b>{`{{ order_summary }}`}</b>. </div> <h2>Refund status</h2> <div> - The merchant has granted you refunds on the purchase of <b>{`{ refund_amount }`}</b>. + The merchant has granted you refunds on the purchase of <b>{`{{ refund_amount }}`}</b>. </div> <h2>Full contract details</h2> @@ -111,15 +112,19 @@ function Title(): VNode { return <title>Status of your order for {`{order_summary}`}</title> } -export function mountIntoBody(): void { +export function mount(): void { try { const params = new URL(window.location.href).searchParams render(<ShowOrderDetails - // taler_refund_uri={params.get('taler_refund_uri') || undefined} + // taler_refund_uri={params.get('taler_refund_uri') || undefined} />, document.body); + } catch (e) { console.error("got error", e); document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`; } } +export function buildTimeRendering(): string { + return renderToString(<ShowOrderDetails />) +} |