refactor: magic link auth

This commit is contained in:
Tristan Yang
2022-06-20 17:41:58 +08:00
parent b25907f7fc
commit b938b6b3aa
17 changed files with 349 additions and 111 deletions
+29 -8
View File
@@ -45,6 +45,13 @@ export const authApi = createApi({
} }
} }
}), }),
register: builder.mutation({
query: (data) => ({
url: `user/register`,
method: "POST",
body: data
})
}),
// 更新token // 更新token
renew: builder.mutation({ renew: builder.mutation({
query: ({ token, refreshToken }) => ({ query: ({ token, refreshToken }) => ({
@@ -87,9 +94,9 @@ export const authApi = createApi({
}) })
}), }),
checkInviteTokenValid: builder.mutation({ checkMagicTokenValid: builder.mutation({
query: (token) => ({ query: (token) => ({
url: "user/check_invite_magic_token", url: "user/check_magic_token",
method: "POST", method: "POST",
body: { magic_token: token } body: { magic_token: token }
}) })
@@ -101,11 +108,23 @@ export const authApi = createApi({
body: { old_password, new_password } body: { old_password, new_password }
}) })
}), }),
sendMagicLink: builder.mutation({ sendLoginMagicLink: builder.mutation({
query: (email) => ({ query: (email) => ({
url: "token/send_magic_link", headers: {
// "content-type": "text/plain",
accept: "text/plain"
},
url: `user/send_login_magic_link?email=${encodeURIComponent(email)}`,
method: "POST", method: "POST",
body: { email } responseHandler: (response) => response.text()
// body: { email }
})
}),
sendRegMagicLink: builder.mutation({
query: (data) => ({
url: `user/send_reg_magic_link`,
method: "POST",
body: data
}) })
}), }),
getMetamaskNonce: builder.query({ getMetamaskNonce: builder.query({
@@ -147,7 +166,8 @@ export const authApi = createApi({
export const { export const {
useGetInitializedQuery, useGetInitializedQuery,
useSendMagicLinkMutation, useSendLoginMagicLinkMutation,
useSendRegMagicLinkMutation,
useGetCredentialsQuery, useGetCredentialsQuery,
useUpdateDeviceTokenMutation, useUpdateDeviceTokenMutation,
useGetOpenidMutation, useGetOpenidMutation,
@@ -155,6 +175,7 @@ export const {
useLazyGetMetamaskNonceQuery, useLazyGetMetamaskNonceQuery,
useLoginMutation, useLoginMutation,
useLazyLogoutQuery, useLazyLogoutQuery,
useCheckInviteTokenValidMutation, useCheckMagicTokenValidMutation,
useUpdatePasswordMutation useUpdatePasswordMutation,
useRegisterMutation
} = authApi; } = authApi;
+3 -2
View File
@@ -6,8 +6,9 @@ import BASE_URL, { tokenHeader } from "../config";
const whiteList = [ const whiteList = [
"login", "login",
"register", "register",
"sendMagicLink", "sendLoginMagicLink",
"checkInviteTokenValid", "sendRegMagicLink",
"checkMagicTokenValid",
"getGoogleAuthConfig", "getGoogleAuthConfig",
"getGithubAuthConfig", "getGithubAuthConfig",
"getSMTPStatus", "getSMTPStatus",
+2 -9
View File
@@ -89,13 +89,7 @@ export const contactApi = createApi({
body: data body: data
}) })
}), }),
register: builder.mutation({
query: (data) => ({
url: `user/register`,
method: "POST",
body: data
})
}),
sendMsg: builder.mutation({ sendMsg: builder.mutation({
query: ({ id, content, type = "text", properties = "" }) => ({ query: ({ id, content, type = "text", properties = "" }) => ({
headers: { headers: {
@@ -139,6 +133,5 @@ export const {
useUpdateAvatarMutation, useUpdateAvatarMutation,
useGetContactsQuery, useGetContactsQuery,
useLazyGetContactsQuery, useLazyGetContactsQuery,
useSendMsgMutation, useSendMsgMutation
useRegisterMutation
} = contactApi; } = contactApi;
@@ -1,7 +1,23 @@
// import { useState, useEffect } from "react"; // import { useState, useEffect } from "react";
// import { useGoogleLogin } from "react-google-login"; // import { useGoogleLogin } from "react-google-login";
import IconGithub from "../../assets/icons/github.svg"; import IconGithub from "../../assets/icons/github.svg";
import { StyledSocialButton } from "./styled"; import styled from "styled-components";
import Button from "./styled/Button";
const StyledSocialButton = styled(Button)`
width: 100%;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
color: #344054;
border: 1px solid #d0d5dd;
background: none !important;
.icon {
width: 24px;
height: 24px;
}
`;
export default function GithubLoginButton({ config = {} }) { export default function GithubLoginButton({ config = {} }) {
const { client_id } = config; const { client_id } = config;
const handleGithubLogin = () => { const handleGithubLogin = () => {
+58
View File
@@ -0,0 +1,58 @@
import { useEffect } from "react";
import { useGoogleLogin } from "react-google-login";
import googleSvg from "../../assets/icons/google.svg?url";
import styled from "styled-components";
import Button from "./styled/Button";
import { useLoginMutation } from "../../app/services/auth";
import toast from "react-hot-toast";
const StyledSocialButton = styled(Button)`
width: 100%;
margin-bottom: 16px;
display: flex;
align-items: center;
justify-content: center;
gap: 12px;
color: #344054;
border: 1px solid #d0d5dd;
background: none !important;
.icon {
width: 24px;
height: 24px;
}
`;
export default function GoogleLoginButton({ clientId }) {
const [login, { isSuccess, isLoading }] = useLoginMutation();
const { signIn, loaded } = useGoogleLogin({
onScriptLoadFailure: (wtf) => {
console.error("google login script load failure", wtf);
},
clientId,
onSuccess: ({ tokenId, ...rest }) => {
console.info("google oauth success", tokenId, rest);
login({
id_token: tokenId,
type: "google"
});
},
onFailure: (wtf) => {
console.error("google login failure", wtf);
}
});
useEffect(() => {
if (isSuccess) {
toast.success("Login Successfully");
// navigateTo("/");
}
}, [isSuccess]);
const handleGoogleLogin = () => {
signIn();
};
// console.log("google login ", loaded);
return (
<StyledSocialButton disabled={!loaded || isLoading} onClick={handleGoogleLogin}>
<img className="icon" src={googleSvg} alt="google icon" />
{loaded ? `Sign in with Google` : `Initailizing`}
</StyledSocialButton>
);
}
+2 -2
View File
@@ -75,9 +75,9 @@ const PageRoutes = () => {
} }
> >
<Route index element={<RegPage />} /> <Route index element={<RegPage />} />
<Route path="magiclink"> <Route path="set_name">
<Route index element={<RegWithUsernamePage />} /> <Route index element={<RegWithUsernamePage />} />
<Route path=":token" element={<RegWithUsernamePage />} /> <Route path=":from" element={<RegWithUsernamePage />} />
</Route> </Route>
</Route> </Route>
<Route <Route
+3 -3
View File
@@ -3,8 +3,8 @@ import StyledWrapper from "./styled";
import { Navigate } from "react-router-dom"; import { Navigate } from "react-router-dom";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import BASE_URL from "../../app/config"; import BASE_URL from "../../app/config";
import { useRegisterMutation } from "../../app/services/contact"; import { useRegisterMutation } from "../../app/services/auth";
import { useCheckInviteTokenValidMutation } from "../../app/services/auth"; import { useCheckMagicTokenValidMutation } from "../../app/services/auth";
import { useSelector } from "react-redux"; import { useSelector } from "react-redux";
export default function InvitePage() { export default function InvitePage() {
@@ -17,7 +17,7 @@ export default function InvitePage() {
// const navigateTo = useNavigate(); // const navigateTo = useNavigate();
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 }] =
useCheckInviteTokenValidMutation(); useCheckMagicTokenValidMutation();
useEffect(() => { useEffect(() => {
// console.log(search); // console.log(search);
const query = new URLSearchParams(location.search); const query = new URLSearchParams(location.search);
-33
View File
@@ -1,33 +0,0 @@
// import { useState, useEffect } from "react";
import { useGoogleLogin } from "react-google-login";
import googleSvg from "../../assets/icons/google.svg?url";
import { StyledSocialButton } from "./styled";
export default function GoogleLoginButton({ login, clientId }) {
const { signIn, loaded } = useGoogleLogin({
onScriptLoadFailure: (wtf) => {
console.error("google login script load failure", wtf);
},
clientId,
onSuccess: ({ tokenId, ...rest }) => {
console.info("google oauth success", tokenId, rest);
login({
id_token: tokenId,
type: "google"
});
},
onFailure: (wtf) => {
console.error("google login failure", wtf);
}
});
const handleGoogleLogin = () => {
signIn();
};
// console.log("google login ", loaded);
return (
<StyledSocialButton disabled={!loaded} onClick={handleGoogleLogin}>
<img className="icon" src={googleSvg} alt="google icon" />
{loaded ? `Sign in with Google` : `Initailizing`}
</StyledSocialButton>
);
}
+1 -1
View File
@@ -24,7 +24,7 @@ const StyledSignUpLink = styled.p`
export default function MagicLinkLogin() { export default function MagicLinkLogin() {
const navigate = useNavigate(); const navigate = useNavigate();
const handleSignUp = () => { const handleSignUp = () => {
navigate("/"); navigate("/register");
}; };
return ( return (
<StyledSignUpLink> <StyledSignUpLink>
+9 -9
View File
@@ -8,14 +8,14 @@ import MetamaskLoginButton from "./MetamaskLoginButton";
import OidcLoginButton from "./OidcLoginButton"; import OidcLoginButton from "./OidcLoginButton";
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 GoogleLoginButton from "./GoogleLoginButton";
import MagicLinkLogin from "./MagicLinkLogin"; import MagicLinkLogin from "./MagicLinkLogin";
import SignUpLink from "./SignUpLink"; import SignUpLink from "./SignUpLink";
import { useLoginMutation } from "../../app/services/auth"; import { useLoginMutation } from "../../app/services/auth";
import { useGetLoginConfigQuery, useGetSMTPStatusQuery } from "../../app/services/server"; import { useGetLoginConfigQuery, useGetSMTPStatusQuery } from "../../app/services/server";
import useGoogleAuthConfig from "../../common/hook/useGoogleAuthConfig"; import useGoogleAuthConfig from "../../common/hook/useGoogleAuthConfig";
import GithubLoginButton from "./GithubLoginButton";
import useGithubAuthConfig from "../../common/hook/useGithubAuthConfig"; import useGithubAuthConfig from "../../common/hook/useGithubAuthConfig";
import GoogleLoginButton from "../../common/component/GoogleLoginButton";
import GithubLoginButton from "../../common/component/GithubLoginButton";
export default function LoginPage() { export default function LoginPage() {
const { data: enableSMTP } = useGetSMTPStatusQuery(); const { data: enableSMTP } = useGetSMTPStatusQuery();
const [login, { isSuccess, isLoading, error }] = useLoginMutation(); const [login, { isSuccess, isLoading, error }] = useLoginMutation();
@@ -32,7 +32,7 @@ export default function LoginPage() {
const oauth = query.get("oauth"); const oauth = query.get("oauth");
const code = query.get("code"); const code = query.get("code");
const state = query.get("state"); const state = query.get("state");
const token = query.get("token"); const magic_token = query.get("magic_token");
const exists = query.get("exists"); const exists = query.get("exists");
if (oauth) { if (oauth) {
switch (oauth) { switch (oauth) {
@@ -58,18 +58,18 @@ export default function LoginPage() {
} }
} }
// magic link // magic link
if (token && typeof exists !== "undefined") { if (magic_token && typeof exists !== "undefined") {
console.log("tokken", token, exists); // console.log("tokken", token, exists);
const isLogin = exists == "true"; const isLogin = exists == "true";
if (isLogin) { if (isLogin) {
// login // login
login({ login({
token, magic_token,
type: "magiclink" type: "magiclink"
}); });
} else { } else {
// reg // reg with magic link and set name only
location.href = `/#/reg/magiclink/${token}`; location.href = `?magic_token=${magic_token}#/register/set_name/login`;
} }
} }
}, []); }, []);
@@ -167,7 +167,7 @@ export default function LoginPage() {
</form> </form>
{hasDivider && <hr className="or" />} {hasDivider && <hr className="or" />}
{enableMagicLink && <MagicLinkLogin />} {enableMagicLink && <MagicLinkLogin />}
{googleLogin && <GoogleLoginButton login={login} clientId={clientId} />} {googleLogin && <GoogleLoginButton clientId={clientId} />}
{enableGithubLogin && <GithubLoginButton config={githubAuthConfig} />} {enableGithubLogin && <GithubLoginButton config={githubAuthConfig} />}
{enableMetamaskLogin && <MetamaskLoginButton login={login} />} {enableMetamaskLogin && <MetamaskLoginButton login={login} />}
{oidc.length > 0 && <OidcLoginButton issuers={oidc} />} {oidc.length > 0 && <OidcLoginButton issuers={oidc} />}
+33
View File
@@ -0,0 +1,33 @@
// import React from "react";
import styled from "styled-components";
const Styled = styled.div`
display: flex;
flex-direction: column;
align-items: center;
.title {
font-weight: 600;
font-size: 30px;
line-height: 38px;
color: #101828;
margin-bottom: 12px;
}
.desc {
text-align: center;
font-weight: 400;
font-size: 16px;
line-height: 24px;
color: #667085;
&:not(:last-child) {
margin-bottom: 24px;
}
}
`;
export default function EmailNextTip() {
return (
<Styled>
<div className="title">Magic link Sent</div>
<p className="desc">Login to your email client, and continue next step</p>
<p className="desc">You can close this window now.</p>
</Styled>
);
}
+30 -15
View File
@@ -1,25 +1,30 @@
/* eslint-disable no-undef */ /* eslint-disable no-undef */
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { useDispatch } from "react-redux"; import { useDispatch } from "react-redux";
// import { useNavigate } from "react-router-dom";
// import toast from "react-hot-toast";
import { useParams } from "react-router-dom"; import { useParams } from "react-router-dom";
import { setAuthData } from "../../app/slices/auth.data"; import { setAuthData } from "../../app/slices/auth.data";
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 { useLoginMutation, useCheckInviteTokenValidMutation } from "../../app/services/auth"; import { useLoginMutation, useCheckMagicTokenValidMutation } from "../../app/services/auth";
import toast from "react-hot-toast"; import toast from "react-hot-toast";
import ExpiredTip from "./ExpiredTip"; import ExpiredTip from "./ExpiredTip";
import { useRegisterMutation } from "../../app/services/auth";
export default function RegWithUsername() { export default function RegWithUsername() {
const { token } = useParams();
const [checkTokenInvalid, { data: isTokenValid, isLoading: checkingToken }] = const [checkTokenInvalid, { data: isTokenValid, isLoading: checkingToken }] =
useCheckInviteTokenValidMutation(); useCheckMagicTokenValidMutation();
const [login, { isLoading, error, isSuccess, data }] = useLoginMutation(); const [login, { isLoading: loginLoading, error, isSuccess: loginSuccess, data: loginData }] =
useLoginMutation();
const [register, { isLoading: regLoading, isSuccess: regSuccess, data: regData }] =
useRegisterMutation();
// const navigateTo = useNavigate(); // const navigateTo = useNavigate();
const { from = "reg" } = useParams();
const dispatch = useDispatch(); const dispatch = useDispatch();
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const query = new URLSearchParams(location.search);
// const githubCode = query.get("gcode");
const token = query.get("magic_token");
useEffect(() => { useEffect(() => {
if (token) { if (token) {
checkTokenInvalid(token); checkTokenInvalid(token);
@@ -38,32 +43,42 @@ export default function RegWithUsername() {
} }
}, [error]); }, [error]);
useEffect(() => { useEffect(() => {
const isSuccess = loginSuccess || regSuccess;
const data = loginData || regData;
if (isSuccess && data) { if (isSuccess && data) {
// 更新本地认证信息 // 更新本地认证信息
console.log("login data", data);
toast.success("Login Successfully"); toast.success("Login Successfully");
dispatch(setAuthData(data)); dispatch(setAuthData(data));
// tricky
location.href = `/#/`; location.href = `/#/`;
} }
}, [isSuccess, data]); }, [loginSuccess, regSuccess, loginData, regData]);
const handleLogin = (evt) => { const handleAuth = (evt) => {
evt.preventDefault(); evt.preventDefault();
if (from == "reg") {
register({
magic_token: token,
name: username
});
} else {
login({ login({
token, magic_token: token,
username, extra_name: username,
type: "magiclink" type: "magiclink"
}); });
// sendMagicLink(email); }
}; };
const handleInput = (evt) => { const handleInput = (evt) => {
const { value } = evt.target; const { value } = evt.target;
setUsername(value); setUsername(value);
}; };
if (!token) return "no token"; if (!token) return "No Token";
if (checkingToken) return "checking Magic Link..."; if (checkingToken) return "Checking Magic Link...";
if (!isTokenValid) return <ExpiredTip />; if (!isTokenValid) return <ExpiredTip />;
const isLoading = loginLoading || regLoading;
const isSuccess = loginSuccess || regSuccess;
return ( return (
<> <>
<div className="tips"> <div className="tips">
@@ -73,7 +88,7 @@ export default function RegWithUsername() {
visible to others in spaces you joined. visible to others in spaces you joined.
</span> </span>
</div> </div>
<form onSubmit={handleLogin}> <form onSubmit={handleAuth}>
<Input <Input
className="large" className="large"
name="username" name="username"
+63 -19
View File
@@ -1,42 +1,86 @@
/* eslint-disable no-undef */ import { useState, useEffect } from "react";
import { useState } from "react";
// import { useDispatch } from "react-redux"; // import { useDispatch } from "react-redux";
// import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
// import toast from "react-hot-toast"; // import toast from "react-hot-toast";
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 { useSendMagicLinkMutation } from "../../app/services/auth"; import { useSendRegMagicLinkMutation } from "../../app/services/auth";
import EmailNextTip from "./EmailNextStepTip";
// import { useSendLoginMagicLinkMutation } from "../../app/services/auth";
export default function Reg() { export default function Reg() {
// const [ const [sendRegMagicLink, { isLoading, data, isSuccess }] = useSendRegMagicLinkMutation();
// sendMagicLink, const navigateTo = useNavigate();
// { data, isSuccess, isLoading, error }, const [magicToken, setMagicToken] = useState("");
// ] = useSendMagicLinkMutation(); const [input, setInput] = useState({
// const navigateTo = useNavigate(); email: "",
// const dispatch = useDispatch(); password: "",
const [username, setUsername] = useState(""); confirmPassword: ""
});
useEffect(() => {
const query = new URLSearchParams(location.search);
// const githubCode = query.get("gcode");
const token = query.get("magic_token");
if (token) {
setMagicToken(token);
}
}, []);
useEffect(() => {
if (isSuccess && data) {
const { new_magic_token, mail_is_sent } = data;
if (!mail_is_sent && new_magic_token) {
// 直接进入set_name流程
navigateTo(`?magic_token=${new_magic_token}#/register/set_name`);
}
}
}, [isSuccess, data]);
const handleLogin = (evt) => { const handleReg = (evt) => {
evt.preventDefault(); evt.preventDefault();
const { email, password } = input;
sendRegMagicLink({
magic_token: magicToken,
email,
password
});
// sendMagicLink(email); // sendMagicLink(email);
}; };
const handleInput = (evt) => { const handleInput = (evt) => {
const { type } = evt.target.dataset;
const { value } = evt.target; const { value } = evt.target;
console.log(value); // console.log(type, value);
setUsername(value); setInput((prev) => {
prev[type] = value;
return { ...prev };
});
}; };
const { email, password } = input;
if (data?.mail_is_sent) return <EmailNextTip />;
return ( return (
<form onSubmit={handleLogin}> <form onSubmit={handleReg}>
<Input <Input
className="large" className="large"
name="username" name="email"
value={username} value={email}
required required
placeholder="Enter your Name22" placeholder="Enter your email"
data-type="email"
onChange={handleInput} onChange={handleInput}
/> />
<Button type="submit">{isLoading ? "Sending" : `Register`}</Button> <Input
className="large"
type="password"
value={password}
name="password"
required
data-type="password"
onChange={handleInput}
placeholder="Enter your password"
/>
<Button type="submit" disabled={isLoading}>
{isLoading ? "Signing Up" : `Sign Up`}
</Button>
</form> </form>
); );
} }
+34
View File
@@ -0,0 +1,34 @@
import styled from "styled-components";
import { useNavigate } from "react-router-dom";
const StyledSignInLink = styled.p`
text-align: center;
margin: 24px 0 8px;
> span {
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #667085;
margin-right: 4px;
}
> a {
font-weight: 500;
font-size: 14px;
line-height: 20px;
color: #22d3ee;
cursor: pointer;
}
`;
export default function SignInLink() {
const navigate = useNavigate();
const handleSignIn = () => {
navigate("/login");
};
return (
<StyledSignInLink>
<span>Have an account?</span>
<a onClick={handleSignIn}>Sign In</a>
</StyledSignInLink>
);
}
+38 -1
View File
@@ -1,12 +1,49 @@
/* eslint-disable no-undef */
import { Outlet } from "react-router-dom"; import { Outlet } from "react-router-dom";
import { useMatch } from "react-router-dom";
import BASE_URL from "../../app/config";
import SignInLink from "./SignInLink";
import { useGetLoginConfigQuery } from "../../app/services/server";
import useGithubAuthConfig from "../../common/hook/useGithubAuthConfig";
import useGoogleAuthConfig from "../../common/hook/useGoogleAuthConfig";
import GoogleLoginButton from "../../common/component/GoogleLoginButton";
import GithubLoginButton from "../../common/component/GithubLoginButton";
import StyledWrapper from "./styled"; import StyledWrapper from "./styled";
export default function Reg() { export default function Reg() {
const isRegHome = useMatch(`/register`);
const { clientId } = useGoogleAuthConfig();
const { config: githubAuthConfig } = useGithubAuthConfig();
const { data: loginConfig, isSuccess: loginConfigSuccess } = useGetLoginConfigQuery();
if (!loginConfigSuccess) return null;
const {
github: enableGithubLogin,
google: enableGoogleLogin,
who_can_sign_up: whoCanSignUp
} = loginConfig;
const googleLogin = enableGoogleLogin && clientId;
// 没有开放注册
if (whoCanSignUp !== "EveryOne") return `Open Register is Closed!`;
return ( return (
<StyledWrapper> <StyledWrapper>
<div className="form"> <div className="form">
{isRegHome && (
<>
<div className="tips">
<img src={`${BASE_URL}/resource/organization/logo`} alt="logo" className="logo" />
<h2 className="title">Sign Up to Rustchat</h2>
<span className="desc">Please enter your details.</span>
</div>
</>
)}
<Outlet /> <Outlet />
{isRegHome && (
<>
<hr className="or" />
{googleLogin && <GoogleLoginButton clientId={clientId} />}
{enableGithubLogin && <GithubLoginButton config={githubAuthConfig} />}
<SignInLink />
</>
)}
</div> </div>
</StyledWrapper> </StyledWrapper>
); );
+19
View File
@@ -45,6 +45,25 @@ const StyledWrapper = styled.div`
width: 360px; width: 360px;
} }
} }
.or {
border: none;
position: relative;
height: 1px;
background-color: #e4e7ec;
margin: 26px 0;
&:after {
padding: 4px;
background-color: #fff;
content: "OR";
position: absolute;
left: 50%;
top: 50%;
transform: translate3d(-50%, -50%, 0);
font-size: 14px;
line-height: 20px;
color: #667085;
}
}
`; `;
export default StyledWrapper; export default StyledWrapper;
+5 -5
View File
@@ -7,12 +7,12 @@ import BASE_URL from "../../app/config";
import StyledWrapper from "./styled"; import StyledWrapper from "./styled";
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 { useSendMagicLinkMutation } from "../../app/services/auth"; import { useSendLoginMagicLinkMutation } from "../../app/services/auth";
import SentTip from "./SentTip"; import SentTip from "./SentTip";
export default function SendMagicLinkPage() { export default function SendMagicLinkPage() {
const [sent, setSent] = useState(false); const [sent, setSent] = useState(false);
const [sendMagicLink, { isSuccess, isLoading, error }] = useSendMagicLinkMutation(); const [sendMagicLink, { isSuccess, isLoading, error }] = useSendLoginMagicLinkMutation();
const navigateTo = useNavigate(); const navigateTo = useNavigate();
// const dispatch = useDispatch(); // const dispatch = useDispatch();
@@ -32,13 +32,13 @@ export default function SendMagicLinkPage() {
toast.error(error.data); toast.error(error.data);
break; break;
case 401: case 401:
toast.error("username or password incorrect"); toast.error("Username or Password Incorrect");
break; break;
case 404: case 404:
toast.error("account not exsit"); toast.error("Account not exsit");
break; break;
default: default:
toast.error("something error"); toast.error("Something Error");
break; break;
} }
return; return;