"use client"; import { useEffect, useRef } from "react"; import { UseFormReturn } from "react-hook-form"; import { Button } from "@app/components/ui/button"; import { Form, FormControl, FormField, FormItem, FormMessage } from "@app/components/ui/form"; import { InputOTP, InputOTPGroup, InputOTPSlot } from "./ui/input-otp"; import { Alert, AlertDescription } from "@app/components/ui/alert"; import { useTranslations } from "next-intl"; import { REGEXP_ONLY_DIGITS_AND_CHARS } from "input-otp"; import * as z from "zod"; type MfaInputFormProps = { form: UseFormReturn<{ code: string }>; onSubmit: (values: { code: string }) => void | Promise; onBack: () => void; error?: string | null; loading?: boolean; formId?: string; }; export default function MfaInputForm({ form, onSubmit, onBack, error, loading = false, formId = "mfaForm" }: MfaInputFormProps) { const t = useTranslations(); const otpContainerRef = useRef(null); // Auto-focus MFA input when component mounts useEffect(() => { const focusInput = () => { // Try using the ref first if (otpContainerRef.current) { const hiddenInput = otpContainerRef.current.querySelector( "input" ) as HTMLInputElement; if (hiddenInput) { hiddenInput.focus(); return; } } // Fallback: query the DOM const otpContainer = document.querySelector( '[data-slot="input-otp"]' ); if (!otpContainer) return; const hiddenInput = otpContainer.querySelector( "input" ) as HTMLInputElement; if (hiddenInput) { hiddenInput.focus(); return; } // Last resort: click the first slot const firstSlot = otpContainer.querySelector( '[data-slot="input-otp-slot"]' ) as HTMLElement; if (firstSlot) { firstSlot.click(); } }; // Use requestAnimationFrame to wait for the next paint requestAnimationFrame(() => { requestAnimationFrame(() => { focusInput(); }); }); }, []); return (

{t("otpAuth")}

{t("otpAuthDescription")}

(
{ field.onChange(value); if (value.length === 6) { form.handleSubmit(onSubmit)(); } }} >
)} /> {error && ( {error} )}
); }