'use client'; import React, { useState, useRef, useEffect, Suspense } from 'react'; import { useRouter, useSearchParams } from 'next/navigation'; import Link from 'next/link'; function VerifyEmailContent() { const router = useRouter(); const searchParams = useSearchParams(); const email = searchParams.get('email') || ''; const error = searchParams.get('error'); const [code, setCode] = useState(['', '', '', '', '', '']); const [isLoading, setIsLoading] = useState(false); const [message, setMessage] = useState(null); const [errorMsg, setErrorMsg] = useState(null); const [isResending, setIsResending] = useState(false); const inputRefs = useRef<(HTMLInputElement | null)[]>([]); useEffect(() => { if (error === 'invalid_token') { setErrorMsg('Verification link is invalid or expired. Please enter your code manually or request a new one.'); } else if (error === 'missing_token') { setErrorMsg('Invalid verification link.'); } else if (error === 'server_error') { setErrorMsg('Something went wrong. Please try again.'); } }, [error]); // Auto-focus first input useEffect(() => { inputRefs.current[0]?.focus(); }, []); const handleInput = (index: number, value: string) => { // Handle paste of full code if (value.length > 1) { const digits = value.replace(/\D/g, '').slice(0, 6).split(''); const newCode = [...code]; digits.forEach((digit, i) => { if (index + i < 6) newCode[index + i] = digit; }); setCode(newCode); const nextIndex = Math.min(index + digits.length, 5); inputRefs.current[nextIndex]?.focus(); // Auto-submit if all 6 digits entered if (newCode.every(d => d !== '')) { submitCode(newCode.join('')); } return; } const digit = value.replace(/\D/g, ''); const newCode = [...code]; newCode[index] = digit; setCode(newCode); if (digit && index < 5) { inputRefs.current[index + 1]?.focus(); } // Auto-submit if all 6 digits entered if (newCode.every(d => d !== '')) { submitCode(newCode.join('')); } }; const handleKeyDown = (index: number, e: React.KeyboardEvent) => { if (e.key === 'Backspace' && !code[index] && index > 0) { inputRefs.current[index - 1]?.focus(); } }; const submitCode = async (fullCode: string) => { setIsLoading(true); setErrorMsg(null); setMessage(null); try { const response = await fetch('/api/auth/verify-email', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email, code: fullCode }), }); const data = await response.json(); if (!response.ok) { setErrorMsg(data.error || 'Verification failed'); setCode(['', '', '', '', '', '']); inputRefs.current[0]?.focus(); setIsLoading(false); return; } setMessage('Email verified! Redirecting to login...'); setTimeout(() => { router.push('/auth/login?verified=true'); }, 1500); } catch { setErrorMsg('Something went wrong. Please try again.'); setIsLoading(false); } }; const handleResend = async () => { setIsResending(true); setErrorMsg(null); setMessage(null); try { const response = await fetch('/api/auth/resend-verification', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email }), }); const data = await response.json(); if (!response.ok) { setErrorMsg(data.error || 'Failed to resend code'); } else { setMessage('A new verification code has been sent to your email.'); } } catch { setErrorMsg('Failed to resend code. Please try again.'); } finally { setIsResending(false); } }; return (
{/* Logo */}
My Weekly ToDo's
{/* Title */}

Verify your email

We sent a 6-digit code to {email}

{/* Messages */} {errorMsg && (
{errorMsg}
)} {message && (
{message}
)} {/* Code Input */}
{code.map((digit, index) => ( { inputRefs.current[index] = el; }} type="text" inputMode="numeric" maxLength={1} value={digit} onChange={e => handleInput(index, e.target.value)} onKeyDown={e => handleKeyDown(index, e)} onPaste={e => { e.preventDefault(); const pasted = e.clipboardData.getData('text').replace(/\D/g, '').slice(0, 6); if (pasted) handleInput(index, pasted); }} disabled={isLoading} style={{ width: '48px', height: '56px', textAlign: 'center', fontSize: '1.5rem', fontWeight: 700, fontFamily: "'Courier New', monospace", background: '#f8f9fa', border: digit ? '2px solid #667eea' : '2px solid #d0d5dd', borderRadius: '10px', color: '#667eea', outline: 'none', transition: 'border-color 0.2s, box-shadow 0.2s', caretColor: '#667eea', boxSizing: 'border-box', }} onFocus={e => { e.target.style.borderColor = '#667eea'; e.target.style.boxShadow = '0 0 0 3px rgba(102, 126, 234, 0.15)'; }} onBlur={e => { e.target.style.borderColor = digit ? '#667eea' : '#d0d5dd'; e.target.style.boxShadow = 'none'; }} /> ))}
{/* Verify Button */} {/* Resend */}
Didn't receive the code?{' '}
{/* Back to login */}
← Back to login

Simple. Beautiful. Yours.

); } export default function VerifyEmailPage() { return (
My Weekly ToDo's

Loading...

}>
); }