Spaces:
Sleeping
Sleeping
| import React, { useState } from "react"; | |
| import { z } from "zod"; | |
| import { useForm } from "react-hook-form"; | |
| import { zodResolver } from "@hookform/resolvers/zod"; | |
| import { Link } from "react-router-dom"; | |
| import { | |
| Form, | |
| FormControl, | |
| FormField, | |
| FormItem, | |
| FormLabel, | |
| FormMessage, | |
| } from "@/components/ui/form"; | |
| import { Input } from "@/components/ui/input"; | |
| import { Button } from "@/components/ui/button"; | |
| import { | |
| Card, | |
| CardContent, | |
| CardDescription, | |
| CardFooter, | |
| CardHeader, | |
| CardTitle, | |
| } from "@/components/ui/card"; | |
| import Logo from "@/components/ui/logo"; | |
| import { toast } from "@/lib/custom-toast"; | |
| import { authService } from "@/lib/api"; | |
| // Form schema and validation | |
| const formSchema = z.object({ | |
| email: z.string().email({ | |
| message: "Please enter a valid email address", | |
| }), | |
| }); | |
| const ForgotPassword = () => { | |
| const [isLoading, setIsLoading] = useState(false); | |
| const [isEmailSent, setIsEmailSent] = useState(false); | |
| const [apiError, setApiError] = useState<string | null>(null); | |
| const form = useForm<z.infer<typeof formSchema>>({ | |
| resolver: zodResolver(formSchema), | |
| defaultValues: { | |
| email: "", | |
| }, | |
| }); | |
| const onSubmit = async (values: z.infer<typeof formSchema>) => { | |
| try { | |
| setIsLoading(true); | |
| setApiError(null); | |
| // Call the password reset request API | |
| const response = await authService.requestPasswordReset(values.email); | |
| // Show success message and update UI | |
| setIsEmailSent(true); | |
| toast.success(response.message || "Password reset link sent to your email"); | |
| } catch (error: any) { | |
| // Show error message | |
| const errorMessage = error.message || "Failed to send reset link. Please try again."; | |
| setApiError(errorMessage); | |
| toast.error(errorMessage); | |
| } finally { | |
| setIsLoading(false); | |
| } | |
| }; | |
| return ( | |
| <div className="flex min-h-screen items-center justify-center bg-background p-4"> | |
| <div className="w-full max-w-md space-y-6"> | |
| <div className="flex flex-col items-center space-y-2 text-center"> | |
| <Logo className="h-10 w-10" /> | |
| <h1 className="text-2xl font-bold">Forgot Password</h1> | |
| <p className="text-sm text-muted-foreground"> | |
| Enter your email to receive a password reset link | |
| </p> | |
| </div> | |
| <Card className="shadow-lg border-none overflow-hidden"> | |
| <div className="absolute top-0 left-0 right-0 h-1 bg-gradient-to-r from-orange-400 to-coral-600"></div> | |
| <CardContent className="pt-6 pb-4"> | |
| {isEmailSent ? ( | |
| <div className="text-center py-6 px-4"> | |
| <h2 className="text-xl font-semibold mb-2">Check Your Email</h2> | |
| <p className="text-muted-foreground mb-4"> | |
| We've sent a password reset link to your email address. | |
| </p> | |
| <Button | |
| variant="link" | |
| className="mt-2" | |
| asChild | |
| > | |
| <Link to="/login">Back to Login</Link> | |
| </Button> | |
| </div> | |
| ) : ( | |
| <> | |
| {apiError && ( | |
| <div className="bg-red-50 border border-red-200 text-red-600 px-4 py-2 rounded-md mb-4 text-sm"> | |
| {apiError} | |
| </div> | |
| )} | |
| <Form {...form}> | |
| <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-4"> | |
| <FormField | |
| control={form.control} | |
| name="email" | |
| render={({ field }) => ( | |
| <FormItem> | |
| <FormLabel>Email</FormLabel> | |
| <FormControl> | |
| <Input | |
| placeholder="Enter your email" | |
| type="email" | |
| autoComplete="email" | |
| {...field} | |
| disabled={isLoading} | |
| /> | |
| </FormControl> | |
| <FormMessage /> | |
| </FormItem> | |
| )} | |
| /> | |
| <Button | |
| type="submit" | |
| className="w-full" | |
| disabled={isLoading} | |
| > | |
| {isLoading ? "Sending..." : "Send Reset Link"} | |
| </Button> | |
| </form> | |
| </Form> | |
| </> | |
| )} | |
| </CardContent> | |
| <CardFooter className="flex justify-center border-t px-6 py-4"> | |
| <Button | |
| variant="link" | |
| className="px-0" | |
| asChild | |
| > | |
| <Link to="/login">Back to Login</Link> | |
| </Button> | |
| </CardFooter> | |
| </Card> | |
| </div> | |
| </div> | |
| ); | |
| }; | |
| export default ForgotPassword; |