aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-09-20 16:10:32 -0300
committerSebastian <sebasjm@gmail.com>2023-09-25 14:50:40 -0300
commit7d4c5a71aaa6c4e781af124fe821d8be4ed101ed (patch)
tree760314547bb21ed9ee3501dd8af657bf2fc9a577
parente39d5c488e2e425bd7febf694caadc17d5126401 (diff)
more ui
-rw-r--r--packages/demobank-ui/src/hooks/backend.ts16
-rw-r--r--packages/demobank-ui/src/hooks/settings.ts10
-rw-r--r--packages/demobank-ui/src/pages/BankFrame.tsx50
-rw-r--r--packages/demobank-ui/src/pages/HomePage.tsx9
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx165
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalQRCode.tsx117
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