summaryrefslogtreecommitdiff
path: root/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2023-02-08 17:41:19 -0300
committerSebastian <sebasjm@gmail.com>2023-02-08 17:41:19 -0300
commita8c5a9696c1735a178158cbc9ac4f9bb4b6f013d (patch)
treefc24dbf06b548925dbc065a49060473fdd220c94 /packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
parent9b0d887a1bc292f652352c1dba4ed4243a88bbbe (diff)
downloadwallet-core-a8c5a9696c1735a178158cbc9ac4f9bb4b6f013d.tar.gz
wallet-core-a8c5a9696c1735a178158cbc9ac4f9bb4b6f013d.tar.bz2
wallet-core-a8c5a9696c1735a178158cbc9ac4f9bb4b6f013d.zip
impl accout management and refactor
Diffstat (limited to 'packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx')
-rw-r--r--packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx466
1 files changed, 258 insertions, 208 deletions
diff --git a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
index b87b77c83..4e5c621e2 100644
--- a/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
+++ b/packages/demobank-ui/src/pages/WithdrawalConfirmationQuestion.tsx
@@ -15,24 +15,29 @@
*/
import { Logger } from "@gnu-taler/taler-util";
+import { useTranslationContext } from "@gnu-taler/web-util/lib/index.browser";
import { Fragment, h, VNode } from "preact";
-import { StateUpdater, useMemo, useState } from "preact/hooks";
+import { useMemo, useState } from "preact/hooks";
import { useBackendContext } from "../context/backend.js";
-import { PageStateType, usePageContext } from "../context/pageState.js";
-import {
- InternationalizationAPI,
- useTranslationContext,
-} from "@gnu-taler/web-util/lib/index.browser";
-import { BackendState } from "../hooks/backend.js";
-import { prepareHeaders } from "../utils.js";
+import { usePageContext } from "../context/pageState.js";
+import { useAccessAPI } from "../hooks/access.js";
+import { undefinedIfEmpty } from "../utils.js";
+import { ShowInputErrorLabel } from "./ShowInputErrorLabel.js";
const logger = new Logger("WithdrawalConfirmationQuestion");
+interface Props {
+ account: string;
+ withdrawalId: string;
+}
/**
* Additional authentication required to complete the operation.
* Not providing a back button, only abort.
*/
-export function WithdrawalConfirmationQuestion(): VNode {
+export function WithdrawalConfirmationQuestion({
+ account,
+ withdrawalId,
+}: Props): VNode {
const { pageState, pageStateSetter } = usePageContext();
const backend = useBackendContext();
const { i18n } = useTranslationContext();
@@ -42,10 +47,20 @@ export function WithdrawalConfirmationQuestion(): VNode {
a: Math.floor(Math.random() * 10),
b: Math.floor(Math.random() * 10),
};
- }, [pageState.withdrawalId]);
+ }, []);
+ const { confirmWithdrawal, abortWithdrawal } = useAccessAPI();
const [captchaAnswer, setCaptchaAnswer] = useState<string | undefined>();
-
+ const answer = parseInt(captchaAnswer ?? "", 10);
+ const errors = undefinedIfEmpty({
+ answer: !captchaAnswer
+ ? i18n.str`Answer the question before continue`
+ : Number.isNaN(answer)
+ ? i18n.str`The answer should be a number`
+ : answer !== captchaNumbers.a + captchaNumbers.b
+ ? i18n.str`The answer "${answer}" to "${captchaNumbers.a} + ${captchaNumbers.b}" is wrong.`
+ : undefined,
+ });
return (
<Fragment>
<h1 class="nav">{i18n.str`Confirm Withdrawal`}</h1>
@@ -82,33 +97,49 @@ export function WithdrawalConfirmationQuestion(): VNode {
setCaptchaAnswer(e.currentTarget.value);
}}
/>
+ <ShowInputErrorLabel
+ message={errors?.answer}
+ isDirty={captchaAnswer !== undefined}
+ />
</p>
<p>
<button
type="submit"
class="pure-button pure-button-primary btn-confirm"
+ disabled={!!errors}
onClick={async (e) => {
e.preventDefault();
- if (
- captchaAnswer ==
- (captchaNumbers.a + captchaNumbers.b).toString()
- ) {
- await confirmWithdrawalCall(
- backend.state,
- pageState.withdrawalId,
- pageStateSetter,
- i18n,
- );
- return;
+ try {
+ await confirmWithdrawal(withdrawalId);
+ pageStateSetter((prevState) => {
+ const { talerWithdrawUri, ...rest } = prevState;
+ return {
+ ...rest,
+ info: i18n.str`Withdrawal confirmed!`,
+ };
+ });
+ } catch (error) {
+ pageStateSetter((prevState) => ({
+ ...prevState,
+ error: {
+ title: i18n.str`Could not confirm the withdrawal`,
+ description: (error as any).error.description,
+ debug: JSON.stringify(error),
+ },
+ }));
}
- pageStateSetter((prevState: PageStateType) => ({
- ...prevState,
-
- error: {
- title: i18n.str`The answer "${captchaAnswer}" to "${captchaNumbers.a} + ${captchaNumbers.b}" is wrong.`,
- },
- }));
- setCaptchaAnswer(undefined);
+ // if (
+ // captchaAnswer ==
+ // (captchaNumbers.a + captchaNumbers.b).toString()
+ // ) {
+ // await confirmWithdrawalCall(
+ // backend.state,
+ // pageState.withdrawalId,
+ // pageStateSetter,
+ // i18n,
+ // );
+ // return;
+ // }
}}
>
{i18n.str`Confirm`}
@@ -118,12 +149,31 @@ export function WithdrawalConfirmationQuestion(): VNode {
class="pure-button pure-button-secondary btn-cancel"
onClick={async (e) => {
e.preventDefault();
- await abortWithdrawalCall(
- backend.state,
- pageState.withdrawalId,
- pageStateSetter,
- i18n,
- );
+ try {
+ await abortWithdrawal(withdrawalId);
+ pageStateSetter((prevState) => {
+ const { talerWithdrawUri, ...rest } = prevState;
+ return {
+ ...rest,
+ info: i18n.str`Withdrawal confirmed!`,
+ };
+ });
+ } catch (error) {
+ pageStateSetter((prevState) => ({
+ ...prevState,
+ error: {
+ title: i18n.str`Could not confirm the withdrawal`,
+ description: (error as any).error.description,
+ debug: JSON.stringify(error),
+ },
+ }));
+ }
+ // await abortWithdrawalCall(
+ // backend.state,
+ // pageState.withdrawalId,
+ // pageStateSetter,
+ // i18n,
+ // );
}}
>
{i18n.str`Cancel`}
@@ -156,188 +206,188 @@ export function WithdrawalConfirmationQuestion(): VNode {
* This function will set the confirmation status in the
* 'page state' and let the related components refresh.
*/
-async function confirmWithdrawalCall(
- backendState: BackendState,
- withdrawalId: string | undefined,
- pageStateSetter: StateUpdater<PageStateType>,
- i18n: InternationalizationAPI,
-): Promise<void> {
- if (backendState.status === "loggedOut") {
- logger.error("No credentials found.");
- pageStateSetter((prevState) => ({
- ...prevState,
+// async function confirmWithdrawalCall(
+// backendState: BackendState,
+// withdrawalId: string | undefined,
+// pageStateSetter: StateUpdater<PageStateType>,
+// i18n: InternationalizationAPI,
+// ): Promise<void> {
+// if (backendState.status === "loggedOut") {
+// logger.error("No credentials found.");
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`No credentials found.`,
- },
- }));
- return;
- }
- if (typeof withdrawalId === "undefined") {
- logger.error("No withdrawal ID found.");
- pageStateSetter((prevState) => ({
- ...prevState,
+// error: {
+// title: i18n.str`No credentials found.`,
+// },
+// }));
+// return;
+// }
+// if (typeof withdrawalId === "undefined") {
+// logger.error("No withdrawal ID found.");
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`No withdrawal ID found.`,
- },
- }));
- return;
- }
- let res: Response;
- try {
- const { username, password } = backendState;
- const headers = prepareHeaders(username, password);
- /**
- * NOTE: tests show that when a same object is being
- * POSTed, caching might prevent same requests from being
- * made. Hence, trying to POST twice the same amount might
- * get silently ignored.
- *
- * headers.append("cache-control", "no-store");
- * headers.append("cache-control", "no-cache");
- * headers.append("pragma", "no-cache");
- * */
+// error: {
+// title: i18n.str`No withdrawal ID found.`,
+// },
+// }));
+// return;
+// }
+// let res: Response;
+// try {
+// const { username, password } = backendState;
+// const headers = prepareHeaders(username, password);
+// /**
+// * NOTE: tests show that when a same object is being
+// * POSTed, caching might prevent same requests from being
+// * made. Hence, trying to POST twice the same amount might
+// * get silently ignored.
+// *
+// * headers.append("cache-control", "no-store");
+// * headers.append("cache-control", "no-cache");
+// * headers.append("pragma", "no-cache");
+// * */
- // Backend URL must have been stored _with_ a final slash.
- const url = new URL(
- `access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/confirm`,
- backendState.url,
- );
- res = await fetch(url.href, {
- method: "POST",
- headers,
- });
- } catch (error) {
- logger.error("Could not POST withdrawal confirmation to the bank", error);
- pageStateSetter((prevState) => ({
- ...prevState,
+// // Backend URL must have been stored _with_ a final slash.
+// const url = new URL(
+// `access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/confirm`,
+// backendState.url,
+// );
+// res = await fetch(url.href, {
+// method: "POST",
+// headers,
+// });
+// } catch (error) {
+// logger.error("Could not POST withdrawal confirmation to the bank", error);
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`Could not confirm the withdrawal`,
- description: (error as any).error.description,
- debug: JSON.stringify(error),
- },
- }));
- return;
- }
- if (!res || !res.ok) {
- const response = await res.json();
- // assume not ok if res is null
- logger.error(
- `Withdrawal confirmation gave response error (${res.status})`,
- res.statusText,
- );
- pageStateSetter((prevState) => ({
- ...prevState,
+// error: {
+// title: i18n.str`Could not confirm the withdrawal`,
+// description: (error as any).error.description,
+// debug: JSON.stringify(error),
+// },
+// }));
+// return;
+// }
+// if (!res || !res.ok) {
+// const response = await res.json();
+// // assume not ok if res is null
+// logger.error(
+// `Withdrawal confirmation gave response error (${res.status})`,
+// res.statusText,
+// );
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`Withdrawal confirmation gave response error`,
- debug: JSON.stringify(response),
- },
- }));
- return;
- }
- logger.trace("Withdrawal operation confirmed!");
- pageStateSetter((prevState) => {
- const { talerWithdrawUri, ...rest } = prevState;
- return {
- ...rest,
+// error: {
+// title: i18n.str`Withdrawal confirmation gave response error`,
+// debug: JSON.stringify(response),
+// },
+// }));
+// return;
+// }
+// logger.trace("Withdrawal operation confirmed!");
+// pageStateSetter((prevState) => {
+// const { talerWithdrawUri, ...rest } = prevState;
+// return {
+// ...rest,
- info: i18n.str`Withdrawal confirmed!`,
- };
- });
-}
+// info: i18n.str`Withdrawal confirmed!`,
+// };
+// });
+// }
-/**
- * Abort a withdrawal operation via the Access API's /abort.
- */
-async function abortWithdrawalCall(
- backendState: BackendState,
- withdrawalId: string | undefined,
- pageStateSetter: StateUpdater<PageStateType>,
- i18n: InternationalizationAPI,
-): Promise<void> {
- if (backendState.status === "loggedOut") {
- logger.error("No credentials found.");
- pageStateSetter((prevState) => ({
- ...prevState,
+// /**
+// * Abort a withdrawal operation via the Access API's /abort.
+// */
+// async function abortWithdrawalCall(
+// backendState: BackendState,
+// withdrawalId: string | undefined,
+// pageStateSetter: StateUpdater<PageStateType>,
+// i18n: InternationalizationAPI,
+// ): Promise<void> {
+// if (backendState.status === "loggedOut") {
+// logger.error("No credentials found.");
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`No credentials found.`,
- },
- }));
- return;
- }
- if (typeof withdrawalId === "undefined") {
- logger.error("No withdrawal ID found.");
- pageStateSetter((prevState) => ({
- ...prevState,
+// error: {
+// title: i18n.str`No credentials found.`,
+// },
+// }));
+// return;
+// }
+// if (typeof withdrawalId === "undefined") {
+// logger.error("No withdrawal ID found.");
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`No withdrawal ID found.`,
- },
- }));
- return;
- }
- let res: Response;
- try {
- const { username, password } = backendState;
- const headers = prepareHeaders(username, password);
- /**
- * NOTE: tests show that when a same object is being
- * POSTed, caching might prevent same requests from being
- * made. Hence, trying to POST twice the same amount might
- * get silently ignored. Needs more observation!
- *
- * headers.append("cache-control", "no-store");
- * headers.append("cache-control", "no-cache");
- * headers.append("pragma", "no-cache");
- * */
+// error: {
+// title: i18n.str`No withdrawal ID found.`,
+// },
+// }));
+// return;
+// }
+// let res: Response;
+// try {
+// const { username, password } = backendState;
+// const headers = prepareHeaders(username, password);
+// /**
+// * NOTE: tests show that when a same object is being
+// * POSTed, caching might prevent same requests from being
+// * made. Hence, trying to POST twice the same amount might
+// * get silently ignored. Needs more observation!
+// *
+// * headers.append("cache-control", "no-store");
+// * headers.append("cache-control", "no-cache");
+// * headers.append("pragma", "no-cache");
+// * */
- // Backend URL must have been stored _with_ a final slash.
- const url = new URL(
- `access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/abort`,
- backendState.url,
- );
- res = await fetch(url.href, { method: "POST", headers });
- } catch (error) {
- logger.error("Could not abort the withdrawal", error);
- pageStateSetter((prevState) => ({
- ...prevState,
+// // Backend URL must have been stored _with_ a final slash.
+// const url = new URL(
+// `access-api/accounts/${backendState.username}/withdrawals/${withdrawalId}/abort`,
+// backendState.url,
+// );
+// res = await fetch(url.href, { method: "POST", headers });
+// } catch (error) {
+// logger.error("Could not abort the withdrawal", error);
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`Could not abort the withdrawal.`,
- description: (error as any).error.description,
- debug: JSON.stringify(error),
- },
- }));
- return;
- }
- if (!res.ok) {
- const response = await res.json();
- logger.error(
- `Withdrawal abort gave response error (${res.status})`,
- res.statusText,
- );
- pageStateSetter((prevState) => ({
- ...prevState,
+// error: {
+// title: i18n.str`Could not abort the withdrawal.`,
+// description: (error as any).error.description,
+// debug: JSON.stringify(error),
+// },
+// }));
+// return;
+// }
+// if (!res.ok) {
+// const response = await res.json();
+// logger.error(
+// `Withdrawal abort gave response error (${res.status})`,
+// res.statusText,
+// );
+// pageStateSetter((prevState) => ({
+// ...prevState,
- error: {
- title: i18n.str`Withdrawal abortion failed.`,
- description: response.error.description,
- debug: JSON.stringify(response),
- },
- }));
- return;
- }
- logger.trace("Withdrawal operation aborted!");
- pageStateSetter((prevState) => {
- const { ...rest } = prevState;
- return {
- ...rest,
+// error: {
+// title: i18n.str`Withdrawal abortion failed.`,
+// description: response.error.description,
+// debug: JSON.stringify(response),
+// },
+// }));
+// return;
+// }
+// logger.trace("Withdrawal operation aborted!");
+// pageStateSetter((prevState) => {
+// const { ...rest } = prevState;
+// return {
+// ...rest,
- info: i18n.str`Withdrawal aborted!`,
- };
- });
-}
+// info: i18n.str`Withdrawal aborted!`,
+// };
+// });
+// }