"use client"; import { zodResolver } from "@hookform/resolvers/zod"; import { Alert, AlertTitle } from "@ui/components/alert"; import { Button } from "@ui/components/button"; import { AlertTriangleIcon, ArrowLeftIcon } from "lucide-react"; import { authClient } from "@repo/auth/client"; import { config } from "@repo/config"; import { useAuthErrorMessages } from "@saas/auth/hooks/errors-messages"; import { useRouter } from "@shared/hooks/router"; import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from "@ui/components/form"; import { InputOTP, InputOTPGroup, InputOTPSeparator, InputOTPSlot, } from "@ui/components/input-otp"; import { useTranslations } from "next-intl"; import Link from "next/link"; import { useSearchParams } from "next/navigation"; import { useForm } from "react-hook-form"; import * as z from "zod"; const formSchema = z.object({ code: z.string().min(6).max(6), }); type FormValues = z.infer; export function OtpForm() { const t = useTranslations(); const router = useRouter(); const { getAuthErrorMessage } = useAuthErrorMessages(); const searchParams = useSearchParams(); const invitationId = searchParams.get("invitationId"); const redirectTo = searchParams.get("redirectTo"); const redirectPath = invitationId ? `/app/organization-invitation/${invitationId}` : (redirectTo ?? config.auth.redirectAfterSignIn); const form = useForm({ resolver: zodResolver(formSchema), defaultValues: { code: "", }, }); const onSubmit = form.handleSubmit(async ({ code }) => { try { const { error } = await authClient.twoFactor.verifyTotp({ code, }); if (error) { throw error; } router.replace(redirectPath); } catch (e) { form.setError("root", { message: getAuthErrorMessage( e && typeof e === "object" && "code" in e ? (e.code as string) : undefined, ), }); } }); return ( <>

{t("auth.verify.title")}

{t("auth.verify.message")}

{form.formState.errors.root && ( {form.formState.errors.root.message} )} ( {t("auth.verify.code")} { field.onChange(value); onSubmit(); }} > )} />
{t("auth.verify.backToSignin")}
); }