From 9922192b0dba2e479b5af3e29c1d44b98e4d29d7 Mon Sep 17 00:00:00 2001
From: Sebastian <sebasjm@gmail.com>
Date: Tue, 28 Feb 2023 19:03:43 -0300
Subject: fix #7729

---
 packages/demobank-ui/src/pages/AdminPage.tsx | 149 ++++++++++++++++++---------
 1 file changed, 100 insertions(+), 49 deletions(-)

(limited to 'packages/demobank-ui/src/pages/AdminPage.tsx')

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),
-    });
-  }
-}
-- 
cgit v1.2.3

