Spaces:
Sleeping
Sleeping
| "use client" | |
| import { useState } from "react" | |
| import { useForm } from "react-hook-form" | |
| import { zodResolver } from "@hookform/resolvers/zod" | |
| import * as z from "zod" | |
| import { signIn } from "next-auth/react" | |
| import { useRouter } from "next/navigation" | |
| import { Loader2 } from "lucide-react" | |
| import Link from "next/link" | |
| import { Button } from "@/components/ui/button" | |
| import { | |
| Form, | |
| FormControl, | |
| FormField, | |
| FormItem, | |
| FormLabel, | |
| FormMessage, | |
| } from "@/components/ui/form" | |
| import { Input } from "@/components/ui/input" | |
| import { | |
| Card, | |
| CardContent, | |
| CardDescription, | |
| CardHeader, | |
| CardTitle, | |
| } from "@/components/ui/card" | |
| const formSchema = z.object({ | |
| email: z.string().email("Invalid email address"), | |
| password: z.string().min(1, "Password is required"), | |
| }) | |
| export default function LoginPage() { | |
| const router = useRouter() | |
| const [isLoading, setIsLoading] = useState(false) | |
| const [error, setError] = useState<string | null>(null) | |
| const form = useForm<z.infer<typeof formSchema>>({ | |
| resolver: zodResolver(formSchema), | |
| defaultValues: { | |
| email: "", | |
| password: "", | |
| }, | |
| }) | |
| async function onSubmit(values: z.infer<typeof formSchema>) { | |
| setIsLoading(true) | |
| setError(null) | |
| try { | |
| const result = await signIn("credentials", { | |
| email: values.email, | |
| password: values.password, | |
| redirect: false, | |
| }) | |
| if (result?.error) { | |
| setError("Invalid email or password") | |
| return | |
| } | |
| router.push("/admin/dashboard") | |
| router.refresh() | |
| } catch (error) { | |
| setError("Something went wrong. Please try again.") | |
| } finally { | |
| setIsLoading(false) | |
| } | |
| } | |
| return ( | |
| <div className="flex min-h-screen items-center justify-center bg-gray-100 p-4 dark:bg-gray-900"> | |
| <Card className="w-full max-w-md"> | |
| <CardHeader className="space-y-1"> | |
| <CardTitle className="text-2xl font-bold text-center"> | |
| Admin Login | |
| </CardTitle> | |
| <CardDescription className="text-center"> | |
| Enter your credentials to access the dashboard | |
| </CardDescription> | |
| </CardHeader> | |
| <CardContent> | |
| <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="admin@example.com" {...field} /> | |
| </FormControl> | |
| <FormMessage /> | |
| </FormItem> | |
| )} | |
| /> | |
| <FormField | |
| control={form.control} | |
| name="password" | |
| render={({ field }) => ( | |
| <FormItem> | |
| <FormLabel>Password</FormLabel> | |
| <FormControl> | |
| <Input type="password" placeholder="••••••" {...field} /> | |
| </FormControl> | |
| <FormMessage /> | |
| </FormItem> | |
| )} | |
| /> | |
| <div className="flex justify-end"> | |
| <Link | |
| href="/admin/forgot-password" | |
| className="text-sm font-medium text-primary hover:underline" | |
| > | |
| Forgot password? | |
| </Link> | |
| </div> | |
| {error && ( | |
| <div className="text-sm text-red-500 font-medium text-center"> | |
| {error} | |
| </div> | |
| )} | |
| <Button type="submit" className="w-full" disabled={isLoading}> | |
| {isLoading ? ( | |
| <> | |
| <Loader2 className="mr-2 h-4 w-4 animate-spin" /> | |
| Signing in... | |
| </> | |
| ) : ( | |
| "Sign In" | |
| )} | |
| </Button> | |
| </form> | |
| </Form> | |
| </CardContent> | |
| </Card> | |
| </div> | |
| ) | |
| } | |