204 lines
7.2 KiB
TypeScript
204 lines
7.2 KiB
TypeScript
/*
|
|
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 {
|
|
Amounts,
|
|
HttpStatusCode,
|
|
Logger,
|
|
WithdrawUriResult,
|
|
parsePaytoUri,
|
|
} from "@gnu-taler/taler-util";
|
|
import { ErrorType, notifyInfo, useTranslationContext } from "@gnu-taler/web-util/browser";
|
|
import { Fragment, VNode, h } from "preact";
|
|
import { Loading } from "../components/Loading.js";
|
|
import { useWithdrawalDetails } from "../hooks/access.js";
|
|
import { useSettings } from "../hooks/settings.js";
|
|
import { handleNotOkResult } from "./HomePage.js";
|
|
import { QrCodeSection } from "./QrCodeSection.js";
|
|
import { WithdrawalConfirmationQuestion } from "./WithdrawalConfirmationQuestion.js";
|
|
|
|
const logger = new Logger("WithdrawalQRCode");
|
|
|
|
interface Props {
|
|
withdrawUri: WithdrawUriResult;
|
|
onContinue: () => void;
|
|
onLoadNotOk: () => void;
|
|
}
|
|
/**
|
|
* Offer the QR code (and a clickable taler://-link) to
|
|
* permit the passing of exchange and reserve details to
|
|
* the bank. Poll the backend until such operation is done.
|
|
*/
|
|
export function WithdrawalQRCode({
|
|
withdrawUri,
|
|
onContinue,
|
|
onLoadNotOk,
|
|
}: Props): VNode {
|
|
const [settings, updateSettings] = useSettings();
|
|
function clearCurrentWithdrawal(): void {
|
|
updateSettings("currentWithdrawalOperationId", undefined);
|
|
onContinue();
|
|
}
|
|
const { i18n } = useTranslationContext();
|
|
const result = useWithdrawalDetails(withdrawUri.withdrawalOperationId);
|
|
if (!result.ok) {
|
|
if (result.loading) {
|
|
return <Loading />;
|
|
}
|
|
if (
|
|
result.type === ErrorType.CLIENT &&
|
|
result.status === HttpStatusCode.NotFound
|
|
) {
|
|
clearCurrentWithdrawal()
|
|
return <div>operation not found</div>;
|
|
}
|
|
// onLoadNotOk();
|
|
return handleNotOkResult(i18n)(result);
|
|
}
|
|
const { data } = result;
|
|
|
|
if (data.aborted) {
|
|
return <section id="main" class="content">
|
|
<h1 class="nav">{i18n.str`Operation aborted`}</h1>
|
|
<section>
|
|
<p>
|
|
<i18n.Translate>
|
|
The wire transfer to the GNU Taler Exchange bank's account was aborted, your balance
|
|
was not affected.
|
|
</i18n.Translate>
|
|
</p>
|
|
<p>
|
|
<i18n.Translate>
|
|
You can close this page now or continue to the account page.
|
|
</i18n.Translate>
|
|
</p>
|
|
<a class="pure-button pure-button-primary"
|
|
style={{ float: "right" }}
|
|
onClick={async (e) => {
|
|
e.preventDefault();
|
|
clearCurrentWithdrawal()
|
|
onContinue()
|
|
}}>
|
|
{i18n.str`Continue`}
|
|
</a>
|
|
|
|
</section>
|
|
</section>
|
|
}
|
|
|
|
if (data.confirmation_done) {
|
|
return <div class="relative ml-auto mr-auto transform overflow-hidden rounded-lg bg-white px-4 pb-4 pt-5 text-left shadow-xl transition-all sm:my-8 sm:w-full sm:max-w-sm sm:p-6">
|
|
<div>
|
|
<div class="mx-auto flex h-12 w-12 items-center justify-center rounded-full bg-green-100">
|
|
<svg class="h-6 w-6 text-green-600" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" aria-hidden="true">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M4.5 12.75l6 6 9-13.5" />
|
|
</svg>
|
|
</div>
|
|
<div class="mt-3 text-center sm:mt-5">
|
|
<h3 class="text-base font-semibold leading-6 text-gray-900" id="modal-title">
|
|
<i18n.Translate>Withdrawal OK</i18n.Translate>
|
|
</h3>
|
|
<div class="mt-2">
|
|
<p class="text-sm text-gray-500">
|
|
<i18n.Translate>
|
|
The wire transfer to the Taler exchange bank's account is completed, now the
|
|
exchange will send the requested amount into your GNU Taler wallet.
|
|
</i18n.Translate>
|
|
</p>
|
|
</div>
|
|
<div class="mt-2">
|
|
<p >
|
|
<i18n.Translate>
|
|
You can close this page now or continue to the account page.
|
|
</i18n.Translate>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="mt-4">
|
|
<div class="flex items-center justify-between">
|
|
<span class="flex flex-grow flex-col">
|
|
<span class="text-sm text-black font-medium leading-6 " id="availability-label">
|
|
<i18n.Translate>Do not show this again</i18n.Translate>
|
|
</span>
|
|
</span>
|
|
<button type="button" data-enabled={!settings.showWithdrawalSuccess} class="bg-indigo-600 data-[enabled=false]:bg-gray-200 relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-indigo-600 focus:ring-offset-2" role="switch" aria-checked="false" aria-labelledby="availability-label" aria-describedby="availability-description"
|
|
|
|
onClick={() => {
|
|
updateSettings("showWithdrawalSuccess", !settings.showWithdrawalSuccess);
|
|
}}>
|
|
<span aria-hidden="true" data-enabled={!settings.showWithdrawalSuccess} class="translate-x-5 data-[enabled=false]:translate-x-0 pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"></span>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="mt-5 sm:mt-6">
|
|
<button type="button"
|
|
class="inline-flex w-full justify-center rounded-md bg-indigo-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-indigo-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
|
|
onClick={async (e) => {
|
|
e.preventDefault();
|
|
clearCurrentWithdrawal()
|
|
onContinue()
|
|
}}>
|
|
<i18n.Translate>Continue</i18n.Translate>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
}
|
|
if (!data.selection_done) {
|
|
return (
|
|
<QrCodeSection
|
|
withdrawUri={withdrawUri}
|
|
onAborted={() => {
|
|
notifyInfo(i18n.str`Operation canceled`);
|
|
clearCurrentWithdrawal()
|
|
onContinue()
|
|
}}
|
|
/>
|
|
);
|
|
}
|
|
|
|
if (!data.selected_reserve_pub) {
|
|
return <div>
|
|
the exchange is selcted but no reserve pub
|
|
</div>
|
|
}
|
|
|
|
const account = !data.selected_exchange_account ? undefined : parsePaytoUri(data.selected_exchange_account)
|
|
|
|
if (!account) {
|
|
return <div>
|
|
the exchange is selcted but no account
|
|
</div>
|
|
}
|
|
|
|
return (
|
|
<WithdrawalConfirmationQuestion
|
|
withdrawUri={withdrawUri}
|
|
details={{
|
|
account,
|
|
reserve: data.selected_reserve_pub,
|
|
amount: Amounts.parseOrThrow("usd:10.00")
|
|
}}
|
|
onAborted={() => {
|
|
notifyInfo(i18n.str`Operation canceled`);
|
|
clearCurrentWithdrawal()
|
|
onContinue()
|
|
}}
|
|
/>
|
|
);
|
|
} |