import { useForm } from "@tanstack/react-form";
import { Link, useNavigate } from "@tanstack/react-router";
import { toast } from "sonner";
import z from "zod";
import { authClient } from "@/lib/auth-client";
import { Button, buttonVariants } from "./ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "./ui/card";
import { Input } from "./ui/input";
import { Label } from "./ui/label";
export default function SignInForm() {
const navigate = useNavigate();
const form = useForm({
defaultValues: {
email: "",
password: "",
},
onSubmit: async ({ value }) => {
await authClient.signIn.email(
{
email: value.email,
password: value.password,
},
{
onSuccess: () => {
navigate({
to: "/dashboard",
});
toast.success("Sign in successful");
},
onError: (error) => {
toast.error(error.error.message || error.error.statusText);
},
}
);
},
validators: {
onSubmit: z.object({
email: z.email("Invalid email address"),
password: z.string().min(8, "Password must be at least 8 characters"),
}),
},
});
return (
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle>Welcome back</CardTitle>
<CardDescription>Login to your account to continue.</CardDescription>
</CardHeader>
<CardContent>
<form
className="space-y-4"
onSubmit={(e) => {
e.preventDefault();
e.stopPropagation();
form.handleSubmit();
}}
>
<div>
<form.Field name="email">
{(field) => (
<div className="space-y-2">
<Label htmlFor={field.name}>Email</Label>
<Input
id={field.name}
name={field.name}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
placeholder="name@example.com"
type="email"
value={field.state.value}
/>
{field.state.meta.errors.map((error) => (
<p className="text-red-500" key={error?.message}>
{error?.message}
</p>
))}
</div>
)}
</form.Field>
</div>
<div>
<form.Field name="password">
{(field) => (
<div className="space-y-2">
<Label htmlFor={field.name}>Password</Label>
<Input
id={field.name}
name={field.name}
onBlur={field.handleBlur}
onChange={(e) => field.handleChange(e.target.value)}
placeholder="At least 8 characters"
type="password"
value={field.state.value}
/>
{field.state.meta.errors.map((error) => (
<p className="text-red-500" key={error?.message}>
{error?.message}
</p>
))}
</div>
)}
</form.Field>
</div>
<form.Subscribe>
{(state) => (
<Button
className="w-full"
disabled={!state.canSubmit || state.isSubmitting}
loading={state.isSubmitting}
type="submit"
>
Login
</Button>
)}
</form.Subscribe>
</form>
<div className="mt-4 text-center">
<Link className={buttonVariants({ variant: "link" })} to="/signup">
Need an account? Sign Up
</Link>
</div>
</CardContent>
</Card>
);
}