diff options
Diffstat (limited to 'packages/merchant-backoffice-ui/src/paths/instance/templates/qr')
-rw-r--r-- | packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx | 65 | ||||
-rw-r--r-- | packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx | 2 |
2 files changed, 61 insertions, 6 deletions
diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx index 756909d15..66ac72ff5 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/QrPage.tsx @@ -31,8 +31,10 @@ import { } from "../../../../components/form/FormProvider.js"; import { Input } from "../../../../components/form/Input.js"; import { InputCurrency } from "../../../../components/form/InputCurrency.js"; +import { ConfirmModal } from "../../../../components/modal/index.js"; import { useBackendContext } from "../../../../context/backend.js"; import { useConfigContext } from "../../../../context/config.js"; +import { useInstanceContext } from "../../../../context/instance.js"; import { MerchantBackend } from "../../../../declaration.js"; type Entity = MerchantBackend.Template.UsingTemplateDetails; @@ -46,7 +48,9 @@ interface Props { export function QrPage({ template, id: templateId, onBack }: Props): VNode { const { i18n } = useTranslationContext(); const { url: backendUrl } = useBackendContext(); + const { id: instanceId } = useInstanceContext(); const config = useConfigContext(); + const [setupTOTP, setSetupTOTP] = useState(false); const [state, setState] = useState<Partial<Entity>>({ amount: template.template_contract.amount, @@ -82,8 +86,33 @@ export function QrPage({ template, id: templateId, onBack }: Props): VNode { const payTemplateUri = `${talerProto}//pay-template/${merchantURL.hostname}/${templateId}${paramsStr}`; + const issuer = encodeURIComponent( + `${new URL(backendUrl).hostname}/${instanceId}`, + ); + const oauthUri = !template.pos_algorithm + ? undefined + : template.pos_algorithm === 1 + ? `otpauth://totp/${issuer}:${templateId}?secret=${template.pos_key}&issuer=${issuer}&algorithm=SHA1&digits=8&period=30` + : template.pos_algorithm === 2 + ? `otpauth://totp/${issuer}:${templateId}?secret=${template.pos_key}&issuer=${issuer}&algorithm=SHA1&digits=8&period=30` + : undefined; return ( <div> + {oauthUri && ( + <ConfirmModal + description="Setup TOTP" + active={setupTOTP} + onConfirm={() => { + setSetupTOTP(false); + }} + > + <p>Scan this qr code with your TOTP device</p> + <QR text={oauthUri} /> + <pre style={{ textAlign: "center" }}> + <a href={oauthUri}>{oauthUri}</a> + </pre> + </ConfirmModal> + )} <section class="section is-main-section"> <div class="columns"> <div class="column" /> @@ -114,20 +143,48 @@ export function QrPage({ template, id: templateId, onBack }: Props): VNode { <i18n.Translate>Cancel</i18n.Translate> </button> )} - <button class="button is-info" onClick={onBack}> + <button + class="button is-info" + onClick={() => saveAsPDF(templateId)} + > <i18n.Translate>Print</i18n.Translate> </button> + {oauthUri && ( + <button + class="button is-info" + onClick={() => setSetupTOTP(true)} + > + <i18n.Translate>Setup TOTP</i18n.Translate> + </button> + )} </div> </div> <div class="column" /> </div> </section> - <section> - <pre> + <section id="printThis"> + <QR text={payTemplateUri} /> + <pre style={{ textAlign: "center" }}> <a href={payTemplateUri}>{payTemplateUri}</a> </pre> - <QR text={payTemplateUri} /> </section> </div> ); } + +function saveAsPDF(name: string): void { + const printWindow = window.open("", "", "height=400,width=800"); + if (!printWindow) return; + const divContents = document.getElementById("printThis"); + if (!divContents) return; + printWindow.document.write( + `<html><head><title>Order template for ${name}</title><style>`, + ); + printWindow.document.write("</style></head><body> </body></html>"); + printWindow.document.close(); + printWindow.document.body.appendChild(divContents.cloneNode(true)); + printWindow.addEventListener("load", () => { + printWindow.print(); + printWindow.close(); + }); +} diff --git a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx index 97d25b700..044cc7d79 100644 --- a/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx +++ b/packages/merchant-backoffice-ui/src/paths/instance/templates/qr/index.tsx @@ -51,10 +51,8 @@ export default function TemplateQrPage({ onNotFound, onUnauthorized, }: Props): VNode { - const { createOrderFromTemplate } = useTemplateAPI(); const result = useTemplateDetails(tid); const [notif, setNotif] = useState<Notification | undefined>(undefined); - const { i18n } = useTranslationContext(); if (result.clientError && result.isUnauthorized) return onUnauthorized(); if (result.clientError && result.isNotfound) return onNotFound(); |