From 4de014927e95d792633ea367eb4404459489d44f Mon Sep 17 00:00:00 2001
From: Sebastian <sebasjm@gmail.com>
Date: Sun, 5 Mar 2023 15:21:12 -0300
Subject: validate IBAN, removing internal iban from account form, add missing
 logo, do not save backend URL in login state

---
 packages/demobank-ui/src/pages/AdminPage.tsx | 214 +++++++++++++++------------
 1 file changed, 118 insertions(+), 96 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 2a5701a95..3d0c09cbf 100644
--- a/packages/demobank-ui/src/pages/AdminPage.tsx
+++ b/packages/demobank-ui/src/pages/AdminPage.tsx
@@ -40,6 +40,7 @@ import {
   PartialButDefined,
   RecursivePartial,
   undefinedIfEmpty,
+  validateIBAN,
   WithIntermediate,
 } from "../utils.js";
 import { ErrorBannerFloat } from "./BankFrame.js";
@@ -230,74 +231,78 @@ export function AdminPage({ onLoadNotOk }: Props): VNode {
       </p>
 
       <section id="main">
-        <article>
-          <h2>{i18n.str`Accounts:`}</h2>
-          <div class="results">
-            <table class="pure-table pure-table-striped">
-              <thead>
-                <tr>
-                  <th>{i18n.str`Username`}</th>
-                  <th>{i18n.str`Name`}</th>
-                  <th></th>
-                  <th></th>
-                </tr>
-              </thead>
-              <tbody>
-                {customers.map((item, idx) => {
-                  return (
-                    <tr key={idx}>
-                      <td>
-                        <a
-                          href="#"
-                          onClick={(e) => {
-                            e.preventDefault();
-                            setShowDetails(item.username);
-                          }}
-                        >
-                          {item.username}
-                        </a>
-                      </td>
-                      <td>{item.name}</td>
-                      <td>
-                        <a
-                          href="#"
-                          onClick={(e) => {
-                            e.preventDefault();
-                            setUpdatePassword(item.username);
-                          }}
-                        >
-                          change password
-                        </a>
-                      </td>
-                      <td>
-                        <a
-                          href="#"
-                          onClick={(e) => {
-                            e.preventDefault();
-                            setShowCashouts(item.username);
-                          }}
-                        >
-                          cashouts
-                        </a>
-                      </td>
-                      <td>
-                        <a
-                          href="#"
-                          onClick={(e) => {
-                            e.preventDefault();
-                            setRemoveAccount(item.username);
-                          }}
-                        >
-                          remove
-                        </a>
-                      </td>
-                    </tr>
-                  );
-                })}
-              </tbody>
-            </table>
-          </div>
-        </article>
+        {!customers.length ? (
+          <div></div>
+        ) : (
+          <article>
+            <h2>{i18n.str`Accounts:`}</h2>
+            <div class="results">
+              <table class="pure-table pure-table-striped">
+                <thead>
+                  <tr>
+                    <th>{i18n.str`Username`}</th>
+                    <th>{i18n.str`Name`}</th>
+                    <th></th>
+                    <th></th>
+                  </tr>
+                </thead>
+                <tbody>
+                  {customers.map((item, idx) => {
+                    return (
+                      <tr key={idx}>
+                        <td>
+                          <a
+                            href="#"
+                            onClick={(e) => {
+                              e.preventDefault();
+                              setShowDetails(item.username);
+                            }}
+                          >
+                            {item.username}
+                          </a>
+                        </td>
+                        <td>{item.name}</td>
+                        <td>
+                          <a
+                            href="#"
+                            onClick={(e) => {
+                              e.preventDefault();
+                              setUpdatePassword(item.username);
+                            }}
+                          >
+                            change password
+                          </a>
+                        </td>
+                        <td>
+                          <a
+                            href="#"
+                            onClick={(e) => {
+                              e.preventDefault();
+                              setShowCashouts(item.username);
+                            }}
+                          >
+                            cashouts
+                          </a>
+                        </td>
+                        <td>
+                          <a
+                            href="#"
+                            onClick={(e) => {
+                              e.preventDefault();
+                              setRemoveAccount(item.username);
+                            }}
+                          >
+                            remove
+                          </a>
+                        </td>
+                      </tr>
+                    );
+                  })}
+                </tbody>
+              </table>
+            </div>
+          </article>
+        )}
       </section>
     </Fragment>
   );
