Skip to content

Commit

Permalink
Create reset password page
Browse files Browse the repository at this point in the history
- Added a reset password form with three inputs: `old password`, `new password`, and `confirm password`.
- Included a submit button to handle form submission for the password reset.
- Ensured validation for new password and confirm password fields to match.
- Applied basic styling consistent with the current design.
  • Loading branch information
Fingertips18 committed Sep 23, 2024
1 parent a9a085f commit ab1024b
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 10 deletions.
5 changes: 5 additions & 0 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Route, Routes } from "react-router-dom";

import { ForgotPasswordPage } from "@/pages/forgot-password/page";
import { ResetPasswordPage } from "@/pages/reset-password/page";
import VerifyEmailPage from "@/pages/verify-email/page";
import PrivateGuard from "@/guards/private-guard";
import { AppRoutes } from "@/constants/routes";
Expand All @@ -25,6 +26,10 @@ function App() {
path={AppRoutes.ForgotPassword}
element={<ForgotPasswordPage />}
/>
<Route
path={`${AppRoutes.ResetPassword}/:token`}
element={<ResetPasswordPage />}
/>
</Routes>
</main>
);
Expand Down
43 changes: 40 additions & 3 deletions client/src/constants/collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
ValidateUsername,
} from "@/lib/utils/validations";

export const SIGNUPINPUTS = [
export const SIGNUP_INPUTS = [
{
name: "username",
label: "Username",
Expand Down Expand Up @@ -35,7 +35,7 @@ export const SIGNUPINPUTS = [
name: "password",
label: "Password",
tooltip:
"Create a strong password with at least 8 characters. Include a mix of uppercase letters, lowercase letters, numbers, and special characters for better security.",
"Create a password with at least 8 characters, including uppercase, lowercase, numbers, and special characters for security.",
placeholder: "e.g. m#P52s@ap$V",
type: "password",
autoComplete: "new-password",
Expand All @@ -56,7 +56,7 @@ export const SIGNUPINPUTS = [
},
];

export const SIGNININPUTS = [
export const SIGNIN_INPUTS = [
{
name: "email",
label: "Email Address",
Expand All @@ -82,3 +82,40 @@ export const SIGNININPUTS = [
maxLength: 128,
},
];

export const RESET_PASSWORD_INPUTS = [
{
name: "old-password",
label: "Old Password",
tooltip: "Enter your current password",
placeholder: "e.g. m#P52s@ap$V",
type: "password",
autoComplete: "new-password",
suffixIcon: Lock,
validation: ValidatePassword,
maxLength: 128,
},
{
name: "new-password",
label: "New Password",
tooltip:
"Create a password with at least 8 characters, including uppercase, lowercase, numbers, and special characters for security",
placeholder: "e.g. m#P52s@ap$V",
type: "password",
autoComplete: "new-password",
suffixIcon: Lock,
validation: ValidatePassword,
maxLength: 128,
},
{
label: "Confirm Password",
tooltip:
"Re-enter your password to confirm it matches the one you typed above. Ensure both passwords are identical.",
placeholder: "e.g. m#P52s@ap$V",
type: "password",
autoComplete: "new-password",
suffixIcon: Lock,
validation: ValidateConfirmPassword,
maxLength: 128,
},
];
1 change: 1 addition & 0 deletions client/src/constants/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export const VERIFYEMAILKEY = "verify-email";
export const RESENDVERIFYKEY = "resend-verify";
export const VERIFYTOKENKEY = "verify-token";
export const FORGOTPASSWORDKEY = "forgot-password";
export const RESETPASSWORDKEY = "reset-password";
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { useMutation } from "@tanstack/react-query";
import { FormEvent, useState } from "react";

import { RESET_PASSWORD_INPUTS } from "@/constants/collections";
import { RESETPASSWORDKEY } from "@/constants/keys";
import { Button } from "@/components/text-button";
import { Input } from "@/components/input";

const ResetPasswordForm = () => {
const [confirmPassword, setConfirmPassword] = useState("");
const { isPending } = useMutation({
mutationKey: [RESETPASSWORDKEY],
});

const onSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
};

return (
<form
onSubmit={onSubmit}
className="p-4 lg:p-6 w-full md:w-fit rounded-md border border-primary/50 bg-primary/15 drop-shadow-2xl space-y-4 lg:space-y-6"
>
{RESET_PASSWORD_INPUTS.map((r) => (
<Input
key={r.label}
required
disabled={isPending}
{...r}
validation={(value) => {
if (r.name === "new-password") {
setConfirmPassword(value);
}
if (r.name === undefined) {
return r.validation({
pass1: value,
pass2: confirmPassword,
});
}

return r.validation(value);
}}
/>
))}

<Button
label="Sign In"
disabled={isPending}
loading={isPending}
type="submit"
/>
</form>
);
};

export { ResetPasswordForm };
18 changes: 18 additions & 0 deletions client/src/pages/reset-password/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { ResetPasswordForm } from "./_components/reset-password-form";

const ResetPasswordPage = () => {
return (
<section className="px-4 lg:px-0 h-full flex-center flex-col gap-y-6 w-fit mx-auto">
<h2
className="text-lg lg:text-2xl font-extrabold text-center uppercase w-full
rounded-md border border-primary/50 bg-primary/15 drop-shadow-2xl p-4"
>
Reset Password
</h2>

<ResetPasswordForm />
</section>
);
};

export { ResetPasswordPage };
10 changes: 5 additions & 5 deletions client/src/pages/sign-in/_components/sign-in-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { GenericResponse } from "@/lib/classes/generic-response-class";
import { ErrorResponse } from "@/lib/classes/error-response-class";
import { AuthService } from "@/lib/services/auth-service";
import { useAuthStore } from "@/lib/stores/auth-store";
import { SIGNININPUTS } from "@/constants/collections";
import { SIGNIN_INPUTS } from "@/constants/collections";
import { SignInDTO } from "@/lib/DTO/sign-in-dto";
import { Button } from "@/components/text-button";
import { AppRoutes } from "@/constants/routes";
Expand Down Expand Up @@ -52,13 +52,13 @@ const SignInForm = () => {
onSubmit={onSubmit}
className="p-4 lg:p-6 w-full md:w-fit rounded-md border border-primary/50 bg-primary/15 drop-shadow-2xl space-y-4 lg:space-y-6"
>
{SIGNININPUTS.map((s) => (
{SIGNIN_INPUTS.map((i) => (
<Input
key={s.label}
key={i.label}
required
disabled={isPending}
{...s}
validation={s.validation}
{...i}
validation={i.validation}
/>
))}

Expand Down
4 changes: 2 additions & 2 deletions client/src/pages/sign-up/_components/sign-up-form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { toast } from "sonner";

import { ErrorResponse } from "@/lib/classes/error-response-class";
import { AuthService } from "@/lib/services/auth-service";
import { SIGNUPINPUTS } from "@/constants/collections";
import { SIGNUP_INPUTS } from "@/constants/collections";
import { SignUpDTO } from "@/lib/DTO/sign-up-dto";
import { Button } from "@/components/text-button";
import { AppRoutes } from "@/constants/routes";
Expand Down Expand Up @@ -41,7 +41,7 @@ const SignUpForm = () => {
onSubmit={onSubmit}
className="p-4 lg:p-6 w-full md:w-fit rounded-md border border-primary/50 bg-primary/15 drop-shadow-2xl space-y-4 lg:space-y-6"
>
{SIGNUPINPUTS.map((s) => (
{SIGNUP_INPUTS.map((s) => (
<Input
key={s.label}
required
Expand Down

0 comments on commit ab1024b

Please sign in to comment.