diff options
author | Sebastian <sebasjm@gmail.com> | 2023-09-20 16:10:32 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2023-09-25 14:50:40 -0300 |
commit | 7d4c5a71aaa6c4e781af124fe821d8be4ed101ed (patch) | |
tree | 760314547bb21ed9ee3501dd8af657bf2fc9a577 | |
parent | e39d5c488e2e425bd7febf694caadc17d5126401 (diff) |
more ui
-rw-r--r-- | packages/demobank-ui/src/hooks/backend.ts | 16 | ||||
-rw-r--r-- | packages/demobank-ui/src/hooks/settings.ts | 10 | ||||
-rw-r--r-- | packages/demobank-ui/src/pages/BankFrame.tsx | 50 | ||||
-rw-r--r-- | packages/demobank-ui/src/pages/HomePage.tsx | 9 | ||||
-rw-r--r-- | packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx | 165 | ||||
-rw-r--r-- | packages/demobank-ui/src/pages/WithdrawalQRCode.tsx | 117 |
6 files changed, 221 insertions, 146 deletions
diff --git a/packages/demobank-ui/src/hooks/backend.ts b/packages/demobank-ui/src/hooks/backend.ts index 4b60d1b6c..c05ab33e9 100644 --- a/packages/demobank-ui/src/hooks/backend.ts +++ b/packages/demobank-ui/src/hooks/backend.ts @@ -85,18 +85,26 @@ export function getInitialBackendBaseURL(): string { typeof localStorage !== "undefined" ? localStorage.getItem("bank-base-url") : undefined; + let result: string; if (!overrideUrl) { //normal path if (!bankUiSettings.backendBaseURL) { console.error( "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 + result = overrideUrl + } + try { + return canonicalizeBaseUrl(result) + } catch (e) { + //fall back + return canonicalizeBaseUrl(window.origin) } - // testing/development path - return canonicalizeBaseUrl(overrideUrl); } export const defaultState: BackendState = { diff --git a/packages/demobank-ui/src/hooks/settings.ts b/packages/demobank-ui/src/hooks/settings.ts index 46b31bf2a..43e803726 100644 --- a/packages/demobank-ui/src/hooks/settings.ts +++ b/packages/demobank-ui/src/hooks/settings.ts @@ -15,8 +15,12 @@ */ import { + AmountString, Codec, buildCodecForObject, + codecForAmountString, + codecForBoolean, + codecForNumber, codecForString, codecOptional, } from "@gnu-taler/taler-util"; @@ -24,15 +28,21 @@ import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser"; interface Settings { currentWithdrawalOperationId: string | undefined; + showWithdrawalSuccess: boolean; + maxWithdrawalAmount: number; } export const codecForSettings = (): Codec<Settings> => buildCodecForObject<Settings>() .property("currentWithdrawalOperationId", codecOptional(codecForString())) + .property("showWithdrawalSuccess", (codecForBoolean())) + .property("maxWithdrawalAmount", codecForNumber()) .build("Settings"); const defaultSettings: Settings = { currentWithdrawalOperationId: undefined, + showWithdrawalSuccess: true, + maxWithdrawalAmount: 25 }; const DEMOBANK_SETTINGS_KEY = buildStorageKey( diff --git a/packages/demobank-ui/src/pages/BankFrame.tsx b/packages/demobank-ui/src/pages/BankFrame.tsx index d234845a0..e682085ae 100644 --- a/packages/demobank-ui/src/pages/BankFrame.tsx +++ b/packages/demobank-ui/src/pages/BankFrame.tsx @@ -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> */} </a> </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> </li> + + + <li class="sm:hidden"> <div class="text-xs font-semibold leading-6 text-gray-400"> <i18n.Translate>Sites</i18n.Translate> @@ -343,14 +363,14 @@ function StatusBanner(): VNode { switch (n.message.type) { case "error": return <div class="rounded-md bg-red-50 p-4"> - <div class="flex"> - <div class="flex-shrink-0"> - <svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> - <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" /> - </svg> - </div> - <div class="ml-3 flex-1 md:flex md:justify-between"> - <p class="text-sm font-medium text-red-800">{n.message.title}</p> + <div class="flex"> + <div class="flex-shrink-0"> + <svg class="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"> + <path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.28 7.22a.75.75 0 00-1.06 1.06L8.94 10l-1.72 1.72a.75.75 0 101.06 1.06L10 11.06l1.72 1.72a.75.75 0 101.06-1.06L11.06 10l1.72-1.72a.75.75 0 00-1.06-1.06L10 8.94 8.28 7.22z" clip-rule="evenodd" /> + </svg> + </div> + <div class="ml-3 flex-1 md:flex md:justify-between"> + <p class="text-sm font-medium text-red-800">{n.message.title}</p> <p class="mt-3 text-sm md:ml-6 md:mt-0"> <button type="button" class="inline-flex font-semibold items-center rounded bg-white px-2 py-1 text-xs text-gray-900 shadow-sm ring-1 ring-inset ring-gray-300 hover:bg-gray-50" onClick={(e) => { @@ -363,15 +383,15 @@ function StatusBanner(): VNode { <path d="M6.28 5.22a.75.75 0 00-1.06 1.06L8.94 10l-3.72 3.72a.75.75 0 101.06 1.06L10 11.06l3.72 3.72a.75.75 0 101.06-1.06L11.06 10l3.72-3.72a.75.75 0 00-1.06-1.06L10 8.94 6.28 5.22z" /> </svg> </button> - </p> + </p> + </div> </div> + {n.message.description && + <div class="mt-2 text-sm text-red-700"> + {n.message.description} + </div> + } </div> - {n.message.description && - <div class="mt-2 text-sm text-red-700"> - {n.message.description} - </div> - } - </div> case "info": return <div class="rounded-md bg-green-50 border-4 border-green-600 p-6"> <div class="flex"> diff --git a/packages/demobank-ui/src/pages/HomePage.tsx b/packages/demobank-ui/src/pages/HomePage.tsx index e00daf278..e82e46eb2 100644 --- a/packages/demobank-ui/src/pages/HomePage.tsx +++ b/packages/demobank-ui/src/pages/HomePage.tsx @@ -95,8 +95,9 @@ export function WithdrawalOperationPage({ }): VNode { //FIXME: libeufin sandbox should return show to create the integration api endpoint //or return withdrawal uri from response + const baseUrl = getInitialBackendBaseURL() const uri = stringifyWithdrawUri({ - bankIntegrationApiBaseUrl: `${getInitialBackendBaseURL()}/integration-api`, + bankIntegrationApiBaseUrl: `${baseUrl}/integration-api`, withdrawalOperationId: operationId, }); const parsedUri = parseWithdrawUri(uri); @@ -155,7 +156,7 @@ export function handleNotOkResult( } case ErrorType.SERVER: { notify({ - type: "error", + type: "error", title: i18n.str`Server returned with error`, description: result.payload.error.description as TranslatedString, debug: JSON.stringify(result.payload), @@ -164,7 +165,7 @@ export function handleNotOkResult( } case ErrorType.UNREADABLE: { notify({ - type:"error", + type: "error", title: i18n.str`Unexpected error.`, description: i18n.str`Response from ${result.info?.url} is unreadable, http status: ${result.status}`, debug: JSON.stringify(result), @@ -173,7 +174,7 @@ export function handleNotOkResult( } case ErrorType.UNEXPECTED: { notify({ - type:"error", + type: "error", title: i18n.str`Unexpected error.`, description: i18n.str`Diagnostic from ${result.info?.url} is "${result.message}"`, debug: JSON.stringify(result), diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx index 28f00169d..80e7a78ac 100644 --- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx +++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx @@ -20,24 +20,23 @@ import { HttpStatusCode, Logger, PaytoUri, - PaytoUriGeneric, PaytoUriIBAN, PaytoUriTalerBank, TranslatedString, - WithdrawUriResult, + WithdrawUriResult } from "@gnu-taler/taler-util"; import { RequestError, notify, notifyError, + notifyInfo, useTranslationContext, } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { useMemo, useState } from "preact/hooks"; +import { ShowInputErrorLabel } from "../components/ShowInputErrorLabel.js"; import { useAccessAnonAPI } from "../hooks/access.js"; import { buildRequestErrorMessage, undefinedIfEmpty } from "../utils.js"; -import { ShowInputErrorLabel } from "../components/ShowInputErrorLabel.js"; -import { Amount } from "./PaytoWireTransferForm.js"; const logger = new Logger("WithdrawalConfirmationQuestion"); @@ -71,6 +70,7 @@ export function WithdrawalConfirmationQuestion({ const { confirmWithdrawal, abortWithdrawal } = useAccessAnonAPI(); const [captchaAnswer, setCaptchaAnswer] = useState<string | undefined>(); const answer = parseInt(captchaAnswer ?? "", 10); + const [busy, setBusy] = useState<Record<string, undefined>>() const errors = undefinedIfEmpty({ answer: !captchaAnswer ? i18n.str`Answer the question before continue` @@ -79,13 +79,15 @@ export function WithdrawalConfirmationQuestion({ : answer !== captchaNumbers.a + captchaNumbers.b ? i18n.str`The answer "${answer}" to "${captchaNumbers.a} + ${captchaNumbers.b}" is wrong.` : undefined, - }); + }) ?? busy; async function doTransfer() { try { + setBusy({}) await confirmWithdrawal( withdrawUri.withdrawalOperationId, ); + notifyInfo(i18n.str`Wire transfer completed!`) } catch (error) { if (error instanceof RequestError) { notify( @@ -107,10 +109,12 @@ export function WithdrawalConfirmationQuestion({ ) } } + setBusy(undefined) } async function doCancel() { try { + setBusy({}) await abortWithdrawal(withdrawUri.withdrawalOperationId); onAborted(); } catch (error) { @@ -132,6 +136,7 @@ export function WithdrawalConfirmationQuestion({ ) } } + setBusy(undefined) } return ( @@ -142,68 +147,6 @@ export function WithdrawalConfirmationQuestion({ <i18n.Translate>Confirm the withdrawal operation</i18n.Translate> </h3> <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"> <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" 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" - // value={username ?? ""} + value={captchaAnswer ?? ""} required name="answer" id="answer" autocomplete="off" - // value={value ?? ""} - // disabled={!onChange} - // onInput={(e): void => { - // if (onChange) { - // onChange(e.currentTarget.value); - // } - // }} + onChange={(e): void => { + setCaptchaAnswer(e.currentTarget.value) + }} /> </div> - <ShowInputErrorLabel message={errors?.answer} isDirty={false} /> + <ShowInputErrorLabel message={errors?.answer} isDirty={captchaAnswer !== undefined} /> </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"> <button type="button" class="text-sm font-semibold leading-6 text-gray-900" - // onClick={onCancel} + onClick={doCancel} > <i18n.Translate>Cancel</i18n.Translate></button> <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" - // disabled={isRawPayto ? !!errorsPayto : !!errorsWire} - // onClick={(e) => { - // e.preventDefault() - // doStart() - // }} + disabled={!!errors} + onClick={(e) => { + e.preventDefault() + doTransfer() + }} > <i18n.Translate>Transfer</i18n.Translate> </button> @@ -323,6 +262,68 @@ export function WithdrawalConfirmationQuestion({ </form> </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> diff --git a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx index 3b983c2d4..b48e3b1dc 100644 --- a/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx +++ b/packages/demobank-ui/src/pages/WithdrawalQRCode.tsx @@ -62,9 +62,10 @@ export function WithdrawalQRCode({ result.type === ErrorType.CLIENT && result.status === HttpStatusCode.NotFound ) { + clearCurrentWithdrawal() return <div>operation not found</div>; } - onLoadNotOk(); + // onLoadNotOk(); return handleNotOkResult(i18n)(result); } const { data } = result; @@ -85,12 +86,12 @@ export function WithdrawalQRCode({ </i18n.Translate> </p> <a class="pure-button pure-button-primary" - style={{float:"right"}} + style={{ float: "right" }} onClick={async (e) => { e.preventDefault(); clearCurrentWithdrawal() onContinue() - }}> + }}> {i18n.str`Continue`} </a> @@ -99,49 +100,69 @@ export function WithdrawalQRCode({ } if (data.confirmation_done) { - return <section id="main" class="content"> - <h1 class="nav">{i18n.str`Operation completed`}</h1> - - <section id="assets" style={{maxWidth: 400, marginLeft: "auto", marginRight:"auto"}}> - <p> - <i18n.Translate> - The wire transfer to the GNU Taler Exchange bank's account is completed, now the - exchange will send the requested amount into your GNU Taler wallet. - </i18n.Translate> - </p> - <p> - <i18n.Translate> - You can close this page now or continue to the account page. - </i18n.Translate> - </p> - <div style={{textAlign:"center"}}> + if (!settings.showWithdrawalSuccess) { + clearCurrentWithdrawal() + onContinue() + } + 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" - <a class="pure-button pure-button-primary" - onClick={async (e) => { - e.preventDefault(); - clearCurrentWithdrawal() - onContinue() + onClick={() => { + updateSettings("showWithdrawalSuccess", !settings.showWithdrawalSuccess); }}> - {i18n.str`Continue`} - </a> + <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> - </section> - </section> - } - if (!data.selected_reserve_pub) { - return <div> - the exchange is selcted but no reserve pub + </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> - } - const account = !data.selected_exchange_account ? undefined : parsePaytoUri(data.selected_exchange_account) - if (!account) { - return <div> - the exchange is selcted but no account - </div> } - if (!data.selection_done) { return ( <QrCodeSection @@ -150,11 +171,25 @@ export function WithdrawalQRCode({ 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} @@ -167,7 +202,7 @@ export function WithdrawalQRCode({ notifyInfo(i18n.str`Operation canceled`); clearCurrentWithdrawal() onContinue() - }} + }} /> ); }
\ No newline at end of file |