@@ -835,15 +840,15 @@ function AccountForm({
         ? i18n.str`only "IBAN" target are supported`
         : !IBAN_REGEX.test(parsed.iban)
         ? i18n.str`IBAN should have just uppercased letters and numbers`
-        : undefined,
+        : validateIBAN(parsed.iban, i18n),
       contact_data: undefinedIfEmpty({
         email: !newForm.contact_data?.email
-          ? undefined
+          ? i18n.str`required`
           : !EMAIL_REGEX.test(newForm.contact_data.email)
           ? i18n.str`it should be an email`
           : undefined,
         phone: !newForm.contact_data?.phone
-          ? undefined
+          ? i18n.str`required`
           : !newForm.contact_data.phone.startsWith("+")
           ? i18n.str`should start with +`
           : !REGEX_JUST_NUMBERS_REGEX.test(newForm.contact_data.phone)
@@ -851,10 +856,10 @@ function AccountForm({
           : undefined,
       }),
       iban: !newForm.iban
-        ? i18n.str`required`
+        ? undefined //optional field
         : !IBAN_REGEX.test(newForm.iban)
         ? i18n.str`IBAN should have just uppercased letters and numbers`
-        : undefined,
+        : validateIBAN(newForm.iban, i18n),
       name: !newForm.name ? i18n.str`required` : undefined,
       username: !newForm.username ? i18n.str`required` : undefined,
     });
@@ -866,7 +871,10 @@ function AccountForm({
   return (
     <form class="pure-form">
       <fieldset>
-        <label for="username">{i18n.str`Username`}</label>
+        <label for="username">
+          {i18n.str`Username`}
+          {purpose === "create" && <b style={{ color: "red" }}>*</b>}
+        </label>
         <input
           name="username"
           type="text"
@@ -876,14 +884,17 @@ function AccountForm({
             form.username = e.currentTarget.value;
             updateForm(structuredClone(form));
           }}
-        />
+        />{" "}
         <ShowInputErrorLabel
           message={errors?.username}
           isDirty={form.username !== undefined}
         />
       </fieldset>
       <fieldset>
-        <label>{i18n.str`Name`}</label>
+        <label>
+          {i18n.str`Name`}
+          {purpose === "create" && <b style={{ color: "red" }}>*</b>}
+        </label>
         <input
           disabled={purpose !== "create"}
           value={form.name ?? ""}
@@ -897,23 +908,28 @@ function AccountForm({
           isDirty={form.name !== undefined}
         />
       </fieldset>
+      {purpose !== "create" && (
+        <fieldset>
+          <label>{i18n.str`Internal IBAN`}</label>
+          <input
+            disabled={true}
+            value={form.iban ?? ""}
+            onChange={(e) => {
+              form.iban = e.currentTarget.value;
+              updateForm(structuredClone(form));
+            }}
+          />
+          <ShowInputErrorLabel
+            message={errors?.iban}
+            isDirty={form.iban !== undefined}
+          />
+        </fieldset>
+      )}
       <fieldset>
-        <label>{i18n.str`Internal IBAN`}</label>
-        <input
-          disabled={purpose !== "create"}
-          value={form.iban ?? ""}
-          onChange={(e) => {
-            form.iban = e.currentTarget.value;
-            updateForm(structuredClone(form));
-          }}
-        />
-        <ShowInputErrorLabel
-          message={errors?.iban}
-          isDirty={form.iban !== undefined}
-        />
-      </fieldset>
-      <fieldset>
-        <label>{i18n.str`Email`}</label>
+        <label>
+          {i18n.str`Email`}
+          {purpose !== "show" && <b style={{ color: "red" }}>*</b>}
+        </label>
         <input
           disabled={purpose === "show"}
           value={form.contact_data.email ?? ""}
@@ -928,7 +944,10 @@ function AccountForm({
         />
       </fieldset>
       <fieldset>
-        <label>{i18n.str`Phone`}</label>
+        <label>
+          {i18n.str`Phone`}
+          {purpose !== "show" && <b style={{ color: "red" }}>*</b>}
+        </label>
         <input
           disabled={purpose === "show"}
           value={form.contact_data.phone ?? ""}
@@ -943,12 +962,15 @@ function AccountForm({
         />
       </fieldset>
       <fieldset>
-        <label>{i18n.str`Cashout address`}</label>
+        <label>
+          {i18n.str`Cashout address`}
+          {purpose !== "show" && <b style={{ color: "red" }}>*</b>}
+        </label>
         <input
           disabled={purpose === "show"}
-          value={form.cashout_address ?? ""}
+          value={(form.cashout_address ?? "").substring("payto://iban/".length)}
           onChange={(e) => {
-            form.cashout_address = e.currentTarget.value;
+            form.cashout_address = "payto://iban/" + e.currentTarget.value;
             updateForm(structuredClone(form));
           }}
         />
-- 
cgit v1.2.3

