/* eslint-disable no-undef */ import { ChangeEvent, FormEvent, useEffect, useState } from "react"; import toast from "react-hot-toast"; import { useTranslation } from "react-i18next"; import { FetchBaseQueryError } from "@reduxjs/toolkit/dist/query"; import BASE_URL from "@/app/config"; import { useLoginMutation } from "@/app/services/auth"; import { useGetLoginConfigQuery, useGetSMTPStatusQuery } from "@/app/services/server"; import { useAppSelector } from "@/app/store"; import Divider from "@/components/Divider"; import Button from "@/components/styled/Button"; import Input from "@/components/styled/Input"; import StyledLabel from "@/components/styled/Label"; import IconBack from "@/assets/icons/arrow.left.svg"; import MagicLinkLogin from "./MagicLinkLogin"; import SignUpLink from "./SignUpLink"; import SocialLoginButtons from "./SocialLoginButtons"; import { shallowEqual } from "react-redux"; const defaultInput = { email: "", password: "" }; export default function LoginPage() { const { name: serverName, logo } = useAppSelector((store) => store.server, shallowEqual); const { t } = useTranslation("auth"); const { t: ct } = useTranslation(); const { data: enableSMTP, isLoading: loadingSMTPStatus } = useGetSMTPStatusQuery(); const [login, { isSuccess, isLoading, error }] = useLoginMutation(); const { data: loginConfig, isSuccess: loginConfigSuccess } = useGetLoginConfigQuery(); const [emailInputted, setEmailInputted] = useState(false); const [input, setInput] = useState(defaultInput); useEffect(() => { const query = new URLSearchParams(location.search); const code = query.get("code"); const state = query.get("state"); const magic_token = query.get("magic_token"); const exists = query.get("exists"); // oidc const fromOIDC = code && state; if (fromOIDC) { login({ code, state, type: "oidc" }); } // magic link if (magic_token && typeof exists !== "undefined") { const isLogin = exists == "true"; if (isLogin) { // login login({ magic_token, type: "magiclink" }); } else { // reg with magic link and set name only // navigate(`/register/set_name/login?magic_token=${magic_token}`); location.href = `/#/register/set_name/login?magic_token=${magic_token}`; } } }, []); useEffect(() => { if (error) { switch ((error as FetchBaseQueryError).status) { case 401: case 404: toast.error("Username or Password incorrect"); break; case 410: toast.error( "No associated account found, please contact user admin for an invitation link to join." ); break; // 451 有解析错误,暂时先客户端处理 case "PARSING_ERROR": break; default: toast.error("Something Error"); break; } return; } }, [error]); useEffect(() => { console.log("login success", isSuccess); if (isSuccess) { toast.success(ct("tip.login")); // setInput(defaultInput); // navigateTo("/"); } }, [isSuccess]); const handleLogin = (evt: FormEvent) => { evt.preventDefault(); const enableMagicLink = enableSMTP && loginConfig?.magic_link; if (enableMagicLink && !emailInputted) { setEmailInputted(true); return; } login({ ...input, type: "password" }); }; const handleInput = (evt: ChangeEvent) => { const { type } = evt.target.dataset as { type?: "email" | "password" }; const { value } = evt.target; if (!type) return; const newInput = { ...input, [type]: value }; setInput(newInput); }; const handleBack = () => { setEmailInputted(false); }; const { email, password } = input; if (!loginConfigSuccess) return null; const { magic_link, who_can_sign_up: whoCanSignUp } = loginConfig; const enableMagicLink = enableSMTP && magic_link; const hideSocials = (enableMagicLink && emailInputted) || whoCanSignUp == "InvitationOnly"; const showSignIn = !enableMagicLink || emailInputted; if (loadingSMTPStatus) return null; return (
{emailInputted && ( )}
logo

{t("login.title", { name: serverName })}

{!emailInputted && (
Email
)} {(!enableMagicLink || emailInputted) && (
Password
)} {showSignIn ? ( ) : ( )}
{emailInputted && } {!hideSocials && }
{whoCanSignUp === "EveryOne" && }
); }