'use client' import { useState } from 'react' import { useTranslations } from 'next-intl' const LOGOS = '/nw-themes/nw-ryu/nw-images/nw-logos' type Msg = { success: boolean; text: string } | null async function post(action: string, extra: Record): Promise<{ success: boolean; message: string; qrCodeUrl?: string; secretKey?: string }> { const res = await fetch('/api/account/2fa', { method: 'POST', headers: { 'Content-Type': 'application/json' }, credentials: 'same-origin', body: JSON.stringify({ action, ...extra }), }) return res.json() } /** Ojo para mostrar/ocultar un campo de contraseña/token. */ function EyeToggle({ shown, onToggle }: { shown: boolean; onToggle: () => void }) { const t = useTranslations('UI') return ( ) } export function TwoFactorLogin({ enabled }: { enabled: boolean }) { return (


{enabled ? : }
) } /* ------------------------------ Activar + QR ------------------------------- */ function ActivateFlow() { const t = useTranslations('UI') const [password, setPassword] = useState('') const [showPassword, setShowPassword] = useState(false) const [token, setToken] = useState('') const [showToken, setShowToken] = useState(false) const [busy, setBusy] = useState(false) const [msg, setMsg] = useState(null) const [qr, setQr] = useState<{ qrCodeUrl: string; secretKey: string } | null>(null) const [done, setDone] = useState(false) // verificación const [code, setCode] = useState('') const [vBusy, setVBusy] = useState(false) const [vMsg, setVMsg] = useState(null) const [copied, setCopied] = useState(false) async function activate(e: React.FormEvent) { e.preventDefault() if (busy) return setBusy(true) setMsg(null) try { const d = await post('activate', { password, securityToken: token }) setMsg({ success: !!d.success, text: d.message }) if (d.success && d.qrCodeUrl && d.secretKey) setQr({ qrCodeUrl: d.qrCodeUrl, secretKey: d.secretKey }) } catch { setMsg({ success: false, text: t('twofa.errGeneric') }) } finally { setBusy(false) } } async function verify(e: React.FormEvent) { e.preventDefault() if (vBusy) return setVBusy(true) setVMsg(null) try { const d = await post('verify', { code }) setVMsg({ success: !!d.success, text: d.message }) if (d.success) setDone(true) } catch { setVMsg({ success: false, text: t('twofa.errGeneric') }) } finally { setVBusy(false) } } function copySecret() { if (!qr) return navigator.clipboard?.writeText(qr.secretKey).then(() => { setCopied(true) setTimeout(() => setCopied(false), 1500) }) } return ( <>
{!qr && ( )}
setPassword(e.target.value)} disabled={!!qr} /> setShowPassword((s) => !s)} />
setToken(e.target.value)} disabled={!!qr} /> setShowToken((s) => !s)} />

{msg && (
{msg.text}
)} {qr && (

{t('twofa.step1')}

Google Play App Store

{t('twofa.step2')}

QR Code

{t('twofa.copyKeyNote')}



{t('twofa.step3')}

setCode(e.target.value)} disabled={done} />

{vMsg && (
{vMsg.text}
)}
)} ) } /* ------------------------------- Desactivar -------------------------------- */ function DisableForm() { const t = useTranslations('UI') const [code, setCode] = useState('') const [busy, setBusy] = useState(false) const [msg, setMsg] = useState(null) const [done, setDone] = useState(false) async function disable(e: React.FormEvent) { e.preventDefault() if (busy) return setBusy(true) setMsg(null) try { const d = await post('disable', { code }) setMsg({ success: !!d.success, text: d.message }) if (d.success) setDone(true) } catch { setMsg({ success: false, text: t('twofa.errGeneric') }) } finally { setBusy(false) } } return ( <>

{t('twofa.enabledNotice')}

{t('twofa.disableInstruction')}


setCode(e.target.value)} disabled={done} />

{msg && (
{msg.text}
)} ) }