From 140311d7419fa2192e5149df8f589c3c3733a399 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Thu, 10 Jul 2025 20:50:19 +0000 Subject: feat: Support forget and reset password --- apps/web/components/signin/ForgotPasswordForm.tsx | 149 ++++++++++++++++++++++ 1 file changed, 149 insertions(+) create mode 100644 apps/web/components/signin/ForgotPasswordForm.tsx (limited to 'apps/web/components/signin/ForgotPasswordForm.tsx') diff --git a/apps/web/components/signin/ForgotPasswordForm.tsx b/apps/web/components/signin/ForgotPasswordForm.tsx new file mode 100644 index 00000000..29d55f2b --- /dev/null +++ b/apps/web/components/signin/ForgotPasswordForm.tsx @@ -0,0 +1,149 @@ +"use client"; + +import { useState } from "react"; +import { useRouter } from "next/navigation"; +import { ActionButton } from "@/components/ui/action-button"; +import { Alert, AlertDescription } from "@/components/ui/alert"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { + Form, + FormControl, + FormField, + FormItem, + FormLabel, + FormMessage, +} from "@/components/ui/form"; +import { Input } from "@/components/ui/input"; +import { api } from "@/lib/trpc"; +import { zodResolver } from "@hookform/resolvers/zod"; +import { TRPCClientError } from "@trpc/client"; +import { AlertCircle, CheckCircle } from "lucide-react"; +import { useForm } from "react-hook-form"; +import { z } from "zod"; + +const forgotPasswordSchema = z.object({ + email: z.string().email("Please enter a valid email address"), +}); + +export default function ForgotPasswordForm() { + const [isSubmitted, setIsSubmitted] = useState(false); + const [errorMessage, setErrorMessage] = useState(""); + const router = useRouter(); + + const form = useForm>({ + resolver: zodResolver(forgotPasswordSchema), + }); + + const forgotPasswordMutation = api.users.forgotPassword.useMutation(); + + const onSubmit = async (values: z.infer) => { + try { + setErrorMessage(""); + await forgotPasswordMutation.mutateAsync(values); + setIsSubmitted(true); + } catch (error) { + if (error instanceof TRPCClientError) { + setErrorMessage(error.message); + } else { + setErrorMessage("An unexpected error occurred. Please try again."); + } + } + }; + + return ( + + + + {isSubmitted ? "Check your email" : "Forgot your password?"} + + + {isSubmitted + ? "If an account with that email exists, we've sent you a password reset link." + : "Enter your email address and we'll send you a link to reset your password."} + + + + {isSubmitted ? ( + <> +
+ +
+ + + If an account with that email exists, we've sent you a + password reset link. + + + router.push("/signin")} + className="w-full" + > + Back to Sign In + + + ) : ( + <> +
+ + {errorMessage && ( + + + {errorMessage} + + )} + + ( + + Email + + + + + + )} + /> + + + Send Reset Link + + + + +
+ router.push("/signin")} + className="w-full" + > + Back to Sign In + +
+ + )} +
+
+ ); +} -- cgit v1.2.3-70-g09d2