summaryrefslogtreecommitdiff
path: root/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-12-04 09:43:03 -0300
committerSebastian <sebasjm@gmail.com>2023-12-04 09:43:23 -0300
commit8407a1d52e3a89f9c005f9820586d2d0a123c177 (patch)
tree2e467910a656f5b34758b4b4d2ceb9e8f41cfc00 /packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
parent8616c67de8de79a39298299eac9dc368749bfc7a (diff)
downloadwallet-core-8407a1d52e3a89f9c005f9820586d2d0a123c177.tar.gz
wallet-core-8407a1d52e3a89f9c005f9820586d2d0a123c177.tar.bz2
wallet-core-8407a1d52e3a89f9c005f9820586d2d0a123c177.zip
api sync, withdrawal info without password, account creation WIP
Diffstat (limited to 'packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx')
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx153
1 files changed, 90 insertions, 63 deletions
diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index e21c0917b..f8913f0ec 100644
--- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -25,13 +25,14 @@ import {
WithdrawUriResult
} from "@gnu-taler/taler-util";
import {
+ Attention,
ErrorLoading,
Loading,
notifyInfo,
useLocalNotification,
useTranslationContext
} from "@gnu-taler/web-util/browser";
-import { Fragment, VNode, h } from "preact";
+import { ComponentChildren, Fragment, VNode, h } from "preact";
import { useMemo, useState } from "preact/hooks";
import { mutate } from "swr";
import { ShowInputErrorLabel } from "@gnu-taler/web-util/browser";
@@ -45,6 +46,7 @@ import { useBackendState } from "../hooks/backend.js";
import { useWithdrawalDetails } from "../hooks/access.js";
import { OperationState } from "./OperationState/index.js";
import { OperationNotFound } from "./WithdrawalQRCode.js";
+import { ErrorLoadingWithDebug } from "../components/ErrorLoadingWithDebug.js";
const logger = new Logger("WithdrawalConfirmationQuestion");
@@ -54,6 +56,7 @@ interface Props {
details: {
account: PaytoUri,
reserve: string,
+ username: string,
amount: AmountJson,
}
}
@@ -75,15 +78,16 @@ export function WithdrawalConfirmationQuestion({
return <Loading />
}
if (withdrawalInfo instanceof TalerError) {
- return <ErrorLoading error={withdrawalInfo} />
+ return <ErrorLoadingWithDebug error={withdrawalInfo} />
}
if (withdrawalInfo.type === "fail") {
- switch(withdrawalInfo.case) {
- case "not-found": return <OperationNotFound onClose={onAborted} />
- default: assertUnreachable(withdrawalInfo.case)
+ switch (withdrawalInfo.case) {
+ case "not-found": return <OperationNotFound onClose={onAborted} />
+ case "invalid-id": return <OperationNotFound onClose={onAborted} />
+ default: assertUnreachable(withdrawalInfo)
}
}
-
+
const captchaNumbers = useMemo(() => {
return {
a: Math.floor(Math.random() * 10),
@@ -200,67 +204,70 @@ export function WithdrawalConfirmationQuestion({
</h3>
<div class="mt-3 text-sm leading-6">
- <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-10 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg">
- <div class="px-4 sm:px-0">
- <h2 class="text-base font-semibold text-gray-900"><i18n.Translate>Answer the next question to authorize the wire transfer.</i18n.Translate></h2>
- </div>
- <form
- class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl md:col-span-2"
- autoCapitalize="none"
- autoCorrect="off"
- onSubmit={e => {
- e.preventDefault()
- }}
- >
- <div class="px-4 py-6 sm:p-8">
- <label for="withdraw-amount">{i18n.str`What is`}&nbsp;
- <em>
- {captchaNumbers.a}&nbsp;+&nbsp;{captchaNumbers.b}
- </em>
- ?
- </label>
- <div class="mt-2">
- <div class="relative rounded-md shadow-sm">
- <input
- type="text"
- // class="block w-full rounded-md border-0 py-1.5 pl-16 text-gray-900 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"
- 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={captchaAnswer ?? ""}
- required
+ <ShouldBeSameUser username={details.username}>
+ <div class="grid grid-cols-1 gap-x-8 gap-y-8 pt-10 md:grid-cols-3 bg-gray-100 my-4 px-4 pb-4 rounded-lg">
+ <div class="px-4 sm:px-0">
+ <h2 class="text-base font-semibold text-gray-900"><i18n.Translate>Answer the next question to authorize the wire transfer.</i18n.Translate></h2>
+ </div>
+ <form
+ class="bg-white shadow-sm ring-1 ring-gray-900/5 sm:rounded-xl md:col-span-2"
+ autoCapitalize="none"
+ autoCorrect="off"
+ onSubmit={e => {
+ e.preventDefault()
+ }}
+ >
+ <div class="px-4 py-6 sm:p-8">
+ <label for="withdraw-amount">{i18n.str`What is`}&nbsp;
+ <em>
+ {captchaNumbers.a}&nbsp;+&nbsp;{captchaNumbers.b}
+ </em>
+ ?
+ </label>
+
+ <div class="mt-2">
+ <div class="relative rounded-md shadow-sm">
+ <input
+ type="text"
+ // class="block w-full rounded-md border-0 py-1.5 pl-16 text-gray-900 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"
+ 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={captchaAnswer ?? ""}
+ required
- name="answer"
- id="answer"
- autocomplete="off"
- onChange={(e): void => {
- setCaptchaAnswer(e.currentTarget.value)
- }}
- />
+ name="answer"
+ id="answer"
+ autocomplete="off"
+ onChange={(e): void => {
+ setCaptchaAnswer(e.currentTarget.value)
+ }}
+ />
+ </div>
+ <ShowInputErrorLabel message={errors?.answer} isDirty={captchaAnswer !== undefined} />
</div>
- <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={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={!!errors}
- onClick={(e) => {
- e.preventDefault()
- doTransfer()
- }}
- >
- <i18n.Translate>Transfer</i18n.Translate>
- </button>
- </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={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={!!errors}
+ onClick={(e) => {
+ e.preventDefault()
+ doTransfer()
+ }}
+ >
+ <i18n.Translate>Transfer</i18n.Translate>
+ </button>
+ </div>
- </form>
- </div>
+ </form>
+ </div>
+ </ShouldBeSameUser>
</div>
<div class="px-4 mt-4 ">
<div class="w-full">
@@ -325,6 +332,26 @@ export function WithdrawalConfirmationQuestion({
</div>
</div>
- </Fragment>
+ </Fragment >
);
}
+
+export function ShouldBeSameUser({ username, children }: { username: string, children: ComponentChildren }): VNode {
+ const { state: credentials } = useBackendState();
+ const { i18n } = useTranslationContext()
+ if (credentials.status === "loggedOut") {
+ return <Attention type="info" title={i18n.str`Authentication required`}>
+ <p>You should login as "{username}"</p>
+ </Attention>
+ }
+ if (credentials.username !== username) {
+ return <Attention type="warning" title={i18n.str`This operation was created with other username`}>
+ <p>
+ You can switch to account "{username}" and complete the operation.
+ </p>
+ </Attention>
+ }
+ return <Fragment>
+ {children}
+ </Fragment>
+} \ No newline at end of file