Skip to content

Commit 8a2642e

Browse files
committed
Add forget password functionality
1 parent 28394d1 commit 8a2642e

File tree

4 files changed

+115
-1
lines changed

4 files changed

+115
-1
lines changed

frontend/src/App.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import Landing from "./pages/Landing";
1010
import Home from "./pages/Home";
1111
import SignUp from "./pages/SignUp";
1212
import LogIn from "./pages/LogIn";
13+
import ForgetPassword from "./pages/ForgetPassword";
1314
import Matched from "./pages/Matched";
1415
import Timeout from "./pages/Timeout";
1516
import ProtectedRoutes from "./components/ProtectedRoutes";
@@ -52,6 +53,7 @@ function App() {
5253
</Route>
5354
<Route path="signup" element={<SignUp />} />
5455
<Route path="login" element={<LogIn />} />
56+
<Route path="forget-password" element={<ForgetPassword />} />
5557
</Routes>
5658
</AuthProvider>
5759
);

frontend/src/contexts/AuthContext.tsx

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ type AuthContextType = {
2929
) => void;
3030
login: (email: string, password: string) => void;
3131
logout: () => void;
32+
resetPassword: (email: string) => void;
3233
user: User | null;
3334
setUser: React.Dispatch<React.SetStateAction<User | null>>;
3435
loading: boolean;
@@ -107,12 +108,20 @@ const AuthProvider: React.FC<{ children?: React.ReactNode }> = (props) => {
107108
toast.success(SUCCESS_LOG_OUT);
108109
};
109110

111+
const resetPassword = (email: string) => {
112+
userClient.post("/users/reset-password", { email }).then(() => {
113+
toast.success("Reset link sent to your email");
114+
});
115+
};
116+
110117
if (loading) {
111118
return <Loader />;
112119
}
113120

114121
return (
115-
<AuthContext.Provider value={{ signup, login, logout, user, setUser, loading }}>
122+
<AuthContext.Provider
123+
value={{ signup, login, logout, user, setUser, resetPassword, loading }}
124+
>
116125
{children}
117126
</AuthContext.Provider>
118127
);
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
import { Box, Button, Stack, TextField, Typography } from "@mui/material";
2+
import LogInSvg from "../../assets/login.svg?react";
3+
import { useAuth } from "../../contexts/AuthContext";
4+
import { emailValidator } from "../../utils/validators";
5+
import { ToastContainer } from "react-toastify";
6+
import "react-toastify/dist/ReactToastify.css";
7+
import { useForm } from "react-hook-form";
8+
import { USE_AUTH_ERROR_MESSAGE } from "../../utils/constants";
9+
10+
const ForgetPassword: React.FC = () => {
11+
const auth = useAuth();
12+
if (!auth) {
13+
throw new Error(USE_AUTH_ERROR_MESSAGE);
14+
}
15+
const { resetPassword } = auth;
16+
17+
const {
18+
register,
19+
handleSubmit,
20+
formState: { errors },
21+
} = useForm<{ email: string }>({ mode: "all" });
22+
23+
return (
24+
<Box
25+
sx={{
26+
display: "flex",
27+
flexDirection: "row",
28+
minHeight: "100vh",
29+
minWidth: "755px",
30+
}}
31+
>
32+
<Box flex={1}>
33+
<Stack
34+
height="100%"
35+
direction="column"
36+
sx={(theme) => ({
37+
backgroundColor: "secondary.main",
38+
padding: theme.spacing(2, 10),
39+
justifyContent: "center",
40+
})}
41+
>
42+
<Typography
43+
component="h1"
44+
variant="h1"
45+
sx={{ color: "primary.main", textAlign: "center" }}
46+
>
47+
Reset Password
48+
</Typography>
49+
<Stack
50+
component="form"
51+
direction="column"
52+
spacing={1.5}
53+
sx={(theme) => ({
54+
marginTop: theme.spacing(2),
55+
marginBottom: theme.spacing(2),
56+
})}
57+
onSubmit={handleSubmit((data) => resetPassword(data.email))}
58+
noValidate
59+
>
60+
<Typography>
61+
Enter your email address and we will send you a password reset
62+
link.
63+
</Typography>
64+
<TextField
65+
label="Email"
66+
required
67+
fullWidth
68+
margin="normal"
69+
type="email"
70+
{...register("email", {
71+
setValueAs: (value: string) => value.trim(),
72+
validate: { emailValidator },
73+
})}
74+
error={!!errors.email}
75+
helperText={errors.email?.message}
76+
/>
77+
<Button
78+
type="submit"
79+
variant="contained"
80+
sx={(theme) => ({ margin: theme.spacing(2, 0) })}
81+
>
82+
Send Reset Link
83+
</Button>
84+
</Stack>
85+
</Stack>
86+
</Box>
87+
<Box
88+
flex={1}
89+
sx={{
90+
display: "flex",
91+
justifyContent: "center",
92+
alignItems: "center",
93+
}}
94+
>
95+
<LogInSvg width="80%" height="80%" />
96+
</Box>
97+
<ToastContainer position="bottom-right" />
98+
</Box>
99+
);
100+
};
101+
102+
export default ForgetPassword;

frontend/src/pages/LogIn/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ const LogIn: React.FC = () => {
122122
textDecoration: "underline",
123123
},
124124
}}
125+
onClick={() => navigate("/forget-password")}
125126
>
126127
Forget password
127128
</StyledTypography>

0 commit comments

Comments
 (0)