refactor: register page
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 {
|
||||||
|
|||||||
@@ -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;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user