"use client"; import Image from "next/image"; import Link from "next/link"; import { useState, useRef, Suspense, useEffect } from "react"; import { useRouter, useSearchParams } from "next/navigation"; import { LanguageToggle } from "@/components/language-toggle"; import { useLanguage } from "@/lib/i18n-context"; function VerifyContent() { const router = useRouter(); const searchParams = useSearchParams(); const email = searchParams.get("email") || ""; const { t } = useLanguage(); const v = t.auth.verify; const [otp, setOtp] = useState(["", "", "", "", "", ""]); const [loading, setLoading] = useState(false); const [resending, setResending] = useState(false); const [error, setError] = useState(""); const [errorStep, setErrorStep] = useState(""); const [success, setSuccess] = useState(""); const [countdown, setCountdown] = useState(0); const inputRefs = useRef<(HTMLInputElement | null)[]>([]); useEffect(() => { inputRefs.current[0]?.focus(); }, []); useEffect(() => { if (countdown <= 0) return; const timer = setTimeout(() => setCountdown((c) => c - 1), 1000); return () => clearTimeout(timer); }, [countdown]); function handleOtpChange(index: number, value: string) { if (!/^\d*$/.test(value)) return; const newOtp = [...otp]; newOtp[index] = value.slice(-1); setOtp(newOtp); if (value && index < 5) { inputRefs.current[index + 1]?.focus(); } } function handleKeyDown(index: number, e: React.KeyboardEvent) { if (e.key === "Backspace" && !otp[index] && index > 0) { inputRefs.current[index - 1]?.focus(); } } function handlePaste(e: React.ClipboardEvent) { e.preventDefault(); const pasted = e.clipboardData.getData("text").replace(/\D/g, "").slice(0, 6); if (!pasted) return; const newOtp = [...otp]; pasted.split("").forEach((char, i) => { if (i < 6) newOtp[i] = char; }); setOtp(newOtp); const nextIndex = Math.min(pasted.length, 5); inputRefs.current[nextIndex]?.focus(); } async function handleSubmit(e: React.FormEvent) { e.preventDefault(); setError(""); setErrorStep(""); const otpCode = otp.join(""); if (otpCode.length < 6) { setError(v.otpTooShort); return; } const rawData = sessionStorage.getItem("registerData"); if (!rawData) { setError(v.noData); return; } const { role } = JSON.parse(rawData); setLoading(true); try { const res = await fetch("/api/auth/verify-otp", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email, otp: otpCode }), }); const data = await res.json(); if (!res.ok) { const backendMessage = data?.error || data?.responseDesc || data?.message || v.verifyFail; setError(backendMessage); setErrorStep(data?.step || ""); return; } const parsedData = JSON.parse(rawData); if (role === "seller") { const registerData = { ...parsedData, email, otpVerified: true }; const registerRes = await fetch("/api/auth/finalize-register", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ role: "seller", registerData }), }); const registerResult = await registerRes.json(); if (!registerRes.ok) { setError(registerResult?.error || v.registerFail); setErrorStep(registerResult?.step || ""); return; } if (registerResult?.token) { sessionStorage.setItem("token", registerResult.token); sessionStorage.setItem("role", "seller"); } sessionStorage.removeItem("registerData"); sessionStorage.removeItem("otpVerified"); sessionStorage.removeItem("otpVerifiedEmail"); setSuccess(v.successSeller); setTimeout(() => { router.push("/dashboard"); }, 1000); return; } sessionStorage.setItem("registerData", JSON.stringify({ ...parsedData, email, otpVerified: true })); sessionStorage.setItem("otpVerified", "true"); sessionStorage.setItem("otpVerifiedEmail", email); setSuccess(v.successBuyer); setTimeout(() => { router.push("/register/complete"); }, 1000); } catch { setError(t.common.connectionError); } finally { setLoading(false); } } async function handleResend() { if (countdown > 0) return; setError(""); setErrorStep(""); setResending(true); try { const res = await fetch("/api/auth/send-otp", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ email }), }); if (res.ok) { setOtp(["", "", "", "", "", ""]); inputRefs.current[0]?.focus(); setCountdown(60); } else { const data = await res.json(); setError(data.error || t.common.connectionError); } } catch { setError(t.common.connectionError); } finally { setResending(false); } } return (
{/* Left Side */}

{v.secureYourFuture}

{v.verifyIdentity}

99.9%

{v.transactionSecurity}

256-bit

{v.bankLevelEncryption}

{/* Right Side */}
{/* Logo */}
Ina Trading
mark_email_read

{v.title}

{v.subtitle}{" "} {email} {v.subtitleSuffix}

{error && (
{error}
{errorStep ? (
Step: {errorStep}
) : null}
)} {success && (
{success}
)} {/* OTP Grid */}
{otp.map((digit, index) => ( { inputRefs.current[index] = el; }} type="text" inputMode="numeric" maxLength={1} value={digit} onChange={(e) => handleOtpChange(index, e.target.value)} onKeyDown={(e) => handleKeyDown(index, e)} placeholder="•" className="otp-input w-14 h-16 text-center text-2xl font-bold rounded-xl border-none bg-surface-container-highest text-on-surface transition-all focus:bg-surface-container-lowest focus:ring-0" /> ))}
{v.noCode}
shield {v.securityTitle}

{v.securityDesc}

close {t.common.cancel}
); } export default function VerifyPage() { return ( ); }