diff options
Diffstat (limited to 'packages/demobank-ui/src/pages/AdminPage.tsx')
-rw-r--r-- | packages/demobank-ui/src/pages/AdminPage.tsx | 149 |
1 files changed, 100 insertions, 49 deletions
diff --git a/packages/demobank-ui/src/pages/AdminPage.tsx b/packages/demobank-ui/src/pages/AdminPage.tsx index 0a1dc26ec..2a5701a95 100644 --- a/packages/demobank-ui/src/pages/AdminPage.tsx +++ b/packages/demobank-ui/src/pages/AdminPage.tsx @@ -16,6 +16,7 @@ import { Amounts, + HttpStatusCode, parsePaytoUri, TranslatedString, } from "@gnu-taler/taler-util"; @@ -35,11 +36,13 @@ import { useAdminAccountAPI, } from "../hooks/circuit.js"; import { + buildRequestErrorMessage, PartialButDefined, + RecursivePartial, undefinedIfEmpty, WithIntermediate, } from "../utils.js"; -import { ErrorBanner } from "./BankFrame.js"; +import { ErrorBannerFloat } from "./BankFrame.js"; import { ShowCashoutDetails } from "./BusinessAccount.js"; import { ShowInputErrorLabel } from "./ShowInputErrorLabel.js"; @@ -373,7 +376,7 @@ export function UpdateAccountPassword({ </h1> </div> {error && ( - <ErrorBanner error={error} onClear={() => saveError(undefined)} /> + <ErrorBannerFloat error={error} onClear={() => saveError(undefined)} /> )} <form class="pure-form"> @@ -435,7 +438,17 @@ export function UpdateAccountPassword({ }); onUpdateSuccess(); } catch (error) { - handleError(error, saveError, i18n); + if (error instanceof RequestError) { + saveError(buildRequestErrorMessage(i18n, error.cause)); + } else { + saveError({ + title: i18n.str`Operation failed, please report`, + description: + error instanceof Error + ? error.message + : JSON.stringify(error), + }); + } } }} /> @@ -467,13 +480,16 @@ function CreateNewAccount({ </h1> </div> {error && ( - <ErrorBanner error={error} onClear={() => saveError(undefined)} /> + <ErrorBannerFloat error={error} onClear={() => saveError(undefined)} /> )} <AccountForm template={undefined} purpose="create" - onChange={(a) => setSubmitAccount(a)} + onChange={(a) => { + console.log(a); + setSubmitAccount(a); + }} /> <p> @@ -514,7 +530,28 @@ function CreateNewAccount({ await createAccount(account); onCreateSuccess(account.password); } catch (error) { - handleError(error, saveError, i18n); + if (error instanceof RequestError) { + saveError( + buildRequestErrorMessage(i18n, error.cause, { + onClientError: (status) => + status === HttpStatusCode.Forbidden + ? i18n.str`The rights to perform the operation are not sufficient` + : status === HttpStatusCode.BadRequest + ? i18n.str`Input data was invalid` + : status === HttpStatusCode.Conflict + ? i18n.str`At least one registration detail was not available` + : undefined, + }), + ); + } else { + saveError({ + title: i18n.str`Operation failed, please report`, + description: + error instanceof Error + ? error.message + : JSON.stringify(error), + }); + } } }} /> @@ -564,7 +601,7 @@ export function ShowAccountDetails({ </h1> </div> {error && ( - <ErrorBanner error={error} onClear={() => saveError(undefined)} /> + <ErrorBannerFloat error={error} onClear={() => saveError(undefined)} /> )} <AccountForm template={result.data} @@ -622,7 +659,26 @@ export function ShowAccountDetails({ }); onUpdateSuccess(); } catch (error) { - handleError(error, saveError, i18n); + if (error instanceof RequestError) { + saveError( + buildRequestErrorMessage(i18n, error.cause, { + onClientError: (status) => + status === HttpStatusCode.Forbidden + ? i18n.str`The rights to change the account are not sufficient` + : status === HttpStatusCode.NotFound + ? i18n.str`The username was not found` + : undefined, + }), + ); + } else { + saveError({ + title: i18n.str`Operation failed, please report`, + description: + error instanceof Error + ? error.message + : JSON.stringify(error), + }); + } } } }} @@ -673,7 +729,7 @@ function RemoveAccount({ </h1> </div> {!isBalanceEmpty && ( - <ErrorBanner + <ErrorBannerFloat error={{ title: i18n.str`Can't delete the account`, description: i18n.str`Balance is not empty`, @@ -681,7 +737,7 @@ function RemoveAccount({ /> )} {error && ( - <ErrorBanner error={error} onClear={() => saveError(undefined)} /> + <ErrorBannerFloat error={error} onClear={() => saveError(undefined)} /> )} <p> @@ -710,7 +766,28 @@ function RemoveAccount({ const r = await deleteAccount(account); onUpdateSuccess(); } catch (error) { - handleError(error, saveError, i18n); + if (error instanceof RequestError) { + saveError( + 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 { + saveError({ + title: i18n.str`Operation failed, please report`, + description: + error instanceof Error + ? error.message + : JSON.stringify(error), + }); + } } }} /> @@ -720,7 +797,6 @@ function RemoveAccount({ </div> ); } - /** * Create valid account object to update or create * Take template as initial values for the form @@ -740,7 +816,9 @@ function AccountForm({ }): VNode { const initial = initializeFromTemplate(template); const [form, setForm] = useState(initial); - const [errors, setErrors] = useState<typeof initial | undefined>(undefined); + const [errors, setErrors] = useState< + RecursivePartial<typeof initial> | undefined + >(undefined); const { i18n } = useTranslationContext(); function updateForm(newForm: typeof initial): void { @@ -748,7 +826,7 @@ function AccountForm({ ? undefined : parsePaytoUri(newForm.cashout_address); - const validationResult = undefinedIfEmpty<typeof initial>({ + const errors = undefinedIfEmpty<RecursivePartial<typeof initial>>({ cashout_address: !newForm.cashout_address ? i18n.str`required` : !parsed @@ -758,20 +836,20 @@ function AccountForm({ : !IBAN_REGEX.test(parsed.iban) ? i18n.str`IBAN should have just uppercased letters and numbers` : undefined, - contact_data: { - email: !newForm.contact_data.email + contact_data: undefinedIfEmpty({ + email: !newForm.contact_data?.email ? undefined : !EMAIL_REGEX.test(newForm.contact_data.email) ? i18n.str`it should be an email` : undefined, - phone: !newForm.contact_data.phone + phone: !newForm.contact_data?.phone ? undefined : !newForm.contact_data.phone.startsWith("+") ? i18n.str`should start with +` : !REGEX_JUST_NUMBERS_REGEX.test(newForm.contact_data.phone) ? i18n.str`phone number can't have other than numbers` : undefined, - }, + }), iban: !newForm.iban ? i18n.str`required` : !IBAN_REGEX.test(newForm.iban) @@ -780,10 +858,9 @@ function AccountForm({ name: !newForm.name ? i18n.str`required` : undefined, username: !newForm.username ? i18n.str`required` : undefined, }); - - setErrors(validationResult); + setErrors(errors); setForm(newForm); - onChange(validationResult === undefined ? undefined : (newForm as any)); + onChange(errors === undefined ? (newForm as any) : undefined); } return ( @@ -846,7 +923,7 @@ function AccountForm({ }} /> <ShowInputErrorLabel - message={errors?.contact_data.email} + message={errors?.contact_data?.email} isDirty={form.contact_data.email !== undefined} /> </fieldset> @@ -861,7 +938,7 @@ function AccountForm({ }} /> <ShowInputErrorLabel - message={errors?.contact_data.phone} + message={errors?.contact_data?.phone} isDirty={form.contact_data?.phone !== undefined} /> </fieldset> @@ -883,29 +960,3 @@ function AccountForm({ </form> ); } - -function handleError( - error: unknown, - saveError: (e: ErrorMessage) => void, - i18n: ReturnType<typeof useTranslationContext>["i18n"], -): void { - if (error instanceof RequestError) { - const payload = error.info.error as SandboxBackend.SandboxError; - saveError({ - title: error.info.serverError - ? i18n.str`Server had an error` - : i18n.str`Server didn't accept the request`, - description: payload.error.description, - }); - } else if (error instanceof Error) { - saveError({ - title: i18n.str`Could not update account`, - description: error.message, - }); - } else { - saveError({ - title: i18n.str`Error, please report`, - debug: JSON.stringify(error), - }); - } -} |