This commit is contained in:
Sebastian 2023-09-20 16:10:32 -03:00
parent e39d5c488e
commit 7d4c5a71aa
No known key found for this signature in database
GPG Key ID: 173909D1A5F66069
6 changed files with 225 additions and 150 deletions

View File

@ -85,18 +85,26 @@ export function getInitialBackendBaseURL(): string {
typeof localStorage !== "undefined" typeof localStorage !== "undefined"
? localStorage.getItem("bank-base-url") ? localStorage.getItem("bank-base-url")
: undefined; : undefined;
let result: string;
if (!overrideUrl) { if (!overrideUrl) {
//normal path //normal path
if (!bankUiSettings.backendBaseURL) { if (!bankUiSettings.backendBaseURL) {
console.error( console.error(
"ERROR: backendBaseURL was overridden by a setting file and missing. Setting value to 'window.origin'", "ERROR: backendBaseURL was overridden by a setting file and missing. Setting value to 'window.origin'",
); );
return canonicalizeBaseUrl(window.origin); result = window.origin
}
return canonicalizeBaseUrl(bankUiSettings.backendBaseURL);
} }
result = bankUiSettings.backendBaseURL;
} else {
// testing/development path // testing/development path
return canonicalizeBaseUrl(overrideUrl); result = overrideUrl
}
try {
return canonicalizeBaseUrl(result)
} catch (e) {
//fall back
return canonicalizeBaseUrl(window.origin)
}
} }
export const defaultState: BackendState = { export const defaultState: BackendState = {

View File

@ -15,8 +15,12 @@
*/ */
import { import {
AmountString,
Codec, Codec,
buildCodecForObject, buildCodecForObject,
codecForAmountString,
codecForBoolean,
codecForNumber,
codecForString, codecForString,
codecOptional, codecOptional,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
@ -24,15 +28,21 @@ import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
interface Settings { interface Settings {
currentWithdrawalOperationId: string | undefined; currentWithdrawalOperationId: string | undefined;
showWithdrawalSuccess: boolean;
maxWithdrawalAmount: number;
} }
export const codecForSettings = (): Codec<Settings> => export const codecForSettings = (): Codec<Settings> =>
buildCodecForObject<Settings>() buildCodecForObject<Settings>()
.property("currentWithdrawalOperationId", codecOptional(codecForString())) .property("currentWithdrawalOperationId", codecOptional(codecForString()))
.property("showWithdrawalSuccess", (codecForBoolean()))
.property("maxWithdrawalAmount", codecForNumber())
.build("Settings"); .build("Settings");
const defaultSettings: Settings = { const defaultSettings: Settings = {
currentWithdrawalOperationId: undefined, currentWithdrawalOperationId: undefined,
showWithdrawalSuccess: true,
maxWithdrawalAmount: 25
}; };
const DEMOBANK_SETTINGS_KEY = buildStorageKey( const DEMOBANK_SETTINGS_KEY = buildStorageKey(

View File

@ -183,8 +183,28 @@ export function BankFrame({
{/* <span class="ml-auto w-9 min-w-max whitespace-nowrap rounded-full bg-gray-50 px-2.5 py-0.5 text-center text-xs font-medium leading-5 text-gray-600 ring-1 ring-inset ring-gray-200" aria-hidden="true">5</span> */} {/* <span class="ml-auto w-9 min-w-max whitespace-nowrap rounded-full bg-gray-50 px-2.5 py-0.5 text-center text-xs font-medium leading-5 text-gray-600 ring-1 ring-inset ring-gray-200" aria-hidden="true">5</span> */}
</a> </a>
</li> </li>
<li>
<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>Show withdrawal confirmation</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={() => {
console.log(settings.showWithdrawalSuccess)
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>
</li>
</ul> </ul>
</li> </li>
<li class="sm:hidden"> <li class="sm:hidden">
<div class="text-xs font-semibold leading-6 text-gray-400"> <div class="text-xs font-semibold leading-6 text-gray-400">
<i18n.Translate>Sites</i18n.Translate> <i18n.Translate>Sites</i18n.Translate>

View File

@ -95,8 +95,9 @@ export function WithdrawalOperationPage({
}): VNode { }): VNode {
//FIXME: libeufin sandbox should return show to create the integration api endpoint //FIXME: libeufin sandbox should return show to create the integration api endpoint
//or return withdrawal uri from response //or return withdrawal uri from response
const baseUrl = getInitialBackendBaseURL()
const uri = stringifyWithdrawUri({ const uri = stringifyWithdrawUri({
bankIntegrationApiBaseUrl: `${getInitialBackendBaseURL()}/integration-api`, bankIntegrationApiBaseUrl: `${baseUrl}/integration-api`,
withdrawalOperationId: operationId, withdrawalOperationId: operationId,
}); });
const parsedUri = parseWithdrawUri(uri); const parsedUri = parseWithdrawUri(uri);
@ -164,7 +165,7 @@ export function handleNotOkResult(
} }
case ErrorType.UNREADABLE: { case ErrorType.UNREADABLE: {
notify({ notify({
type:"error", type: "error",
title: i18n.str`Unexpected error.`, title: i18n.str`Unexpected error.`,
description: i18n.str`Response from ${result.info?.url} is unreadable, http status: ${result.status}`, description: i18n.str`Response from ${result.info?.url} is unreadable, http status: ${result.status}`,
debug: JSON.stringify(result), debug: JSON.stringify(result),
@ -173,7 +174,7 @@ export function handleNotOkResult(
} }
case ErrorType.UNEXPECTED: { case ErrorType.UNEXPECTED: {
notify({ notify({
type:"error", type: "error",
title: i18n.str`Unexpected error.`, title: i18n.str`Unexpected error.`,
description: i18n.str`Diagnostic from ${result.info?.url} is "${result.message}"`, description: i18n.str`Diagnostic from ${result.info?.url} is "${result.message}"`,
debug: JSON.stringify(result), debug: JSON.stringify(result),

View File

@ -20,24 +20,23 @@ import {
HttpStatusCode, HttpStatusCode,
Logger, Logger,
PaytoUri, PaytoUri,
PaytoUriGeneric,
PaytoUriIBAN, PaytoUriIBAN,
PaytoUriTalerBank, PaytoUriTalerBank,
TranslatedString, TranslatedString,
WithdrawUriResult, WithdrawUriResult
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { import {
RequestError, RequestError,
notify, notify,
notifyError, notifyError,
notifyInfo,
useTranslationContext, useTranslationContext,
} from "@gnu-taler/web-util/browser"; } from "@gnu-taler/web-util/browser";
import { Fragment, VNode, h } from "preact"; import { Fragment, VNode, h } from "preact";
import { useMemo, useState } from "preact/hooks"; import { useMemo, useState } from "preact/hooks";
import { ShowInputErrorLabel } from "../components/ShowInputErrorLabel.js";
import { useAccessAnonAPI } from "../hooks/access.js"; import { useAccessAnonAPI } from "../hooks/access.js";
import { buildRequestErrorMessage, undefinedIfEmpty } from "../utils.js"; import { buildRequestErrorMessage, undefinedIfEmpty } from "../utils.js";
import { ShowInputErrorLabel } from "../components/ShowInputErrorLabel.js";
import { Amount } from "./PaytoWireTransferForm.js";
const logger = new Logger("WithdrawalConfirmationQuestion"); const logger = new Logger("WithdrawalConfirmationQuestion");
@ -71,6 +70,7 @@ export function WithdrawalConfirmationQuestion({
const { confirmWithdrawal, abortWithdrawal } = useAccessAnonAPI(); const { confirmWithdrawal, abortWithdrawal } = useAccessAnonAPI();
const [captchaAnswer, setCaptchaAnswer] = useState<string | undefined>(); const [captchaAnswer, setCaptchaAnswer] = useState<string | undefined>();
const answer = parseInt(captchaAnswer ?? "", 10); const answer = parseInt(captchaAnswer ?? "", 10);
const [busy, setBusy] = useState<Record<string, undefined>>()
const errors = undefinedIfEmpty({ const errors = undefinedIfEmpty({
answer: !captchaAnswer answer: !captchaAnswer
? i18n.str`Answer the question before continue` ? i18n.str`Answer the question before continue`
@ -79,13 +79,15 @@ export function WithdrawalConfirmationQuestion({
: answer !== captchaNumbers.a + captchaNumbers.b : answer !== captchaNumbers.a + captchaNumbers.b
? i18n.str`The answer "${answer}" to "${captchaNumbers.a} + ${captchaNumbers.b}" is wrong.` ? i18n.str`The answer "${answer}" to "${captchaNumbers.a} + ${captchaNumbers.b}" is wrong.`
: undefined, : undefined,
}); }) ?? busy;
async function doTransfer() { async function doTransfer() {
try { try {
setBusy({})
await confirmWithdrawal( await confirmWithdrawal(
withdrawUri.withdrawalOperationId, withdrawUri.withdrawalOperationId,
); );
notifyInfo(i18n.str`Wire transfer completed!`)
} catch (error) { } catch (error) {
if (error instanceof RequestError) { if (error instanceof RequestError) {
notify( notify(
@ -107,10 +109,12 @@ export function WithdrawalConfirmationQuestion({
) )
} }
} }
setBusy(undefined)
} }
async function doCancel() { async function doCancel() {
try { try {
setBusy({})
await abortWithdrawal(withdrawUri.withdrawalOperationId); await abortWithdrawal(withdrawUri.withdrawalOperationId);
onAborted(); onAborted();
} catch (error) { } catch (error) {
@ -132,6 +136,7 @@ export function WithdrawalConfirmationQuestion({
) )
} }
} }
setBusy(undefined)
} }
return ( return (
@ -142,68 +147,6 @@ export function WithdrawalConfirmationQuestion({
<i18n.Translate>Confirm the withdrawal operation</i18n.Translate> <i18n.Translate>Confirm the withdrawal operation</i18n.Translate>
</h3> </h3>
<div class="mt-2 max-w-xl text-sm text-gray-500"> <div class="mt-2 max-w-xl text-sm text-gray-500">
<div class="px-4 mt-4 ">
<div class="w-full">
<div class="px-4 sm:px-0">
<p><i18n.Translate>Wire transfer details</i18n.Translate></p>
</div>
<div class="mt-6 border-t border-gray-100">
<dl class="divide-y divide-gray-100">
{((): VNode => {
switch (details.account.targetType) {
case "iban": {
const p = details.account as PaytoUriIBAN
const name = p.params["receiver-name"]
return <Fragment>
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange account</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.iban}</dd>
</div>
{name &&
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange name</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.params["receiver-name"]}</dd>
</div>
}
</Fragment>
}
case "x-taler-bank": {
const p = details.account as PaytoUriTalerBank
const name = p.params["receiver-name"]
return <Fragment>
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange account</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.account}</dd>
</div>
{name &&
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange name</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.params["receiver-name"]}</dd>
</div>
}
</Fragment>
}
default:
return <div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange account</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{details.account.targetPath}</dd>
</div>
}
})()}
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Withdrawal identification</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{details.reserve}</dd>
</div>
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Amount</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{Amounts.stringifyValue(details.amount)}</dd>
</div>
</dl>
</div>
</div>
</div>
<div class="px-4 mt-4 grid grid-cols-1 gap-y-6 sm:grid-cols-3 sm:gap-x-3"> <div class="px-4 mt-4 grid grid-cols-1 gap-y-6 sm:grid-cols-3 sm:gap-x-3">
<label class={"relative flex cursor-pointer rounded-lg border bg-white p-4 shadow-sm focus:outline-noneborder-indigo-600 ring-2 ring-indigo-600"}> <label class={"relative flex cursor-pointer rounded-lg border bg-white p-4 shadow-sm focus:outline-noneborder-indigo-600 ring-2 ring-indigo-600"}>
@ -285,36 +228,32 @@ export function WithdrawalConfirmationQuestion({
aria-describedby="answer" aria-describedby="answer"
autoFocus autoFocus
class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6" class="block w-full rounded-md border-0 py-1.5 text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 placeholder:text-gray-400 focus:ring-2 focus:ring-inset focus:ring-indigo-600 sm:text-sm sm:leading-6"
// value={username ?? ""} value={captchaAnswer ?? ""}
required required
name="answer" name="answer"
id="answer" id="answer"
autocomplete="off" autocomplete="off"
// value={value ?? ""} onChange={(e): void => {
// disabled={!onChange} setCaptchaAnswer(e.currentTarget.value)
// onInput={(e): void => { }}
// if (onChange) {
// onChange(e.currentTarget.value);
// }
// }}
/> />
</div> </div>
<ShowInputErrorLabel message={errors?.answer} isDirty={false} /> <ShowInputErrorLabel message={errors?.answer} isDirty={captchaAnswer !== undefined} />
</div> </div>
</div> </div>
<div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8"> <div class="flex items-center justify-between gap-x-6 border-t border-gray-900/10 px-4 py-4 sm:px-8">
<button type="button" class="text-sm font-semibold leading-6 text-gray-900" <button type="button" class="text-sm font-semibold leading-6 text-gray-900"
// onClick={onCancel} onClick={doCancel}
> >
<i18n.Translate>Cancel</i18n.Translate></button> <i18n.Translate>Cancel</i18n.Translate></button>
<button type="submit" <button type="submit"
class="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" class="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"
// disabled={isRawPayto ? !!errorsPayto : !!errorsWire} disabled={!!errors}
// onClick={(e) => { onClick={(e) => {
// e.preventDefault() e.preventDefault()
// doStart() doTransfer()
// }} }}
> >
<i18n.Translate>Transfer</i18n.Translate> <i18n.Translate>Transfer</i18n.Translate>
</button> </button>
@ -323,6 +262,68 @@ export function WithdrawalConfirmationQuestion({
</form> </form>
</div> </div>
</div> </div>
<div class="px-4 mt-4 ">
<div class="w-full">
<div class="px-4 sm:px-0">
<p><i18n.Translate>Wire transfer details</i18n.Translate></p>
</div>
<div class="mt-6 border-t border-gray-100">
<dl class="divide-y divide-gray-100">
{((): VNode => {
switch (details.account.targetType) {
case "iban": {
const p = details.account as PaytoUriIBAN
const name = p.params["receiver-name"]
return <Fragment>
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange account</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.iban}</dd>
</div>
{name &&
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange name</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.params["receiver-name"]}</dd>
</div>
}
</Fragment>
}
case "x-taler-bank": {
const p = details.account as PaytoUriTalerBank
const name = p.params["receiver-name"]
return <Fragment>
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange account</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.account}</dd>
</div>
{name &&
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange name</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{p.params["receiver-name"]}</dd>
</div>
}
</Fragment>
}
default:
return <div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Exchange account</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{details.account.targetPath}</dd>
</div>
}
})()}
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Withdrawal identification</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{details.reserve}</dd>
</div>
<div class="px-4 py-2 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-0">
<dt class="text-sm font-medium leading-6 text-gray-900">Amount</dt>
<dd class="mt-1 text-sm leading-6 text-gray-700 sm:col-span-2 sm:mt-0">{Amounts.stringifyValue(details.amount)}</dd>
</div>
</dl>
</div>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -62,9 +62,10 @@ export function WithdrawalQRCode({
result.type === ErrorType.CLIENT && result.type === ErrorType.CLIENT &&
result.status === HttpStatusCode.NotFound result.status === HttpStatusCode.NotFound
) { ) {
clearCurrentWithdrawal()
return <div>operation not found</div>; return <div>operation not found</div>;
} }
onLoadNotOk(); // onLoadNotOk();
return handleNotOkResult(i18n)(result); return handleNotOkResult(i18n)(result);
} }
const { data } = result; const { data } = result;
@ -85,7 +86,7 @@ export function WithdrawalQRCode({
</i18n.Translate> </i18n.Translate>
</p> </p>
<a class="pure-button pure-button-primary" <a class="pure-button pure-button-primary"
style={{float:"right"}} style={{ float: "right" }}
onClick={async (e) => { onClick={async (e) => {
e.preventDefault(); e.preventDefault();
clearCurrentWithdrawal() clearCurrentWithdrawal()
@ -99,35 +100,82 @@ export function WithdrawalQRCode({
} }
if (data.confirmation_done) { if (data.confirmation_done) {
return <section id="main" class="content"> if (!settings.showWithdrawalSuccess) {
<h1 class="nav">{i18n.str`Operation completed`}</h1> clearCurrentWithdrawal()
onContinue()
<section id="assets" style={{maxWidth: 400, marginLeft: "auto", marginRight:"auto"}}> }
<p> 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> <i18n.Translate>
The wire transfer to the GNU Taler Exchange bank's account is completed, now the 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. exchange will send the requested amount into your GNU Taler wallet.
</i18n.Translate> </i18n.Translate>
</p> </p>
<p> </div>
<div class="mt-2">
<p >
<i18n.Translate> <i18n.Translate>
You can close this page now or continue to the account page. You can close this page now or continue to the account page.
</i18n.Translate> </i18n.Translate>
</p> </p>
<div style={{textAlign:"center"}}> </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"
<a class="pure-button pure-button-primary" 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) => { onClick={async (e) => {
e.preventDefault(); e.preventDefault();
clearCurrentWithdrawal() clearCurrentWithdrawal()
onContinue() onContinue()
}}> }}>
{i18n.str`Continue`} <i18n.Translate>Continue</i18n.Translate>
</a> </button>
</div> </div>
</section> </div>
</section>
} }
if (!data.selection_done) {
return (
<QrCodeSection
withdrawUri={withdrawUri}
onAborted={() => {
notifyInfo(i18n.str`Operation canceled`);
clearCurrentWithdrawal()
onContinue()
}}
/>
);
}
if (!data.selected_reserve_pub) { if (!data.selected_reserve_pub) {
return <div> return <div>
the exchange is selcted but no reserve pub the exchange is selcted but no reserve pub
@ -142,19 +190,6 @@ export function WithdrawalQRCode({
</div> </div>
} }
if (!data.selection_done) {
return (
<QrCodeSection
withdrawUri={withdrawUri}
onAborted={() => {
notifyInfo(i18n.str`Operation canceled`);
clearCurrentWithdrawal()
onContinue()
}}
/>
);
}
return ( return (
<WithdrawalConfirmationQuestion <WithdrawalConfirmationQuestion
withdrawUri={withdrawUri} withdrawUri={withdrawUri}