/* This file is part of GNU Taler (C) 2022-2024 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 */ import { AbsoluteTime, HttpStatusCode, TalerErrorCode, TranslatedString, assertUnreachable, stringifyWithdrawUri, } from "@gnu-taler/taler-util"; import { Attention, LocalNotificationBanner, notifyInfo, useLocalNotification, useTalerWalletIntegrationAPI, useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useEffect } from "preact/hooks"; import { QR } from "../../components/QR.js"; import { useBankState } from "../../hooks/bank-state.js"; import { usePreferences } from "../../hooks/preferences.js"; import { ShouldBeSameUser } from "../WithdrawalConfirmationQuestion.js"; import { State } from "./index.js"; export function InvalidPaytoView({ payto }: State.InvalidPayto) { return
Payto from server is not valid "{payto}"
; } export function InvalidWithdrawalView({ uri }: State.InvalidWithdrawal) { return
Withdrawal uri from server is not valid "{uri}"
; } export function InvalidReserveView({ reserve }: State.InvalidReserve) { return
Reserve from server is not valid "{reserve}"
; } export function NeedConfirmationView({ onAbort: doAbort, onConfirm: doConfirm, routeHere, account, id, onAuthorizationRequired, }: State.NeedConfirmation) { const { i18n } = useTranslationContext(); const [settings] = usePreferences(); const [notification, notify, errorHandler] = useLocalNotification(); const [, updateBankState] = useBankState(); async function onCancel() { errorHandler(async () => { if (!doAbort) return; const resp = await doAbort(); if (!resp) return; switch (resp.case) { case HttpStatusCode.Conflict: return notify({ type: "error", title: i18n.str`The reserve operation has been confirmed previously and can't be aborted`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.BadRequest: return notify({ type: "error", title: i18n.str`The operation id is invalid.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.NotFound: return notify({ type: "error", title: i18n.str`The operation was not found.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); default: assertUnreachable(resp); } }); } async function onConfirm() { errorHandler(async () => { if (!doConfirm) return; const resp = await doConfirm(); if (!resp) { if (!settings.showWithdrawalSuccess) { notifyInfo(i18n.str`Wire transfer completed!`); } return; } switch (resp.case) { case TalerErrorCode.BANK_CONFIRM_ABORT_CONFLICT: return notify({ type: "error", title: i18n.str`The withdrawal has been aborted previously and can't be confirmed`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case TalerErrorCode.BANK_CONFIRM_INCOMPLETE: return notify({ type: "error", title: i18n.str`The withdrawal operation can't be confirmed before a wallet accepted the transaction.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.BadRequest: return notify({ type: "error", title: i18n.str`The operation id is invalid.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.NotFound: return notify({ type: "error", title: i18n.str`The operation was not found.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case TalerErrorCode.BANK_UNALLOWED_DEBIT: return notify({ type: "error", title: i18n.str`Your balance is not enough.`, description: resp.detail.hint as TranslatedString, debug: resp.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.Accepted: { updateBankState("currentChallenge", { operation: "confirm-withdrawal", id: String(resp.body.challenge_id), sent: AbsoluteTime.never(), location: routeHere.url({ wopid: id }), request: id, }); return onAuthorizationRequired(); } default: assertUnreachable(resp); } }); } return (

Confirm the withdrawal operation

{ e.preventDefault(); }} >
); } export function FailedView({ error }: State.Failed) { const { i18n } = useTranslationContext(); switch (error.case) { case HttpStatusCode.Unauthorized: return (
{error.detail.hint}
); case HttpStatusCode.Conflict: return (
{error.detail.hint}
); case HttpStatusCode.NotFound: return (
{error.detail.hint}
); default: assertUnreachable(error); } } export function AbortedView() { return
aborted
; } export function ConfirmedView({ routeClose }: State.Confirmed) { const { i18n } = useTranslationContext(); const [settings, updateSettings] = usePreferences(); return (

The wire transfer to the Taler operator has been initiated. You will soon receive the requested amount in your Taler wallet.

Do not show this again
); } export function ReadyView({ uri, onAbort: doAbort }: State.Ready): VNode { const { i18n } = useTranslationContext(); const walletInegrationApi = useTalerWalletIntegrationAPI(); const [notification, notify, errorHandler] = useLocalNotification(); const talerWithdrawUri = stringifyWithdrawUri(uri); useEffect(() => { walletInegrationApi.publishTalerAction(uri); }, []); async function onAbort() { errorHandler(async () => { const hasError = await doAbort(); if (!hasError) return; switch (hasError.case) { case HttpStatusCode.Conflict: return notify({ type: "error", title: i18n.str`The reserve operation has been confirmed previously and can't be aborted`, description: hasError.detail.hint as TranslatedString, debug: hasError.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.BadRequest: return notify({ type: "error", title: i18n.str`The operation id is invalid.`, description: hasError.detail.hint as TranslatedString, debug: hasError.detail, when: AbsoluteTime.now(), }); case HttpStatusCode.NotFound: return notify({ type: "error", title: i18n.str`The operation was not found.`, description: hasError.detail.hint as TranslatedString, debug: hasError.detail, when: AbsoluteTime.now(), }); default: assertUnreachable(hasError); } }); } return (

On this device

If you are using a web browser on desktop you can also

On a mobile phone

Scan the QR code with your mobile device.

); }