From 0b7bbed99d155ba030a1328e357ab6751bdbb835 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Thu, 21 Sep 2023 13:10:16 -0300 Subject: more ui: business and admin --- .../demobank-ui/src/pages/admin/RemoveAccount.tsx | 302 ++++++++++++++------- 1 file changed, 204 insertions(+), 98 deletions(-) (limited to 'packages/demobank-ui/src/pages/admin/RemoveAccount.tsx') diff --git a/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx b/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx index 2900db9d2..050f1fb8a 100644 --- a/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx +++ b/packages/demobank-ui/src/pages/admin/RemoveAccount.tsx @@ -1,112 +1,218 @@ import { ErrorType, HttpResponsePaginated, RequestError, notify, notifyError, useTranslationContext } from "@gnu-taler/web-util/browser"; -import { VNode,h,Fragment } from "preact"; +import { VNode, h, Fragment } from "preact"; import { useAccountDetails } from "../../hooks/access.js"; import { useAdminAccountAPI } from "../../hooks/circuit.js"; import { Amounts, HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util"; -import { buildRequestErrorMessage } from "../../utils.js"; +import { buildRequestErrorMessage, undefinedIfEmpty } from "../../utils.js"; +import { useEffect, useRef, useState } from "preact/hooks"; +import { ShowInputErrorLabel } from "../../components/ShowInputErrorLabel.js"; export function RemoveAccount({ - account, - onClear, - onUpdateSuccess, - onLoadNotOk, - }: { - onLoadNotOk: ( - error: HttpResponsePaginated, - ) => VNode; - onClear: () => void; - onUpdateSuccess: () => void; - account: string; - }): VNode { - const { i18n } = useTranslationContext(); - const result = useAccountDetails(account); - const { deleteAccount } = useAdminAccountAPI(); - - if (!result.ok) { - if (result.loading || result.type === ErrorType.TIMEOUT) { - return onLoadNotOk(result); - } - if (result.status === HttpStatusCode.NotFound) { - return
account not found
; - } + account, + onCancel, + onUpdateSuccess, + onLoadNotOk, + focus, +}: { + onLoadNotOk: ( + error: HttpResponsePaginated, + ) => VNode; + focus?: boolean; + onCancel: () => void; + onUpdateSuccess: () => void; + account: string; +}): VNode { + const { i18n } = useTranslationContext(); + const result = useAccountDetails(account); + const [accountName, setAccountName] = useState() + const { deleteAccount } = useAdminAccountAPI(); + + if (!result.ok) { + if (result.loading || result.type === ErrorType.TIMEOUT) { return onLoadNotOk(result); } - - const balance = Amounts.parse(result.data.balance.amount); - if (!balance) { - return
there was an error reading the balance
; + if (result.status === HttpStatusCode.NotFound) { + return
account not found
; } - const isBalanceEmpty = Amounts.isZero(balance); - return ( -
-
-

- Remove account: {account} -

+ return onLoadNotOk(result); + } + const ref = useRef(null); + useEffect(() => { + if (focus) ref.current?.focus(); + }, [focus]); + + const balance = Amounts.parse(result.data.balance.amount); + if (!balance) { + return
there was an error reading the balance
; + } + const isBalanceEmpty = Amounts.isZero(balance); + if (!isBalanceEmpty) { + return
+
+
+
+ +
+
+

+ Can't delete the account +

+
+

+ The account can be delete while still holding some balance. First make sure that the owner make a complete cashout. +

+
+
+
- {/* {FXME: SHOW WARNING} */} - {/* {!isBalanceEmpty && ( - saveError(undefined)} - /> - )} */} - -

-

-
- { - e.preventDefault(); - onClear(); - }} - /> +
+
+ +
+
+ } + + async function doRemove() { + try { + const r = await deleteAccount(account); + onUpdateSuccess(); + } catch (error) { + if (error instanceof RequestError) { + notify( + buildRequestErrorMessage(i18n, error.cause, { + onClientError: (status) => + status === HttpStatusCode.Forbidden + ? i18n.str`The administrator specified a institutional username` + : status === HttpStatusCode.NotFound + ? i18n.str`The username was not found` + : status === HttpStatusCode.PreconditionFailed + ? i18n.str`Balance was not zero` + : undefined, + }), + ); + } else { + notifyError(i18n.str`Operation failed, please report`, + (error instanceof Error + ? error.message + : JSON.stringify(error)) as TranslatedString); + } + } + } + + const errors = undefinedIfEmpty({ + accountName: !accountName + ? i18n.str`required` + : account !== accountName + ? i18n.str`name doesn't match` + : undefined, + }); + + + return ( +
+
+
+
+ +
+
+

+ You are going to remove the account +

+
+

+ This step can't be undone. +

-
- { - e.preventDefault(); - try { - const r = await deleteAccount(account); - onUpdateSuccess(); - } catch (error) { - if (error instanceof RequestError) { - notify( - buildRequestErrorMessage(i18n, error.cause, { - onClientError: (status) => - status === HttpStatusCode.Forbidden - ? i18n.str`The administrator specified a institutional username` - : status === HttpStatusCode.NotFound - ? i18n.str`The username was not found` - : status === HttpStatusCode.PreconditionFailed - ? i18n.str`Balance was not zero` - : undefined, - }), - ); - } else { - notifyError(i18n.str`Operation failed, please report`, - (error instanceof Error - ? error.message - : JSON.stringify(error)) as TranslatedString); - } - } - }} - /> +
+ +
+
+ +
+
+

+ Deleting account "{account}" +

+
+
{ + e.preventDefault() + }} + > +
+
+ +
+ +
+ { + setAccountName(e.currentTarget.value) + }} + placeholder={account} + autocomplete="off" + /> + +
+

+ enter the account name that is going to be deleted +

+
+ + +
-

+
+ {onCancel ? + + :
+ } + +
+
- ); - } - \ No newline at end of file +
+ ); +} -- cgit v1.2.3