csa-dashboard-sementara/csa-dashboard/app/login/page.tsx

111 lines
4.3 KiB
TypeScript

"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { useAuth } from "@/providers/auth-provider";
import { useLogin } from "@/modules/admin/hooks";
import { loginSchema, type LoginInput } from "@/modules/admin/schemas";
import { useToast } from "@/hooks/use-toast";
import Link from "next/link";
export default function LoginPage() {
const router = useRouter();
const { login: authLogin } = useAuth();
const { toast } = useToast();
const loginMutation = useLogin();
const {
register,
handleSubmit,
formState: { errors },
} = useForm<LoginInput>({
resolver: zodResolver(loginSchema),
});
const onSubmit = async (data: LoginInput) => {
try {
const response = await loginMutation.mutateAsync(data);
if (response.data.token) {
authLogin(response.data.token, { email: response.data.admin.email, username: response.data.admin.name });
toast({
title: "Login successful",
description: "Welcome back!",
});
// router.push is handled by authLogin
}
} catch (error: any) {
toast({
title: "Login failed",
description: error.response?.data?.message || "Invalid credentials",
variant: "destructive",
});
}
};
return (
<div className="flex min-h-screen items-center justify-center p-4">
<Card className="w-full max-w-md">
<CardHeader className="space-y-1">
<CardTitle className="text-2xl font-bold text-center text-white">
Admin CSA
</CardTitle>
<CardDescription className="text-center">
Enter your credentials to access the dashboard
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
<div className="space-y-2">
<Label htmlFor="email">Email</Label>
<Input
id="email"
type="email"
placeholder="admin@csa.id"
{...register("email")}
/>
{errors.email && (
<p className="text-sm text-destructive">{errors.email.message}</p>
)}
</div>
<div className="space-y-2">
<Label htmlFor="password">Password</Label>
<Input
id="password"
type="password"
placeholder="••••••••"
{...register("password")}
/>
{errors.password && (
<p className="text-sm text-destructive">{errors.password.message}</p>
)}
</div>
<Button
type="submit"
className="w-full"
disabled={loginMutation.isPending}
>
{loginMutation.isPending ? "Signing in..." : "Sign In"}
</Button>
<p className="text-center text-sm text-muted-foreground">
Don&apos;t have an account?{" "}
<Link href="/register" className="text-primary hover:underline">
Register
</Link>
</p>
</form>
</CardContent>
</Card>
</div>
);
}