'use client'; import React, { useState, useEffect, useRef } from 'react'; import { X, User, Lock, Mail, Phone, MapPin, Sparkles, LogIn, UserPlus, Shield, LogOut, ArrowRight, CheckCircle2, RotateCcw, Smartphone, KeyRound, Fingerprint, Check, Eye, EyeOff, AlertCircle } from 'lucide-react'; import { useAuth } from '@/context/AuthContext'; import { useBrand } from '@/context/BrandContext'; import Link from 'next/link'; export const AuthModal: React.FC = () => { const { user, sendOtp, verifyOtp, register, logout, isAuthModalOpen, closeAuthModal } = useAuth(); const { currentBrand } = useBrand(); // Mode when not logged in: 'login' | 'register' const [mode, setMode] = useState<'login' | 'register'>('login'); const [step, setStep] = useState<'request' | 'verify'>('request'); const [identifier, setIdentifier] = useState(''); const [maskedPhone, setMaskedPhone] = useState(''); const [otpDigits, setOtpDigits] = useState(['', '', '', '', '', '']); const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [phone, setPhone] = useState(''); const [city, setCity] = useState('Cali'); const [address, setAddress] = useState(''); const [error, setError] = useState(null); const [successMsg, setSuccessMsg] = useState(null); const [loading, setLoading] = useState(false); const [resendTimer, setResendTimer] = useState(0); // Sub-tabs when user is logged in: 'profile' | 'security' | '2fa' const [profileTab, setProfileTab] = useState<'profile' | 'security' | '2fa'>('profile'); // Change password form state const [currentPassword, setCurrentPassword] = useState(''); const [newPassword, setNewPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [pwdMsg, setPwdMsg] = useState(null); const [pwdError, setPwdError] = useState(null); // 2FA state const [is2FaEnabled, setIs2FaEnabled] = useState(false); const [twoFactorMsg, setTwoFactorMsg] = useState(null); const inputRefs = useRef<(HTMLInputElement | null)[]>([]); useEffect(() => { if (user) { setIs2FaEnabled(user.twoFactorEnabled !== false); } }, [user]); // Contador de reenvío useEffect(() => { let interval: any = null; if (resendTimer > 0) { interval = setInterval(() => setResendTimer((prev) => prev - 1), 1000); } return () => clearInterval(interval); }, [resendTimer]); if (!isAuthModalOpen) return null; // Paso 1: Enviar OTP const handleSendOtp = async (e: React.FormEvent) => { e.preventDefault(); if (!identifier.trim()) { setError('Por favor ingresa tu número de celular o correo.'); return; } setError(null); setLoading(true); const res = await sendOtp(identifier); setLoading(false); if (res.success) { setMaskedPhone(res.phone || identifier); setSuccessMsg(res.message || 'Código enviado a tu WhatsApp'); setStep('verify'); setResendTimer(60); setOtpDigits(['', '', '', '', '', '']); setTimeout(() => inputRefs.current[0]?.focus(), 150); } else { setError(res.error || 'Error al enviar código de seguridad'); } }; // Paso 2: Verificar OTP const handleOtpChange = (index: number, val: string) => { const cleanVal = val.replace(/\D/g, '').slice(-1); const newDigits = [...otpDigits]; newDigits[index] = cleanVal; setOtpDigits(newDigits); if (cleanVal && index < 5) { inputRefs.current[index + 1]?.focus(); } if (cleanVal && index === 5) { const fullCode = newDigits.join(''); if (fullCode.length === 6) { submitFullCode(fullCode); } } }; const handleKeyDown = (index: number, e: React.KeyboardEvent) => { if (e.key === 'Backspace' && !otpDigits[index] && index > 0) { inputRefs.current[index - 1]?.focus(); } }; const submitFullCode = async (code: string) => { setError(null); setLoading(true); const res = await verifyOtp(identifier, code); setLoading(false); if (!res.success) { setError(res.error || 'Código incorrecto'); } }; const handleVerifySubmit = async (e: React.FormEvent) => { e.preventDefault(); const fullCode = otpDigits.join(''); if (fullCode.length < 4) { setError('Ingresa el código completo de 6 dígitos.'); return; } await submitFullCode(fullCode); }; const handleRegisterSubmit = async (e: React.FormEvent) => { e.preventDefault(); setError(null); setLoading(true); const res = await register({ name, email, phone, city, address }); setLoading(false); if (!res.success) { setError(res.error || 'Error al registrarse'); return; } if (res.otpSent) { setIdentifier(phone); setMaskedPhone(res.maskedPhone || phone); setSuccessMsg(res.message || 'Código enviado a tu WhatsApp'); setStep('verify'); setResendTimer(60); setOtpDigits(['', '', '', '', '', '']); setTimeout(() => inputRefs.current[0]?.focus(), 150); } else { closeAuthModal(); } }; // Cambiar Contraseña const handleChangePassword = async (e: React.FormEvent) => { e.preventDefault(); setPwdError(null); setPwdMsg(null); if (!user) return; if (newPassword !== confirmPassword) { setPwdError('La nueva contraseña y la confirmación no coinciden.'); return; } setLoading(true); try { const res = await fetch('/api/auth/change-password', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: user.id, currentPassword, newPassword, confirmPassword, }), }); const data = await res.json(); setLoading(false); if (data.success) { setPwdMsg('✅ ¡Contraseña actualizada exitosamente!'); setCurrentPassword(''); setNewPassword(''); setConfirmPassword(''); } else { setPwdError(data.error || 'Error al cambiar contraseña'); } } catch (err: any) { setLoading(false); setPwdError(err.message || 'Error de conexión'); } }; // Activar / Desactivar 2FA const handleToggle2Fa = async () => { if (!user) return; const newStatus = !is2FaEnabled; setIs2FaEnabled(newStatus); setTwoFactorMsg(null); try { const res = await fetch('/api/auth/toggle-2fa', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ userId: user.id, twoFactorEnabled: newStatus, twoFactorMethod: 'whatsapp_otp', }), }); const data = await res.json(); if (data.success) { setTwoFactorMsg( newStatus ? '🛡️ Autenticación 2FA por WhatsApp ACTIVADA para tu cuenta.' : '⚪ Autenticación 2FA desactivada.' ); } } catch (e) { console.error(e); } }; return (
{/* LOGGED-IN USER: PROFILE & SECURITY SUITE */} {user ? (
{/* Top Avatar & User Name */}
{user.name.charAt(0).toUpperCase()}

{user.name}

{user.email}

{user.role === 'admin' || user.phone?.replace(/\D/g, '').endsWith('3167455877') || user.email?.toLowerCase() === 'carlos.andres.lasso@gmail.com' ? '👑 Super Administrador' : user.role === 'operator' ? '📦 Operador Logística' : '🛍️ Cliente VIP'}
{/* Profile Navigation Tabs */}
{/* TAB 1: User Profile Info */} {profileTab === 'profile' && (

📱 WhatsApp / Celular: {user.phone}

📍 Ciudad: {user.city || 'Cali'}

{user.address &&

🏠 Dirección: {user.address}

}
{user.role === 'admin' || user.role === 'operator' || user.phone?.replace(/\D/g, '').endsWith('3167455877') || user.email?.toLowerCase() === 'carlos.andres.lasso@gmail.com' ? ( Ir al Panel de Control Admin ) : null}
)} {/* TAB 2: Change Password Form */} {profileTab === 'security' && (

Cambio de Contraseña Seguro

Puedes usar tu clave actual o el PIN Maestro de Emergencia (1978).

{pwdMsg && (
{pwdMsg}
)} {pwdError && (
{pwdError}
)}
setCurrentPassword(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setNewPassword(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
setConfirmPassword(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-400" />
)} {/* TAB 3: 2FA & Biometrics Settings */} {profileTab === '2fa' && (
{twoFactorMsg && (
{twoFactorMsg}
)} {/* 2FA Toggle Card */}

2FA con WhatsApp OTP

Código de 6 dígitos a tu celular
{/* Toggle Button */}

{is2FaEnabled ? '🟢 2FA Activo: Cada inicio de sesión requerirá verificación por WhatsApp.' : '⚪ 2FA Desactivado: Podrás iniciar sesión directamente con tu contraseña o biometría.'}

{/* Biometrics Card */}

Acceso Biométrico / Passkey

Huella dactilar o Face ID nativo

Inicia sesión en 1 segundo usando el sensor de huella de tu teléfono o cámara de tu portátil.

)}
) : ( /* LOGIN WITH 2FA / OTP OR REGISTER */

{step === 'verify' ? 'Verificación de Seguridad' : mode === 'login' ? 'Acceso Seguro OTP' : 'Crear Cuenta'}

{step === 'verify' ? `Ingresa el código enviado a ${maskedPhone}` : mode === 'login' ? 'Validación segura vía WhatsApp con código de 6 dígitos' : 'Regístrate para compras y seguimiento de pedidos'}

{/* Mode Switch Tabs (Only in request step) */} {step === 'request' && (
)} {error && (
{error}
)} {successMsg && step === 'verify' && (
{successMsg}
)} {/* STEP 1: Request OTP */} {step === 'request' && mode === 'login' && (
setIdentifier(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-2xl px-4 py-3 text-white text-sm outline-hidden focus:border-purple-500 transition-all" />

Te enviaremos un código de seguridad de 6 dígitos a tu WhatsApp.

Autenticación 2FA Verificada

Acceso seguro para clientes y administradores con validación en tiempo real.

)} {/* STEP 2: Verify 6-digit OTP */} {step === 'verify' && (
{otpDigits.map((digit, idx) => ( { inputRefs.current[idx] = el; }} type="text" inputMode="numeric" maxLength={1} value={digit} onChange={(e) => handleOtpChange(idx, e.target.value)} onKeyDown={(e) => handleKeyDown(idx, e)} className={`w-11 h-13 sm:w-12 sm:h-14 text-center text-xl font-black rounded-2xl bg-neutral-900 border text-white outline-hidden transition-all ${ digit ? 'border-purple-500 shadow-[0_0_12px_rgba(168,85,247,0.35)]' : 'border-neutral-800 focus:border-purple-500' }`} /> ))}
{/* Acceso de Respaldo si WhatsApp no envía el código */}
)} {/* Register form */} {step === 'request' && mode === 'register' && (
setName(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-500" />
setEmail(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-500" />
setPhone(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-500" />
setCity(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-500" />
setAddress(e.target.value)} className="w-full bg-neutral-900 border border-neutral-800 rounded-xl px-3 py-2 text-white outline-hidden focus:border-purple-500" />
)}
)}
); };