"use client" import { useState, useEffect, useCallback } from "react" import { ArrowLeft, Loader2, Mail } from "lucide-react" import { authClient } from "@/lib/auth-client" import OtpInput from "./otp-input" interface OtpVerificationStepProps { email: string onSuccess: () => void onBack: () => void } export default function OtpVerificationStep({ email, onSuccess, onBack, }: OtpVerificationStepProps) { const [otp, setOtp] = useState("") const [error, setError] = useState("") const [isLoading, setIsLoading] = useState(false) const [resendTimer, setResendTimer] = useState(300) // 5 minutes const [canResend, setCanResend] = useState(false) // Countdown timer useEffect(() => { if (resendTimer <= 0) { setCanResend(true) return } const interval = setInterval(() => { setResendTimer((prev) => prev - 1) }, 1000) return () => clearInterval(interval) }, [resendTimer]) const formatTime = (seconds: number) => { const mins = Math.floor(seconds / 60) const secs = seconds % 60 return `${mins}:${secs.toString().padStart(2, "0")}` } const handleVerify = useCallback(async () => { if (otp.length !== 6) return setIsLoading(true) setError("") const { error } = await authClient.emailOtp.verifyEmail({ email, otp, }) setIsLoading(false) if (error) { setError( error.code === "TOO_MANY_ATTEMPTS" ? "Too many attempts. Please request a new code." : "Invalid code. Please try again.", ) return } onSuccess() }, [otp, email, onSuccess]) // Auto-submit when all digits entered useEffect(() => { if (otp.length === 6) { handleVerify() } }, [otp, handleVerify]) const handleResend = async () => { setError("") await authClient.emailOtp.sendVerificationOtp({ email, type: "email-verification", }) setResendTimer(300) setCanResend(false) } return (

Verify your email

We sent a 6-digit code to{" "} {email}

{canResend ? ( ) : ( Resend code in{" "} {formatTime(resendTimer)} )}
) }