// vita-security.jsx — facial recognition scan + data-security sheet function FaceScan({ t, persona, onDone, onCancel, enroll, mode, badgeText, alignText, doneText, subtitleText }) { const accent = persona.accent; const videoRef = React.useRef(null); const [hasCam, setHasCam] = React.useState(false); const [phase, setPhase] = React.useState('align'); // align | scanning | done const [progress, setProgress] = React.useState(0); const progRef = React.useRef(0); // camera (graceful fallback if denied/unavailable) React.useEffect(() => { let stream; const md = navigator.mediaDevices; if (md && md.getUserMedia) { md.getUserMedia({ video: { facingMode: 'user' }, audio: false }) .then(s => { stream = s; if (videoRef.current) { videoRef.current.srcObject = s; videoRef.current.play().catch(() => {}); } setHasCam(true); }) .catch(() => setHasCam(false)); } return () => { if (stream) stream.getTracks().forEach(tr => tr.stop()); }; }, []); // scan sequence (setInterval — reliable in preview) React.useEffect(() => { const t1 = setTimeout(() => setPhase('scanning'), 900); let iv; const t2 = setTimeout(() => { iv = setInterval(() => { progRef.current = Math.min(100, progRef.current + 3.2); setProgress(progRef.current); if (progRef.current >= 100) { clearInterval(iv); setPhase('done'); setTimeout(() => onDone && onDone(), 1100); } }, 70); }, 950); return () => { clearTimeout(t1); clearTimeout(t2); clearInterval(iv); }; }, []); const done = phase === 'done'; const ring = done ? t.green : accent; const status = phase === 'align' ? (mode === 'switch' ? (alignText || 'Confirma tu identidad') : enroll ? 'Registra tu rostro' : 'Centra tu rostro en el marco') : phase === 'scanning' ? (mode === 'switch' ? 'Verificando…' : enroll ? 'Creando tu identidad biométrica…' : 'Verificando tu identidad…') : (mode === 'switch' ? (doneText || 'Identidad confirmada') : enroll ? 'Rostro registrado' : 'Identidad verificada'); const V = 248; // viewport size return (
{Icon.chevron({ s: 18, c: t.textSoft, w: 2.5 })}
{Icon.faceid({ s: 16, c: accent })} {badgeText || 'RECONOCIMIENTO FACIAL'}
{/* viewport */}
{/* camera feed */}