From b64ae1399aee817921264361b9172bef377d4c29 Mon Sep 17 00:00:00 2001 From: Steven Date: Thu, 29 Aug 2024 20:22:08 +0800 Subject: [PATCH] chore: add admin sign in page --- .../web/src/components/PasswordAuthForm.tsx | 86 +++++++++++++++++ frontend/web/src/pages/AdminSignIn.tsx | 22 +++++ frontend/web/src/pages/SignIn.tsx | 93 ++----------------- frontend/web/src/routers/index.tsx | 5 + 4 files changed, 123 insertions(+), 83 deletions(-) create mode 100644 frontend/web/src/components/PasswordAuthForm.tsx create mode 100644 frontend/web/src/pages/AdminSignIn.tsx diff --git a/frontend/web/src/components/PasswordAuthForm.tsx b/frontend/web/src/components/PasswordAuthForm.tsx new file mode 100644 index 0000000..2451e4c --- /dev/null +++ b/frontend/web/src/components/PasswordAuthForm.tsx @@ -0,0 +1,86 @@ +import { Button, Input } from "@mui/joy"; +import { FormEvent, useState } from "react"; +import toast from "react-hot-toast"; +import { useTranslation } from "react-i18next"; +import { authServiceClient } from "@/grpcweb"; +import useLoading from "@/hooks/useLoading"; +import useNavigateTo from "@/hooks/useNavigateTo"; +import { useUserStore } from "@/stores"; + +const PasswordAuthForm = () => { + const { t } = useTranslation(); + const navigateTo = useNavigateTo(); + const userStore = useUserStore(); + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const actionBtnLoadingState = useLoading(false); + const allowConfirm = email.length > 0 && password.length > 0; + + const handleEmailInputChanged = (e: React.ChangeEvent) => { + const text = e.target.value as string; + setEmail(text); + }; + + const handlePasswordInputChanged = (e: React.ChangeEvent) => { + const text = e.target.value as string; + setPassword(text); + }; + + const handleSigninBtnClick = async (e: FormEvent) => { + e.preventDefault(); + if (actionBtnLoadingState.isLoading) { + return; + } + + try { + actionBtnLoadingState.setLoading(); + const user = await authServiceClient.signIn({ email, password }); + if (user) { + userStore.setCurrentUserId(user.id); + await userStore.fetchCurrentUser(); + navigateTo("/"); + } else { + toast.error("Signin failed"); + } + } catch (error: any) { + console.error(error); + toast.error(error.details); + } + actionBtnLoadingState.setFinish(); + }; + + return ( +
+
+
+ {t("common.email")} + +
+
+ {t("common.password")} + +
+
+
+ +
+
+ ); +}; + +export default PasswordAuthForm; diff --git a/frontend/web/src/pages/AdminSignIn.tsx b/frontend/web/src/pages/AdminSignIn.tsx new file mode 100644 index 0000000..b5d3a03 --- /dev/null +++ b/frontend/web/src/pages/AdminSignIn.tsx @@ -0,0 +1,22 @@ +import React from "react"; +import Logo from "@/components/Logo"; +import PasswordAuthForm from "@/components/PasswordAuthForm"; + +const AdminSignIn: React.FC = () => { + return ( +
+
+
+
+ + Slash +
+

Sign in with admin accounts

+ +
+
+
+ ); +}; + +export default AdminSignIn; diff --git a/frontend/web/src/pages/SignIn.tsx b/frontend/web/src/pages/SignIn.tsx index 48a5cf7..cdd3990 100644 --- a/frontend/web/src/pages/SignIn.tsx +++ b/frontend/web/src/pages/SignIn.tsx @@ -1,65 +1,17 @@ -import { Button, Divider, Input } from "@mui/joy"; -import React, { FormEvent, useEffect, useState } from "react"; +import { Button, Divider } from "@mui/joy"; +import React from "react"; import { toast } from "react-hot-toast"; import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import Logo from "@/components/Logo"; -import { authServiceClient } from "@/grpcweb"; +import PasswordAuthForm from "@/components/PasswordAuthForm"; import { absolutifyLink } from "@/helpers/utils"; -import useLoading from "@/hooks/useLoading"; -import useNavigateTo from "@/hooks/useNavigateTo"; -import { useUserStore, useWorkspaceStore } from "@/stores"; +import { useWorkspaceStore } from "@/stores"; import { IdentityProvider, IdentityProvider_Type } from "@/types/proto/api/v1/workspace_service"; const SignIn: React.FC = () => { const { t } = useTranslation(); - const navigateTo = useNavigateTo(); const workspaceStore = useWorkspaceStore(); - const userStore = useUserStore(); - const [email, setEmail] = useState(""); - const [password, setPassword] = useState(""); - const actionBtnLoadingState = useLoading(false); - const allowConfirm = email.length > 0 && password.length > 0; - - useEffect(() => { - if (workspaceStore.profile.mode === "demo") { - setEmail("slash@yourselfhosted.com"); - setPassword("secret"); - } - }, []); - - const handleEmailInputChanged = (e: React.ChangeEvent) => { - const text = e.target.value as string; - setEmail(text); - }; - - const handlePasswordInputChanged = (e: React.ChangeEvent) => { - const text = e.target.value as string; - setPassword(text); - }; - - const handleSigninBtnClick = async (e: FormEvent) => { - e.preventDefault(); - if (actionBtnLoadingState.isLoading) { - return; - } - - try { - actionBtnLoadingState.setLoading(); - const user = await authServiceClient.signIn({ email, password }); - if (user) { - userStore.setCurrentUserId(user.id); - await userStore.fetchCurrentUser(); - navigateTo("/"); - } else { - toast.error("Signin failed"); - } - } catch (error: any) { - console.error(error); - toast.error(error.details); - } - actionBtnLoadingState.setFinish(); - }; const handleSignInWithIdentityProvider = async (identityProvider: IdentityProvider) => { const stateQueryParameter = identityProvider.id; @@ -87,37 +39,12 @@ const SignIn: React.FC = () => { Slash -
-
-
- {t("common.email")} - -
-
- {t("common.password")} - -
-
-
- -
-
- {!workspaceStore.setting.disallowUserRegistration && ( + {!workspaceStore.setting.disallowPasswordAuth ? ( + + ) : ( +

Password auth is not allowed.

+ )} + {!workspaceStore.setting.disallowUserRegistration && !workspaceStore.setting.disallowPasswordAuth && (

{"Don't have an account yet?"} diff --git a/frontend/web/src/routers/index.tsx b/frontend/web/src/routers/index.tsx index 55abccd..87167c7 100644 --- a/frontend/web/src/routers/index.tsx +++ b/frontend/web/src/routers/index.tsx @@ -1,6 +1,7 @@ import { createBrowserRouter } from "react-router-dom"; import App from "@/App"; import Root from "@/layouts/Root"; +import AdminSignIn from "@/pages/AdminSignIn"; import AuthCallback from "@/pages/AuthCallback"; import CollectionDashboard from "@/pages/CollectionDashboard"; import CollectionSpace from "@/pages/CollectionSpace"; @@ -27,6 +28,10 @@ const router = createBrowserRouter([ path: "", element: , }, + { + path: "admin", + element: , + }, { path: "signup", element: ,