refactor: register page

This commit is contained in:
Tristan Yang
2023-03-02 09:24:42 +08:00
parent be69a9bdac
commit 4c1018dc46
5 changed files with 65 additions and 33 deletions
+5 -1
View File
@@ -78,7 +78,11 @@ export const authApi = createApi({
query: (data) => ({ query: (data) => ({
url: `user/register`, url: `user/register`,
method: "POST", method: "POST",
body: data body: {
...data,
gender: 0,
device: "browser"
}
}) })
}), }),
// 更新token // 更新token
+2 -3
View File
@@ -18,7 +18,7 @@ const InvitePage: FC = () => {
const { token: loginToken } = useAppSelector((store) => store.authData); const { token: loginToken } = useAppSelector((store) => store.authData);
const [secondPwd, setSecondPwd] = useState(""); const [secondPwd, setSecondPwd] = useState("");
const [samePwd, setSamePwd] = useState(true); const [samePwd, setSamePwd] = useState(true);
const [token, setToken] = useState<string | null>(""); const [token, setToken] = useState<string | undefined>();
const [valid, setValid] = useState(false); const [valid, setValid] = useState(false);
const [register, { data, isLoading, isSuccess, isError, error }] = useRegisterMutation(); const [register, { data, isLoading, isSuccess, isError, error }] = useRegisterMutation();
const [checkToken, { data: isValid, isLoading: checkLoading, isSuccess: checkSuccess }] = const [checkToken, { data: isValid, isLoading: checkLoading, isSuccess: checkSuccess }] =
@@ -26,7 +26,7 @@ const InvitePage: FC = () => {
useEffect(() => { useEffect(() => {
const query = new URLSearchParams(location.search); const query = new URLSearchParams(location.search);
setToken(query.get("token")); setToken(query.get("token") ?? undefined);
}, []); }, []);
useEffect(() => { useEffect(() => {
@@ -54,7 +54,6 @@ const InvitePage: FC = () => {
register({ register({
...input, ...input,
magic_token: token, magic_token: token,
gender: 1
}); });
}; };
+49 -18
View File
@@ -1,48 +1,49 @@
import { useState, useEffect, ChangeEvent, FormEvent } from "react"; import { useState, useEffect, ChangeEvent, FormEvent } from "react";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import BASE_URL, { KEY_LOCAL_MAGIC_TOKEN } from "../../app/config"; import BASE_URL, { KEY_LOCAL_MAGIC_TOKEN } from "../../app/config";
import Input from "../../common/component/styled/Input"; import Input from "../../common/component/styled/Input";
import Button from "../../common/component/styled/Button"; import Button from "../../common/component/styled/Button";
import { useLazyCheckEmailQuery, useSendRegMagicLinkMutation } from "../../app/services/auth"; import { useLazyCheckEmailQuery, useRegisterMutation, useSendRegMagicLinkMutation } from "../../app/services/auth";
import EmailNextTip from "./EmailNextStepTip"; import EmailNextTip from "./EmailNextStepTip";
import SignInLink from "./SignInLink"; import SignInLink from "./SignInLink";
import Divider from "../../common/component/Divider"; import Divider from "../../common/component/Divider";
import { useTranslation } from "react-i18next";
import { useGetLoginConfigQuery } from "../../app/services/server"; import { useGetLoginConfigQuery } from "../../app/services/server";
import SocialLoginButtons from "../login/SocialLoginButtons"; import SocialLoginButtons from "../login/SocialLoginButtons";
import { setAuthData } from "../../app/slices/auth.data";
import { useDispatch } from "react-redux";
interface AuthForm { interface AuthForm {
name?: string,
email: string; email: string;
password: string; password: string;
confirmPassword: string; confirmPassword: string;
} }
export default function Reg() { export default function Register() {
const { t } = useTranslation("auth"); const { t } = useTranslation("auth");
const { t: ct } = useTranslation();
const [sendRegMagicLink, { isLoading: signingUp, data, isSuccess }] = const [sendRegMagicLink, { isLoading: signingUp, data, isSuccess }] =
useSendRegMagicLinkMutation(); useSendRegMagicLinkMutation();
const dispatch = useDispatch();
const [register, { isLoading: registering, data: regData, isSuccess: regSuccess }] = useRegisterMutation();
const [checkEmail, { isLoading: checkingEmail }] = useLazyCheckEmailQuery(); const [checkEmail, { isLoading: checkingEmail }] = useLazyCheckEmailQuery();
const { data: loginConfig, isSuccess: loginConfigSuccess } = useGetLoginConfigQuery(); const { data: loginConfig, isSuccess: loginConfigSuccess } = useGetLoginConfigQuery();
// const navigateTo = useNavigate(); // const navigateTo = useNavigate();
const [magicToken, setMagicToken] = useState("");
const [input, setInput] = useState<AuthForm>({ const [input, setInput] = useState<AuthForm>({
email: "", email: "",
password: "", password: "",
confirmPassword: "" confirmPassword: ""
}); });
useEffect(() => {
const query = new URLSearchParams(location.search); const query = new URLSearchParams(location.search);
const token = query.get("magic_token"); const magic_token = query.get("magic_token") ?? undefined;
if (token) { if (magic_token) {
//本地存一下 magic token 后续oauth流程用到 //本地存一下 magic token 后续oauth流程用到
localStorage.setItem(KEY_LOCAL_MAGIC_TOKEN, token); localStorage.setItem(KEY_LOCAL_MAGIC_TOKEN, magic_token);
setMagicToken(token);
} }
}, []); // send reg link
useEffect(() => { useEffect(() => {
if (isSuccess && data) { if (isSuccess && data) {
const { new_magic_token, mail_is_sent } = data; const { new_magic_token, mail_is_sent } = data;
@@ -52,21 +53,40 @@ export default function Reg() {
} }
} }
}, [isSuccess, data]); }, [isSuccess, data]);
// register
useEffect(() => {
if (regSuccess && regData) {
// 更新本地认证信息
toast.success(ct("tip.reg"));
dispatch(setAuthData(regData));
// tricky
location.href = `/#/`;
}
}, [regSuccess, regData]);
const handleReg = async (evt: FormEvent<HTMLFormElement>) => { const handleReg = async (evt: FormEvent<HTMLFormElement>) => {
evt.preventDefault(); evt.preventDefault();
const { email, password, confirmPassword } = input; const { name, email, password, confirmPassword } = input;
if (password !== confirmPassword) { if (password !== confirmPassword) {
toast.error("Not Same Password!"); toast.error("Not Same Password!");
return; return;
} }
const { data: canReg } = await checkEmail(email); const { data: canReg } = await checkEmail(email);
if (canReg) { if (canReg) {
if (magic_token) {
sendRegMagicLink({ sendRegMagicLink({
magic_token: magicToken, magic_token,
email, email,
password password
}); });
} else {
// 带用户名的注册
register({
name,
email,
password
});
}
} else { } else {
toast.error("Email already registered!"); toast.error("Email already registered!");
} }
@@ -93,12 +113,12 @@ export default function Reg() {
who_can_sign_up: whoCanSignUp who_can_sign_up: whoCanSignUp
} = loginConfig; } = loginConfig;
// magic token 没有并且没有开放注册 // magic token 没有并且没有开放注册
if (whoCanSignUp !== "EveryOne" && !magicToken) if (whoCanSignUp !== "EveryOne" && !magic_token)
// todo: i18n // todo: i18n
return <>Sign up method is updated to Invitation Link Only</>; return <>Sign up method is updated to Invitation Link Only</>;
const { email, password, confirmPassword } = input; const { name, email, password, confirmPassword } = input;
if (data?.mail_is_sent) return <EmailNextTip />; if (data?.mail_is_sent) return <EmailNextTip />;
const isLoading = signingUp || checkingEmail; const isLoading = registering || signingUp || checkingEmail;
return ( return (
<> <>
@@ -109,6 +129,17 @@ export default function Reg() {
</div> </div>
<form className="flex flex-col gap-5 w-80 md:min-w-[360px]" onSubmit={handleReg} autoSave={"false"} autoComplete={"true"}> <form className="flex flex-col gap-5 w-80 md:min-w-[360px]" onSubmit={handleReg} autoSave={"false"} autoComplete={"true"}>
{/* 不存在 magic token */}
{!magic_token && <Input
className="large"
name="name"
value={name}
required
type="name"
placeholder={t("placeholder_name")}
data-type="name"
onChange={handleInput}
/>}
<Input <Input
className="large" className="large"
name="email" name="email"
@@ -150,7 +181,7 @@ export default function Reg() {
<div className="flex flex-col gap-3 py-3"> <div className="flex flex-col gap-3 py-3">
<SocialLoginButtons type="register" /> <SocialLoginButtons type="register" />
</div> </div>
<SignInLink token={magicToken} /> <SignInLink token={magic_token} />
</> </>
); );
} }
+2 -2
View File
@@ -48,8 +48,8 @@ export interface UserDTO extends Partial<Pick<User, "name" | "gender" | "languag
export interface UserCreateDTO extends Pick<User, "name" | "gender" | "language" | "email" | "webhook_url" | "is_bot" | "is_admin"> { export interface UserCreateDTO extends Pick<User, "name" | "gender" | "language" | "email" | "webhook_url" | "is_bot" | "is_admin"> {
password: string; password: string;
} }
export interface UserRegDTO extends Pick<User, "name" | "gender" | "language" | "email">, Pick<UserDevice, "device" | "device_token"> { export interface UserRegDTO extends Partial<Pick<User, "name" | "gender" | "language" | "email">>, Partial<Pick<UserDevice, "device" | "device_token">> {
password: string; password?: string;
magic_token?: string magic_token?: string
} }
export interface UserRegResponse extends AuthToken { export interface UserRegResponse extends AuthToken {
-2
View File
@@ -39,8 +39,6 @@ const Login = () => {
name: `${name}-[${from}]`, name: `${name}-[${from}]`,
email, email,
password: email, password: email,
gender: 0,
device: "unknown"
}); });
// const content = new FormData(form).get("prompt") as string; // const content = new FormData(form).get("prompt") as string;
}; };