"use client"; import * as React from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import * as z from "zod"; import { IconLoader } from "@tabler/icons-react"; import { toast } from "sonner"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/input-otp"; const emailSchema = z.object({ email: z.string().email("Enter a valid email address"), }); const codeSchema = z.object({ code: z.string().length(6, "Code must be 6 digits"), }); type EmailFormData = z.infer; type CodeFormData = z.infer; export function PasswordlessForm() { const router = useRouter(); const [step, setStep] = React.useState<"email" | "code">("email"); const [email, setEmail] = React.useState(""); const [isLoading, setIsLoading] = React.useState(false); const emailForm = useForm({ resolver: zodResolver(emailSchema), }); const codeForm = useForm({ resolver: zodResolver(codeSchema), }); const onSendCode = async (data: EmailFormData) => { setIsLoading(true); try { const response = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type: "passwordless_send", email: data.email, }), }); const result = (await response.json()) as { success: boolean; message?: string; error?: string; [key: string]: unknown; }; if (result.success) { setEmail(data.email); setStep("code"); toast.success("Check your email for a 6-digit code"); } else { toast.error(result.error || "Failed to send code"); } } catch { toast.error("An error occurred. Please try again."); } finally { setIsLoading(false); } }; const onVerifyCode = async (data: CodeFormData) => { setIsLoading(true); try { const response = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ type: "passwordless_verify", email, code: data.code, }), }); const result = (await response.json()) as { success: boolean; message?: string; error?: string; redirectUrl?: string; [key: string]: unknown; }; if (result.success) { toast.success("Welcome back!"); router.push(result.redirectUrl as string); } else { toast.error(result.error || "Invalid code"); } } catch { toast.error("An error occurred. Please try again."); } finally { setIsLoading(false); } }; const handleCodeChange = (value: string) => { codeForm.setValue("code", value); if (value.length === 6) { codeForm.handleSubmit(onVerifyCode)(); } }; if (step === "email") { return (
{emailForm.formState.errors.email && (

{emailForm.formState.errors.email.message}

)}

Don't have an account?{" "} Sign up

); } return (

We sent a code to {email}

{codeForm.formState.errors.code && (

{codeForm.formState.errors.code.message}

)}
); }