From 77b03b17a59655c1eeb00e0a818c81f8ea5e326e Mon Sep 17 00:00:00 2001
From: crupest <crupest@outlook.com>
Date: Sat, 29 Jul 2023 22:41:32 +0800
Subject: ...

---
 FrontEnd/src/pages/login/index.tsx | 133 +++++++++++++++++++++++++++++++++++++
 1 file changed, 133 insertions(+)
 create mode 100644 FrontEnd/src/pages/login/index.tsx

(limited to 'FrontEnd/src/pages/login/index.tsx')

diff --git a/FrontEnd/src/pages/login/index.tsx b/FrontEnd/src/pages/login/index.tsx
new file mode 100644
index 00000000..9aee455f
--- /dev/null
+++ b/FrontEnd/src/pages/login/index.tsx
@@ -0,0 +1,133 @@
+import { useState, useEffect } from "react";
+import { Link, useNavigate } from "react-router-dom";
+import { Trans } from "react-i18next";
+
+import { useUser, userService } from "@/services/user";
+
+import { useC } from "@/views/common/common";
+import LoadingButton from "@/views/common/button/LoadingButton";
+import {
+  InputErrorDict,
+  InputGroup,
+  useInputs,
+} from "@/views/common/input/InputGroup";
+import Page from "@/views/common/Page";
+
+import "./index.css";
+
+export default function LoginPage() {
+  const c = useC();
+
+  const user = useUser();
+
+  const navigate = useNavigate();
+
+  const [process, setProcess] = useState<boolean>(false);
+  const [error, setError] = useState<string | null>(null);
+
+  const { hasErrorAndDirty, confirm, setAllDisabled, inputGroupProps } =
+    useInputs({
+      init: {
+        scheme: {
+          inputs: [
+            {
+              key: "username",
+              type: "text",
+              label: "user.username",
+            },
+            {
+              key: "password",
+              type: "text",
+              label: "user.password",
+              password: true,
+            },
+            {
+              key: "rememberMe",
+              type: "bool",
+              label: "user.rememberMe",
+            },
+          ],
+          validator: ({ username, password }) => {
+            const result: InputErrorDict = {};
+            if (username === "") {
+              result["username"] = "login.emptyUsername";
+            }
+            if (password === "") {
+              result["password"] = "login.emptyPassword";
+            }
+            return result;
+          },
+        },
+        dataInit: {},
+      },
+    });
+
+  useEffect(() => {
+    if (user != null) {
+      const id = setTimeout(() => navigate("/"), 3000);
+      return () => {
+        clearTimeout(id);
+      };
+    }
+  }, [navigate, user]);
+
+  if (user != null) {
+    return <p>{c("login.alreadyLogin")}</p>;
+  }
+
+  const submit = (): void => {
+    const confirmResult = confirm();
+    if (confirmResult.type === "ok") {
+      const { username, password, rememberMe } = confirmResult.values;
+      setAllDisabled(true);
+      setProcess(true);
+      userService
+        .login(
+          {
+            username: username as string,
+            password: password as string,
+          },
+          rememberMe as boolean,
+        )
+        .then(
+          () => {
+            if (history.length === 0) {
+              navigate("/");
+            } else {
+              navigate(-1);
+            }
+          },
+          (e: Error) => {
+            setProcess(false);
+            setAllDisabled(false);
+            setError(e.message);
+          },
+        );
+    }
+  };
+
+  return (
+    <Page className="login-page">
+      <div className="login-page-container">
+        <div className="login-page-welcome">{c("welcome")}</div>
+        <InputGroup {...inputGroupProps} />
+        {error ? <p className="cru-color-danger">{c(error)}</p> : null}
+        <div className="login-page-button-row">
+          <LoadingButton
+            loading={process}
+            onClick={(e) => {
+              submit();
+              e.preventDefault();
+            }}
+            disabled={hasErrorAndDirty}
+          >
+            {c("user.login")}
+          </LoadingButton>
+        </div>
+        <Trans i18nKey="login.noAccount">
+          0<Link to="/register">1</Link>2
+        </Trans>
+      </div>
+    </Page>
+  );
+}
-- 
cgit v1.2.3

