From 062939d9cc016a186a282f7a48492c3e01cd740c Mon Sep 17 00:00:00 2001
From: Sebastian <sebasjm@gmail.com>
Date: Thu, 21 Sep 2023 10:31:10 -0300
Subject: admin refactor

---
 .../src/pages/UpdateAccountPassword.tsx            | 131 +++++++++++++++++++++
 1 file changed, 131 insertions(+)
 create mode 100644 packages/demobank-ui/src/pages/UpdateAccountPassword.tsx

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

diff --git a/packages/demobank-ui/src/pages/UpdateAccountPassword.tsx b/packages/demobank-ui/src/pages/UpdateAccountPassword.tsx
new file mode 100644
index 000000000..084a5b643
--- /dev/null
+++ b/packages/demobank-ui/src/pages/UpdateAccountPassword.tsx
@@ -0,0 +1,131 @@
+import { ErrorType, HttpResponsePaginated, RequestError, notify, notifyError, useTranslationContext } from "@gnu-taler/web-util/browser";
+import { useAdminAccountAPI, useBusinessAccountDetails } from "../hooks/circuit.js";
+import { useState } from "preact/hooks";
+import { HttpStatusCode, TranslatedString } from "@gnu-taler/taler-util";
+import { VNode,h ,Fragment} from "preact";
+import { buildRequestErrorMessage, undefinedIfEmpty } from "../utils.js";
+import { ShowInputErrorLabel } from "../components/ShowInputErrorLabel.js";
+
+export function UpdateAccountPassword({
+    account,
+    onClear,
+    onUpdateSuccess,
+    onLoadNotOk,
+  }: {
+    onLoadNotOk: <T>(
+      error: HttpResponsePaginated<T, SandboxBackend.SandboxError>,
+    ) => VNode;
+    onClear: () => void;
+    onUpdateSuccess: () => void;
+    account: string;
+  }): VNode {
+    const { i18n } = useTranslationContext();
+    const result = useBusinessAccountDetails(account);
+    const { changePassword } = useAdminAccountAPI();
+    const [password, setPassword] = useState<string | undefined>();
+    const [repeat, setRepeat] = useState<string | undefined>();
+  
+    if (!result.ok) {
+      if (result.loading || result.type === ErrorType.TIMEOUT) {
+        return onLoadNotOk(result);
+      }
+      if (result.status === HttpStatusCode.NotFound) {
+        return <div>account not found</div>;
+      }
+      return onLoadNotOk(result);
+    }
+  
+    const errors = undefinedIfEmpty({
+      password: !password ? i18n.str`required` : undefined,
+      repeat: !repeat
+        ? i18n.str`required`
+        : password !== repeat
+          ? i18n.str`password doesn't match`
+          : undefined,
+    });
+  
+    return (
+      <div>
+        <div>
+          <h1 class="nav welcome-text">
+            <i18n.Translate>Update password for {account}</i18n.Translate>
+          </h1>
+        </div>
+  
+        <div style={{ maxWidth: 600, overflowX: "hidden", margin: "auto" }}>
+          <form class="pure-form">
+            <fieldset>
+              <label>{i18n.str`Password`}</label>
+              <input
+                type="password"
+                value={password ?? ""}
+                onChange={(e) => {
+                  setPassword(e.currentTarget.value);
+                }}
+              />
+              <ShowInputErrorLabel
+                message={errors?.password}
+                isDirty={password !== undefined}
+              />
+            </fieldset>
+            <fieldset>
+              <label>{i18n.str`Repeat password`}</label>
+              <input
+                type="password"
+                value={repeat ?? ""}
+                onChange={(e) => {
+                  setRepeat(e.currentTarget.value);
+                }}
+              />
+              <ShowInputErrorLabel
+                message={errors?.repeat}
+                isDirty={repeat !== undefined}
+              />
+            </fieldset>
+          </form>
+          <p>
+            <div style={{ display: "flex", justifyContent: "space-between" }}>
+              <div>
+                <input
+                  class="pure-button"
+                  type="submit"
+                  value={i18n.str`Close`}
+                  onClick={async (e) => {
+                    e.preventDefault();
+                    onClear();
+                  }}
+                />
+              </div>
+              <div>
+                <input
+                  id="select-exchange"
+                  class="pure-button pure-button-primary content"
+                  disabled={!!errors}
+                  type="submit"
+                  value={i18n.str`Confirm`}
+                  onClick={async (e) => {
+                    e.preventDefault();
+                    if (!!errors || !password) return;
+                    try {
+                      const r = await changePassword(account, {
+                        new_password: password,
+                      });
+                      onUpdateSuccess();
+                    } catch (error) {
+                      if (error instanceof RequestError) {
+                        notify(buildRequestErrorMessage(i18n, error.cause));
+                      } else {
+                        notifyError(i18n.str`Operation failed, please report`, (error instanceof Error
+                          ? error.message
+                          : JSON.stringify(error)) as TranslatedString)
+                      }
+                    }
+                  }}
+                />
+              </div>
+            </div>
+          </p>
+        </div>
+      </div>
+    );
+  }
\ No newline at end of file
-- 
cgit v1.2.3

