diff --git a/src/App.tsx b/src/App.tsx
index 6db1229..9cf4075 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -10,6 +10,7 @@ import ErrorPage from "./Pages/ErrorPage/ErrorPage";
import DashboardPage from "./Pages/DashboardPage/DashboardPage";
import Revalidator from "./Components/Revalidator/Revalidator";
import ActivationPage from "./Pages/ActivationPage/ActivationPage";
+import ResetPasswordPage from "./Pages/ResetPasswordPage/ResetPasswordPage";
const queryClient = new QueryClient();
const router = createHashRouter([
@@ -42,6 +43,15 @@ const router = createHashRouter([
),
errorElement: ,
},
+ {
+ path: "/reset_password_confirm/:uid/:token",
+ element: (
+ <>
+
+ >
+ ),
+ errorElement: ,
+ },
]);
export default function App() {
diff --git a/src/Components/API/API.tsx b/src/Components/API/API.tsx
index 2b22ca5..29fdaee 100644
--- a/src/Components/API/API.tsx
+++ b/src/Components/API/API.tsx
@@ -1,6 +1,11 @@
/* eslint-disable react-refresh/only-export-components */
import axios from "axios";
-import { ActivationType, LoginType, RegisterType } from "../Types/Types";
+import {
+ ActivationType,
+ LoginType,
+ RegisterType,
+ ResetPasswordConfirmType,
+} from "../Types/Types";
const instance = axios.create({
baseURL: "http://localhost:8000/",
@@ -130,3 +135,28 @@ export function ActivationAPI(activation: ActivationType) {
return false;
});
}
+export function ResetPasswordAPI(email: string) {
+ return instance
+ .post("api/v1/accounts/users/reset_password/", { email: email })
+ .then(() => {
+ console.log("Activation Success");
+ return true;
+ })
+ .catch(() => {
+ console.log("Activation failed");
+ return false;
+ });
+}
+
+export function ResetPasswordConfirmAPI(info: ResetPasswordConfirmType) {
+ return instance
+ .post("api/v1/accounts/users/reset_password_confirm/", info)
+ .then(() => {
+ console.log("Reset Success");
+ return true;
+ })
+ .catch(() => {
+ console.log("Reset failed");
+ return false;
+ });
+}
diff --git a/src/Components/LoginModal/LoginModal.tsx b/src/Components/LoginModal/LoginModal.tsx
index 6cc9459..fb6a5c0 100644
--- a/src/Components/LoginModal/LoginModal.tsx
+++ b/src/Components/LoginModal/LoginModal.tsx
@@ -106,16 +106,6 @@ export default function LoginModal() {
/>
Remember me
-
+
+
+ Enter your email to request a password reset
+
+
+
) => {
+ setEmail(e.target.value);
+ setError("");
+ }}
+ value={email}
+ placeholder={"Enter email associated with account"}
+ />
+ {error}
+
+
+ >
+ );
+}
diff --git a/src/Components/Types/Types.tsx b/src/Components/Types/Types.tsx
index 784a3b6..efcb59a 100644
--- a/src/Components/Types/Types.tsx
+++ b/src/Components/Types/Types.tsx
@@ -16,6 +16,12 @@ export type ActivationType = {
token: string;
};
+export type ResetPasswordConfirmType = {
+ uid: string;
+ token: string;
+ new_password: string;
+};
+
export type AddEquipmentType = {
name: string;
remarks: string;
diff --git a/src/Pages/ActivationPage/ActivationPage.tsx b/src/Pages/ActivationPage/ActivationPage.tsx
index 3117228..e95cf28 100644
--- a/src/Pages/ActivationPage/ActivationPage.tsx
+++ b/src/Pages/ActivationPage/ActivationPage.tsx
@@ -27,6 +27,16 @@ export default function ActivationPage() {
progress: undefined,
theme: "light",
});
+ toast("Please login to continue", {
+ position: "top-right",
+ autoClose: 6000,
+ hideProgressBar: false,
+ closeOnClick: true,
+ pauseOnHover: true,
+ draggable: true,
+ progress: undefined,
+ theme: "light",
+ });
setTimeout(() => {
navigate("/dashboard");
});
diff --git a/src/Pages/LandingPage/LandingPage.tsx b/src/Pages/LandingPage/LandingPage.tsx
index ea0ac88..8c1d046 100644
--- a/src/Pages/LandingPage/LandingPage.tsx
+++ b/src/Pages/LandingPage/LandingPage.tsx
@@ -9,9 +9,11 @@ import RegisterModal from "../../Components/RegisterModal/RegisterModal";
import { useSelector } from "react-redux";
import { useNavigate } from "react-router-dom";
import { RootState } from "../../Components/Plugins/Redux/Store/Store";
+import ResetPasswordModal from "../../Components/ResetPasswordModal/ResetPasswordModal";
export default function LandingPage() {
- const [LoginModalOpen, SetLoginModalOpen] = useState(false);
- const [RegisterModalOpen, SetRegisterModalOpen] = useState(false);
+ const [loginmodalOpen, SetloginmodalOpen] = useState(false);
+ const [registermodalOpen, SetRegisterModalOpen] = useState(false);
+ const [resetmodalOpen, SetResetModalOpen] = useState(false);
const authenticated = useSelector((state: RootState) => state.auth.value);
const navigate = useNavigate();
@@ -68,8 +70,9 @@ export default function LandingPage() {
type={"light"}
label={"Login"}
onClick={() => {
- SetLoginModalOpen(true);
+ SetloginmodalOpen(true);
SetRegisterModalOpen(false);
+ SetResetModalOpen(false);
}}
/>
diff --git a/src/Pages/ResetPasswordPage/ResetPasswordPage.tsx b/src/Pages/ResetPasswordPage/ResetPasswordPage.tsx
new file mode 100644
index 0000000..c70bdde
--- /dev/null
+++ b/src/Pages/ResetPasswordPage/ResetPasswordPage.tsx
@@ -0,0 +1,148 @@
+import { useNavigate, useParams } from "react-router-dom";
+import styles, { colors } from "../../styles";
+import { ResetPasswordConfirmAPI } from "../../Components/API/API";
+import { useState } from "react";
+import { toast } from "react-toastify";
+import { VisibilityOff, Visibility } from "@mui/icons-material";
+import { TextField, InputAdornment, IconButton } from "@mui/material";
+import Button from "../../Components/Button/Button";
+export default function ResetPasswordPage() {
+ const { uid, token } = useParams();
+ const [feedback, setFeedback] = useState("");
+ const [user, setUser] = useState({
+ password: "",
+ confirm_password: "",
+ });
+ const [showPassword, setShowPassword] = useState(false);
+ const navigate = useNavigate();
+ return (
+
+
+
+ Confirm Password Reset
+
+
+ {
+ setShowPassword(!showPassword);
+ setFeedback("");
+ }}
+ edge="end"
+ >
+ {showPassword ? : }
+
+
+ ),
+ }}
+ label="New Password"
+ placeholder={"Enter new password"}
+ onChange={(e: React.ChangeEvent) =>
+ setUser({ ...user, password: e.target.value })
+ }
+ value={user.password}
+ />
+
+ {
+ setShowPassword(!showPassword);
+ setFeedback("");
+ }}
+ edge="end"
+ >
+ {showPassword ? : }
+
+
+ ),
+ }}
+ label="Confirm Password"
+ placeholder={"Re-enter password"}
+ onChange={(e: React.ChangeEvent) =>
+ setUser({ ...user, password: e.target.value })
+ }
+ value={user.password}
+ />
+
+
+ {feedback}
+ {
+ if (uid && token && feedback == "") {
+ ResetPasswordConfirmAPI({
+ uid,
+ token,
+ new_password: user.password,
+ }).then((response) => {
+ if (response) {
+ setFeedback("Reset successful");
+ toast("Reset successful", {
+ position: "top-right",
+ autoClose: 2000,
+ hideProgressBar: false,
+ closeOnClick: true,
+ pauseOnHover: true,
+ draggable: true,
+ progress: undefined,
+ theme: "light",
+ });
+ toast("Please login to continue", {
+ position: "top-right",
+ autoClose: 6000,
+ hideProgressBar: false,
+ closeOnClick: true,
+ pauseOnHover: true,
+ draggable: true,
+ progress: undefined,
+ theme: "light",
+ });
+ setTimeout(() => {
+ navigate("/");
+ });
+ } else {
+ setFeedback("Invalid token specified for password reset");
+ }
+ });
+ }
+ if (!uid || !token) {
+ setFeedback("Missing token for password reset");
+ }
+ }}
+ />
+
+
+ );
+}