refactor: search params in reg

This commit is contained in:
Tristan Yang
2023-03-16 21:13:02 +08:00
parent 5726dcd239
commit 3fd8963f1e
8 changed files with 15 additions and 198 deletions
-2
View File
@@ -18,7 +18,6 @@ const UsersPage = lazy(() => import("./users"));
const CallbackPage = lazy(() => import("./callback"));
const FavoritesPage = lazy(() => import("./favs"));
const OnboardingPage = lazy(() => import("./onboarding"));
const InvitePage = lazy(() => import("./invite"));
const SettingChannelPage = lazy(() => import("./settingChannel"));
const SettingDMPage = lazy(() => import("./settingDM"));
const SettingPage = lazy(() => import("./setting"));
@@ -107,7 +106,6 @@ const PageRoutes = () => {
</LazyIt>
}
/>
<Route path="/invite" element={<LazyIt><InvitePage /></LazyIt>} />
<Route path="/onboarding" element={<LazyIt><OnboardingPage /></LazyIt>} />
<Route
-178
View File
@@ -1,178 +0,0 @@
import { useState, useEffect, FormEvent, ChangeEvent, FC } from "react";
import { Navigate } from "react-router-dom";
import toast from "react-hot-toast";
import BASE_URL from "../../app/config";
import { useRegisterMutation } from "../../app/services/auth";
import { useCheckMagicTokenValidMutation } from "../../app/services/auth";
import { useAppSelector } from "../../app/store";
import StyledButton from "../../common/component/styled/Button";
import Input from "../../common/component/styled/Input";
interface AuthForm {
name: string;
email: string;
password: string;
}
const InvitePage: FC = () => {
const { token: loginToken, serverName } = useAppSelector((store) => {
return { token: store.authData.token, serverName: store.server.name };
});
const [secondPwd, setSecondPwd] = useState("");
const [samePwd, setSamePwd] = useState(true);
const [token, setToken] = useState<string | undefined>();
const [valid, setValid] = useState(false);
const [register, { data, isLoading, isSuccess, isError, error }] = useRegisterMutation();
const [checkToken, { data: isValid, isLoading: checkLoading, isSuccess: checkSuccess }] =
useCheckMagicTokenValidMutation();
useEffect(() => {
const query = new URLSearchParams(location.search);
setToken(query.get("token") ?? undefined);
}, []);
useEffect(() => {
if (token) {
checkToken(token);
}
}, [token]);
useEffect(() => {
if (checkSuccess) {
setValid(!!isValid);
} else {
setValid(false);
}
}, [checkSuccess, isValid]);
const [input, setInput] = useState<AuthForm>({ name: "", email: "", password: "" });
const handleReg = (evt: FormEvent<HTMLFormElement>) => {
evt.preventDefault();
if (!samePwd) {
toast.error("two passwords not same");
return;
}
register({
...input,
magic_token: token,
});
};
const handleInput = (evt: ChangeEvent<HTMLInputElement>) => {
const { type } = evt.target.dataset as { type: keyof AuthForm };
const { value } = evt.target;
setInput((prev) => {
prev[type] = value;
return { ...prev };
});
};
const handleSecondPwdInput = (evt: ChangeEvent<HTMLInputElement>) => {
const { value } = evt.target;
setSecondPwd(value);
};
const handlePwdCheck = () => {
if (secondPwd) {
setSamePwd(secondPwd == input.password);
}
};
useEffect(() => {
if (!samePwd) {
toast.error("two passwords not same");
}
}, [samePwd]);
useEffect(() => {
if (isSuccess && data) {
// 去登录
toast.success("register success, login please");
setTimeout(() => {
location.href = `/#/login`;
// navigateTo("/login",);
}, 500);
} else if (isError && error && "data" in error) {
switch (error.status) {
case 400:
toast.error("Register Failed: please check inputs");
break;
case 412:
toast.error("Register Failed: invalid token or expired");
break;
case 409: {
toast.error(`Register Failed: ${error.data?.reason}`);
break;
}
default:
toast.error("Register Failed");
break;
}
}
}, [data, isSuccess, isError, error]);
const { email, password, name } = input;
if (loginToken) return <Navigate replace to="/" />;
if (!token) return <>token not found</>;
if (checkLoading) return <>checking token valid</>;
if (!valid) return <>invite token expires or invalid</>;
return (
<div className="flex-center h-screen dark:bg-gray-700">
<div className="py-8 px-10 shadow-md rounded-xl">
<div className="flex-center flex-col pb-6">
<img src={`${BASE_URL}/resource/organization/logo`} alt="logo" className="w-14 h-14 mb-7 rounded-full" />
<h2 className="font-semibold text-2xl text-gray-800 dark:text-white mb-2">Sign Up to {serverName}</h2>
<span className="text-gray-400 dark:text-gray-100">Please enter your details.</span>
</div>
<form className="flex flex-col gap-5 min-w-[360px]" onSubmit={handleReg}>
<Input
className="large"
name="name"
value={name}
required
placeholder="Enter your name"
data-type="name"
onChange={handleInput}
/>
<Input
className="large"
name="email"
value={email}
required
placeholder="Enter your email"
data-type="email"
onChange={handleInput}
/>
<Input
className="large"
type="password"
value={password}
name="password"
required
data-type="password"
onChange={handleInput}
placeholder="Enter your password"
/>
<Input
className="large"
type="password"
value={secondPwd}
name="password"
required
data-type="password"
onBlur={handlePwdCheck}
onChange={handleSecondPwdInput}
placeholder="Enter your password again"
/>
<StyledButton disabled={isLoading || isSuccess} className="flex justify-center" type="submit">
Sign Up
</StyledButton>
</form>
</div>
</div>
);
};
export default InvitePage;
+2 -2
View File
@@ -2,7 +2,6 @@
import { useState, useEffect, FormEvent, ChangeEvent } from "react";
import toast from "react-hot-toast";
import BASE_URL from "../../app/config";
// import web3 from "web3";
import Input from "../../common/component/styled/Input";
import Button from "../../common/component/styled/Button";
@@ -56,7 +55,8 @@ export default function LoginPage() {
});
} else {
// reg with magic link and set name only
location.href = `?magic_token=${magic_token}#/register/set_name/login`;
// navigate(`/register/set_name/login?magic_token=${magic_token}`);
location.href = `/#/register/set_name/login?magic_token=${magic_token}`;
}
}
}, []);
+5 -5
View File
@@ -1,7 +1,7 @@
import { useState, useEffect, FC, FormEvent, ChangeEvent } from "react";
import { useDispatch } from "react-redux";
import { useTranslation } from "react-i18next";
import { useParams } from "react-router-dom";
import { useParams, useSearchParams } from "react-router-dom";
import toast from "react-hot-toast";
import { setAuthData } from "../../app/slices/auth.data";
import Input from "../../common/component/styled/Input";
@@ -13,6 +13,7 @@ import { useRegisterMutation } from "../../app/services/auth";
const RegWithUsername: FC = () => {
const { t: ct } = useTranslation();
const { t } = useTranslation("auth");
const [searchParams] = useSearchParams();
const [checkTokenInvalid, { data: isTokenValid, isLoading: checkingToken }] =
useCheckMagicTokenValidMutation();
const [
@@ -27,9 +28,8 @@ const RegWithUsername: FC = () => {
const { from = "reg" } = useParams();
const dispatch = useDispatch();
const [username, setUsername] = useState("");
const query = new URLSearchParams(location.search);
// todo: check if query param exists
const token = query.get("magic_token") as string;
const token = searchParams.get("magic_token") as string;
useEffect(() => {
if (token) {
checkTokenInvalid(token);
@@ -92,8 +92,8 @@ const RegWithUsername: FC = () => {
setUsername(evt.target.value);
};
if (!token) return <>"No Token"</>;
if (checkingToken) return <div className="dark:text-gray-100">"Checking Magic Link..."</div>;
if (!token) return <span className="dark:text-white">No Token</span>;
if (checkingToken) return <div className="dark:text-gray-100">Checking Magic Link...</div>;
if (!isTokenValid) return <ExpiredTip />;
const isLoading = loginLoading || regLoading;
const isSuccess = loginSuccess || regSuccess;
+4 -3
View File
@@ -1,6 +1,7 @@
import { useState, useEffect, ChangeEvent, FormEvent } from "react";
import toast from "react-hot-toast";
import { useTranslation } from "react-i18next";
import { useSearchParams } from "react-router-dom";
import BASE_URL, { KEY_LOCAL_MAGIC_TOKEN } from "../../app/config";
import Input from "../../common/component/styled/Input";
import Button from "../../common/component/styled/Button";
@@ -26,6 +27,7 @@ export default function Register() {
const serverName = useAppSelector(store => store.server.name);
const { t } = useTranslation("auth");
const { t: ct } = useTranslation();
let [searchParams] = useSearchParams();
const [sendRegMagicLink, { isLoading: signingUp, data, isSuccess }] =
useSendRegMagicLinkMutation();
const dispatch = useDispatch();
@@ -40,8 +42,7 @@ export default function Register() {
password: "",
confirmPassword: ""
});
const query = new URLSearchParams(location.search);
const magic_token = query.get("magic_token") ?? undefined;
const magic_token = searchParams.get("magic_token") ?? undefined;
if (magic_token) {
//本地存一下 magic token 后续oauth流程用到
localStorage.setItem(KEY_LOCAL_MAGIC_TOKEN, magic_token);
@@ -118,7 +119,7 @@ export default function Register() {
// magic token 没有并且没有开放注册
if (whoCanSignUp !== "EveryOne" && !magic_token)
// todo: i18n
return <>Sign up method is updated to Invitation Link Only</>;
return <span className="dark:text-white">Sign up method is updated to Invitation Link Only</span>;
const { name, email, password, confirmPassword } = input;
if (data?.mail_is_sent) return <EmailNextTip />;
const isLoading = registering || signingUp || checkingEmail;
-5
View File
@@ -1,11 +1,6 @@
import { useEffect } from "react";
import { Outlet } from "react-router-dom";
export default function RegContainer() {
useEffect(() => {
// 重新组织url
location.href = `${location.origin}${location.hash}${location.search}`;
}, [location]);
return (
<div className="flex-center h-screen overflow-x-hidden overflow-y-auto dark:bg-gray-700">