"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { useForm } from "react-hook-form"; import { z } from "zod"; import { useState } from "react"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardDescription, CardHeader, CardTitle, } from "@/components/ui/card"; import { Form, FormControl, FormDescription, FormField, FormItem, FormLabel, FormMessage, } from "@/components/ui/form"; import { Input } from "@/components/ui/input"; import { InputOTP, InputOTPGroup, InputOTPSlot, } from "@/components/ui/input-otp"; import { AxiosResponse } from "axios"; import { VerifyEmailResponse } from "@server/routers/auth"; import { Loader2 } from "lucide-react"; import { Alert, AlertDescription } from "../../../components/ui/alert"; import { toast } from "@app/hooks/useToast"; import { useRouter } from "next/navigation"; import { formatAxiosError } from "@app/lib/api";; import { createApiClient } from "@app/lib/api"; import { useEnvContext } from "@app/hooks/useEnvContext"; import { cleanRedirect } from "@app/lib/cleanRedirect"; const FormSchema = z.object({ email: z.string().email({ message: "Invalid email address" }), pin: z.string().min(8, { message: "Your verification code must be 8 characters.", }), }); export type VerifyEmailFormProps = { email: string; redirect?: string; }; export default function VerifyEmailForm({ email, redirect, }: VerifyEmailFormProps) { const router = useRouter(); const [error, setError] = useState(null); const [successMessage, setSuccessMessage] = useState(null); const [isResending, setIsResending] = useState(false); const [isSubmitting, setIsSubmitting] = useState(false); const api = createApiClient(useEnvContext()); const form = useForm>({ resolver: zodResolver(FormSchema), defaultValues: { email: email, pin: "", }, }); async function onSubmit(data: z.infer) { setIsSubmitting(true); const res = await api .post>("/auth/verify-email", { code: data.pin, }) .catch((e) => { setError(formatAxiosError(e, "An error occurred")); console.error("Failed to verify email:", e); setIsSubmitting(false); }); if (res && res.data?.data?.valid) { setError(null); setSuccessMessage( "Email successfully verified! Redirecting you..." ); setTimeout(() => { if (redirect) { const safe = cleanRedirect(redirect); router.push(safe); } else { router.push("/"); } setIsSubmitting(false); }, 1500); } } async function handleResendCode() { setIsResending(true); const res = await api.post("/auth/verify-email/request").catch((e) => { setError(formatAxiosError(e, "An error occurred")); console.error("Failed to resend verification code:", e); }); if (res) { setError(null); toast({ variant: "default", title: "Verification code resent", description: "We've resent a verification code to your email address. Please check your inbox.", }); } setIsResending(false); } return (
Verify Email Enter the verification code sent to your email address.
( Email )} /> ( Verification Code
We sent a verification code to your email address.
)} /> {error && ( {error} )} {successMessage && ( {successMessage} )}
); }