/* global React, PrimaryButton */ // Yomee — Analyzing Screen // Transitional screen that sits between Upload and the Dashboard / Confidence // Gate. Simulates the back-end work in two phases so the user understands // what's happening AND that we don't keep their files: // 1) "Analizando tus estados de cuenta…" // 2) "Eliminando tus archivos de forma segura…" // After both phases complete, calls onDone() so the Router can advance to // the next screen (review or radiografía). // // Total duration ≈ 5s of work (varied per step so the rhythm feels human // rather than metronomic) + ~1.6s confetti hold before the Router advances. // Pocopin mascot (pocopin-4.png) is the focal element with a soft floating // loop while work is in progress, and a small bounce on completion. const { useState: useAnalyzingState, useEffect: useAnalyzingEffect } = React; // ──────────────────────────────────────────────── // Step definitions — order matters; each duration is the visible "in // progress" time before the row flips to its done state. // ──────────────────────────────────────────────── const ANALYZING_STEPS = [ { key: "analyze", inProgress: "Analizando tus estados de cuenta", done: "Análisis completo", duration: 1900, }, { key: "delete", inProgress: "Eliminando tus archivos de forma segura", done: "Archivos eliminados", duration: 1300, }, { key: "build", inProgress: "Creando tu radiografía", done: "Radiografía lista", duration: 1800, }, ]; // Confetti hold time — how long the celebration plays before the Router // advances. Long enough for users to register the moment, short enough to // stay snappy. const CONFETTI_HOLD_MS = 1600; // Tiny in-row spinner — same visual language as the upload area's spinner // so this screen feels like a continuation of that interaction. function StepSpinner({ size = 20 }) { return (
); } // Filled mint check — matches the success indicator on file rows. function StepCheck({ size = 22 }) { return (
); } // Empty placeholder dot for steps that haven't started yet. function StepPending({ size = 20 }) { return (
); } // ──────────────────────────────────────────────── // Confetti — lightweight CSS-only burst. Generates ~36 colored chips that // fall from the top with random horizontal drift, rotation and delay. // Colors are pulled from the brand palette so the burst feels on-system. // ──────────────────────────────────────────────── const CONFETTI_COLORS = [ "var(--yo-mint-700)", "var(--yo-forest-500)", "var(--yo-orange-soft)", "var(--yo-coral)", "var(--yo-yellow)", "var(--yo-lavender)", ]; function Confetti({ count = 36 }) { const pieces = React.useMemo(() => { return Array.from({ length: count }, (_, i) => { const left = Math.random() * 100; const delay = Math.random() * 350; const duration = 1200 + Math.random() * 900; const drift = (Math.random() - 0.5) * 120; const rot = Math.random() * 720 - 360; const size = 6 + Math.random() * 6; const color = CONFETTI_COLORS[Math.floor(Math.random() * CONFETTI_COLORS.length)]; const isCircle = Math.random() < 0.3; return { left, delay, duration, drift, rot, size, color, isCircle, i }; }); }, [count]); return ( ); } function StepRow({ status, label }) { const isDone = status === "done"; const isActive = status === "active"; return (
{isDone ? ( ) : isActive ? ( ) : ( )}
{label}
); } // ──────────────────────────────────────────────── // Main screen // ──────────────────────────────────────────────── function AnalyzingScreen({ fileCount = 0, onDone }) { // 0..ANALYZING_STEPS.length — number of steps that have completed. const [completed, setCompleted] = useAnalyzingState(0); const [allDone, setAllDone] = useAnalyzingState(false); // Drives the confetti overlay. Flips on as soon as the last step finishes // and stays on until the Router advances away from this screen. const [showConfetti, setShowConfetti] = useAnalyzingState(false); useAnalyzingEffect(() => { let cancelled = false; const timeouts = []; let elapsed = 0; ANALYZING_STEPS.forEach((step, i) => { elapsed += step.duration; const t = setTimeout(() => { if (cancelled) return; setCompleted(i + 1); if (i === ANALYZING_STEPS.length - 1) { setAllDone(true); setShowConfetti(true); // Navigation no longer happens automatically — the user must press // the CONTINUAR button below, which becomes enabled once allDone // flips. This acts as a stopper before the dashboard so users can // register the completion moment on their own time. } }, elapsed); timeouts.push(t); }); return () => { cancelled = true; timeouts.forEach((t) => clearTimeout(t)); }; }, []); const currentStep = completed; // index of the step that's currently active const headline = allDone ? "¡Listo!" : currentStep === 0 ? "Estamos analizando tus archivos" : currentStep === 1 ? "Protegiendo tu información" : "Construyendo tu radiografía"; const subhead = allDone ? "Tu radiografía está lista" : currentStep === 0 ? "Pocopin está leyendo cada movimiento de tus estados de cuenta" : currentStep === 1 ? "Borramos tus archivos en cuanto terminamos. No los guardamos." : "Estamos uniendo todo para mostrarte tu situación real"; return (
{/* Content — vertically centered, with a slight top bias so the mascot sits higher than dead-center which feels more "active". */}
{/* Mascot — soft floating loop while work is in progress, gentle pop-in on mount and a celebratory bounce on completion. */}
{/* Soft halo ring behind the mascot — pulses while loading. */} {/* Headline */}

{headline}

{subhead}

{/* File count chip — only when meaningful (≥ 1). */} {fileCount > 0 && !allDone && (
{fileCount === 1 ? "1 estado de cuenta" : `${fileCount} estados de cuenta`}
)} {/* Step list */}
{ANALYZING_STEPS.map((step, i) => { let status = "pending"; if (i < completed) status = "done"; else if (i === completed) status = "active"; const label = status === "done" ? step.done : step.inProgress + (status === "active" ? "…" : ""); return ; })}
{/* Privacy note — reinforces the "we don't keep your files" promise. */}
Tus archivos se eliminan de forma permanente una vez procesados
{/* CONTINUAR stopper — disabled while the simulation is running, enabled once all steps complete. Matches the Start Screen primary CTA style (PrimaryButton, primary variant). */}
onDone && onDone()} disabled={!allDone} > CONTINUAR
{/* Celebratory confetti — plays once all 3 steps finish, before the Router advances. Fixed-overlay so it spans the full screen. */} {showConfetti && }
); } Object.assign(window, { AnalyzingScreen, ANALYZING_STEPS });