You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

132 lines
3.6 KiB

"use client";
import { zodResolver } from "@hookform/resolvers/zod";
import { toast, Toaster } from "sonner";
import { useForm } from "react-hook-form";
import { z } from "zod";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { useAuth } from "@/lib/auth-context";
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
const formSchema = z.object({
email: z.string().email({ message: "Invalid email address" }),
password: z
.string()
.min(6, { message: "Password must be at least 6 characters" }),
});
export function LoginForm() {
const router = useRouter();
const searchParams = new URLSearchParams(
typeof window !== "undefined" ? window.location.search : ""
);
const redirectPath = searchParams.get("redirect") || "/";
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: "",
password: "",
},
});
const { login } = useAuth();
const onSubmit = async (data: z.infer<typeof formSchema>) => {
try {
const response = await fetch("/api/auth/login", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
});
const result = await response.json();
if (!response.ok) {
toast.error(result.error || "Login failed");
return;
}
// Use the auth context to handle login
login(result.token, {
...result.user,
FirstName: result.user.FirstName,
LastName: result.user.LastName,
Email: result.user.Email,
});
toast.success("Login successful!");
// Redirect to the original destination or default route
router.push(redirectPath);
} catch (error) {
console.error("Login error:", error);
toast.error("Connection error. Please try again.");
}
};
return (
<div className="max-w-md mx-auto p-6 md:p-8 bg-white rounded-lg shadow-md">
<Toaster position="top-center" richColors />
<Form {...form}>
<form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
<FormField
control={form.control}
name="email"
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input
type="email"
placeholder="Enter your email"
{...field}
className="focus-visible:ring-orange-500"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name="password"
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<Input
type="password"
placeholder="Enter your password"
{...field}
className="focus-visible:ring-orange-500"
/>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button
type="submit"
className="w-full bg-orange-500 hover:bg-orange-600 cursor-pointer text-white font-medium py-2 px-4 rounded-md transition-colors"
>
Login
</Button>
</form>
</Form>
</div>
);
}