// Yomee — Question 1 Screen ("Hagamos números") // Fifth onboarding step. Slider + editable number combo for total debt and monthly payment. // Uses OnboardingHeader from OnboardingShared.jsx; PrimaryButton from Shared.jsx /* global React, OnboardingHeader, PrimaryButton */ const { useState: useStateQ1, useEffect: useEffectQ1, useRef: useRefQ1 } = React; function CurrencySliderField({ value, onChange, min, max, step, disabled }) { const [draft, setDraft] = useStateQ1(null); const inputRef = useRefQ1(null); const fmt = (n) => "$" + (Number.isFinite(n) ? n : 0).toLocaleString("en-US"); const clamp = (n) => Math.max(min, Math.min(max, n)); const snap = (n) => Math.round(n / step) * step; const handleInputChange = (raw) => { const digits = raw.replace(/[^\d]/g, "").slice(0, 10); setDraft(digits); const n = digits === "" ? 0 : parseInt(digits, 10); onChange(clamp(n)); }; const handleBlur = () => { setDraft(null); }; const displayed = draft !== null ? draft === "" ? "" : "$" + parseInt(draft, 10).toLocaleString("en-US") : fmt(value); const pct = max > min ? ((value - min) / (max - min)) * 100 : 0; const GREEN = "#2BAE80"; const TRACK_GRAY = "#E0E0E0"; const sliderClassRef = useRefQ1( "yo-sl-" + Math.random().toString(36).slice(2, 8), ); const sliderClass = sliderClassRef.current; return (
!disabled && inputRef.current && inputRef.current.focus()} style={{ width: "100%", boxSizing: "border-box", borderRadius: 14, background: "#fff", display: "flex", alignItems: "center", justifyContent: "center", padding: "18px 20px", cursor: disabled ? "not-allowed" : "text", }} > { const digits = String(value || "").replace(/[^\d]/g, ""); setDraft(digits === "0" ? "" : digits); requestAnimationFrame(() => { try { e.target.select(); } catch (_) {} }); }} onBlur={handleBlur} onChange={(e) => handleInputChange(e.target.value)} style={{ width: "100%", border: "none", outline: "none", background: "transparent", textAlign: "center", fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 28, letterSpacing: "0.005em", color: "#1a1a1a", }} />
onChange(snap(clamp(parseInt(e.target.value, 10))))} disabled={disabled} className={sliderClass} style={{ display: "block", width: "100%", height: 22, WebkitAppearance: "none", appearance: "none", outline: "none", background: "transparent", margin: 0, padding: 0, }} />
{fmt(min)} {fmt(max)}
); } function Question1Screen({ onBack, onContinue }) { const TOTAL_MIN = 0; const TOTAL_MAX = 500000; const TOTAL_STEP = 5000; const MONTHLY_MIN = 0; const MONTHLY_DEFAULT = 3200; // Reactive bind to the active persona. Switching persona via the Demo // pill must snap the sliders + checkbox to the new persona's values // instantly — no remount required. const yomeeUser = (window.useYomeeUser && window.useYomeeUser()) || {}; const personaTotal = Number.isFinite(yomeeUser.debt) ? yomeeUser.debt : 65000; const personaMonthly = Number.isFinite(yomeeUser.payment) ? yomeeUser.payment : MONTHLY_DEFAULT; const personaCantPay = yomeeUser.payment === 0; const [total, setTotal] = useStateQ1(personaTotal); const [monthly, setMonthly] = useStateQ1(personaMonthly); const [cantPay, setCantPay] = useStateQ1(personaCantPay); // When the active persona changes, snap every field back to that // persona's values — keyed on personaKey so this only fires on switch. useEffectQ1(() => { setTotal(personaTotal); setMonthly(personaMonthly); setCantPay(personaCantPay); // eslint-disable-next-line react-hooks/exhaustive-deps }, [yomeeUser.personaKey]); const monthlyMax = Math.max(0, total); const monthlyStep = total <= 50000 ? 500 : total <= 200000 ? 1000 : 5000; useEffectQ1(() => { if (monthly > monthlyMax) setMonthly(monthlyMax); // eslint-disable-next-line react-hooks/exhaustive-deps }, [monthlyMax]); const submit = () => { if (allValid) { onContinue({ total, monthly: cantPay ? 0 : monthly }); } }; const allValid = total > 0 && (cantPay || monthly > 0); const handleCantPayToggle = () => { setCantPay((prev) => { const next = !prev; if (next) { setMonthly(0); } else { setMonthly(Math.min(MONTHLY_DEFAULT, Math.max(0, total))); } return next; }); }; return (

Hagamos números

¿Cuánto debes en total hoy?
Incluye tarjetas, préstamos o financiamientos activos.
¿Cuánto pagas cada mes?
Si eres totalero, escribe la misma cantidad que arriba.
Puedes usar montos aproximados
Continuar
); } window.Question1Screen = Question1Screen; window.CurrencySliderField = CurrencySliderField;