summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2021-08-27 15:41:41 -0300
committerSebastian <sebasjm@gmail.com>2021-08-27 15:41:41 -0300
commitd8750f7a066cd047ff9f71c13f67a3f8b012bc62 (patch)
treeac49f01a9f4adc9e7bc56f7c19228516543b698b
parenteae88828683ec05d438dd4908d86b73e67e9707d (diff)
downloadmerchant-backoffice-d8750f7a066cd047ff9f71c13f67a3f8b012bc62.tar.gz
merchant-backoffice-d8750f7a066cd047ff9f71c13f67a3f8b012bc62.tar.bz2
merchant-backoffice-d8750f7a066cd047ff9f71c13f67a3f8b012bc62.zip
built time rendering
-rw-r--r--packages/backend/rollup.config.js10
-rw-r--r--packages/backend/src/components/Footer.tsx29
-rw-r--r--packages/backend/src/components/QR.tsx36
-rw-r--r--packages/backend/src/pages/DepletedTip.tsx24
-rw-r--r--packages/backend/src/pages/OfferRefund.tsx55
-rw-r--r--packages/backend/src/pages/OfferTip.stories.tsx1
-rw-r--r--packages/backend/src/pages/OfferTip.tsx34
-rw-r--r--packages/backend/src/pages/RequestPayment.stories.tsx1
-rw-r--r--packages/backend/src/pages/RequestPayment.tsx66
-rw-r--r--packages/backend/src/pages/ShowOrderDetails.stories.tsx1
-rw-r--r--packages/backend/src/pages/ShowOrderDetails.tsx13
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 &copy; 2014&mdash;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 &copy; 2014&mdash;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 />)
+}