138 lines
5.5 KiB
TypeScript
138 lines
5.5 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 {
|
|
HttpStatusCode,
|
|
stringifyWithdrawUri,
|
|
TranslatedString,
|
|
WithdrawUriResult,
|
|
} from "@gnu-taler/taler-util";
|
|
import {
|
|
notify,
|
|
notifyError,
|
|
RequestError,
|
|
useTranslationContext,
|
|
} from "@gnu-taler/web-util/browser";
|
|
import { Fragment, h, VNode } from "preact";
|
|
import { useEffect } from "preact/hooks";
|
|
import { QR } from "../components/QR.js";
|
|
import { useAccessAnonAPI } from "../hooks/access.js";
|
|
import { buildRequestErrorMessage } from "../utils.js";
|
|
|
|
export function QrCodeSection({
|
|
withdrawUri,
|
|
onAborted,
|
|
}: {
|
|
withdrawUri: WithdrawUriResult;
|
|
onAborted: () => void;
|
|
}): VNode {
|
|
const { i18n } = useTranslationContext();
|
|
useEffect(() => {
|
|
//Taler Wallet WebExtension is listening to headers response and tab updates.
|
|
//In the SPA there is no header response with the Taler URI so
|
|
//this hack manually triggers the tab update after the QR is in the DOM.
|
|
// WebExtension will be using
|
|
// https://developer.chrome.com/docs/extensions/reference/tabs/#event-onUpdated
|
|
document.title = `${document.title} ${withdrawUri.withdrawalOperationId}`;
|
|
}, []);
|
|
const talerWithdrawUri = stringifyWithdrawUri(withdrawUri);
|
|
|
|
const { abortWithdrawal } = useAccessAnonAPI();
|
|
|
|
async function doAbort() {
|
|
try {
|
|
await abortWithdrawal(withdrawUri.withdrawalOperationId);
|
|
onAborted();
|
|
} catch (error) {
|
|
if (error instanceof RequestError) {
|
|
notify(
|
|
buildRequestErrorMessage(i18n, error.cause, {
|
|
onClientError: (status) =>
|
|
status === HttpStatusCode.Conflict
|
|
? i18n.str`The reserve operation has been confirmed previously and can't be aborted`
|
|
: undefined,
|
|
}),
|
|
);
|
|
} else {
|
|
notifyError(
|
|
i18n.str`Operation failed, please report`,
|
|
(error instanceof Error
|
|
? error.message
|
|
: JSON.stringify(error)) as TranslatedString
|
|
)
|
|
}
|
|
}
|
|
}
|
|
|
|
return (
|
|
<Fragment>
|
|
<div class="bg-white shadow-xl sm:rounded-lg">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<h3 class="text-base font-semibold leading-6 text-gray-900">
|
|
<i18n.Translate>If you have a Taler wallet installed in this device</i18n.Translate>
|
|
</h3>
|
|
<div class="mt-4">
|
|
<a href={talerWithdrawUri}
|
|
// class="text-sm font-semibold leading-6 text-gray-900 btn "
|
|
class="inline-flex items-center disabled:opacity-50 disabled:cursor-default cursor-pointer 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"
|
|
>
|
|
<i18n.Translate>Click here to start</i18n.Translate>
|
|
</a>
|
|
</div>
|
|
<div class="mt-4 max-w-xl text-sm text-gray-500">
|
|
<p><i18n.Translate>
|
|
You will see the details of the operation in your wallet including the fees (if applies).
|
|
If you still one you can install it from <a class="font-semibold text-gray-500 hover:text-gray-400" href="https://taler.net/en/wallet.html">here</a>.
|
|
</i18n.Translate></p>
|
|
</div>
|
|
<div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 pt-2 mt-2 ">
|
|
<div />
|
|
<button type="button"
|
|
class="disabled:opacity-50 disabled:cursor-default cursor-pointer rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600"
|
|
onClick={doAbort}
|
|
>
|
|
Cancel withdrawal
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="bg-white shadow-xl sm:rounded-lg mt-8">
|
|
<div class="px-4 py-5 sm:p-6">
|
|
<h3 class="text-base font-semibold leading-6 text-gray-900">
|
|
<i18n.Translate>Or if you have the wallet in another device</i18n.Translate>
|
|
</h3>
|
|
<div class="mt-4 max-w-xl text-sm text-gray-500">
|
|
<i18n.Translate>Scan the QR below to start the withdrawal</i18n.Translate>
|
|
</div>
|
|
<div class="mt-2 max-w-md ml-auto mr-auto">
|
|
<QR text={talerWithdrawUri} />
|
|
</div>
|
|
</div>
|
|
<div class="flex items-center justify-center gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
|
|
<button type="button"
|
|
class="disabled:opacity-50 disabled:cursor-default cursor-pointer rounded-md bg-red-600 px-3 py-2 text-sm font-semibold text-white shadow-sm hover:bg-red-500 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-red-600"
|
|
onClick={doAbort}
|
|
>
|
|
Cancel withdrawal
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
</Fragment>
|
|
);
|
|
}
|