// ───────────────────────────────────────────────────────────── // main.jsx — App shell, state, routing, PDF wire-up // ───────────────────────────────────────────────────────────── const { useState, useEffect, useRef, useCallback } = React; // Detect if we are inside an iframe (e.g. embedded in WordPress). // Adds .is-embedded to
so CSS can collapse `min-height: 100vh`, // which would otherwise force the body to fill the iframe and make // auto-resize stick to the tallest screen ever rendered. if (typeof window !== 'undefined' && window.parent && window.parent !== window) { try { document.body.classList.add('is-embedded'); } catch (e) { /* noop */ } } // Scrolls the diagnostic view to top. // When embedded inside an iframe (e.g. WordPress page), also notifies // the parent so the OUTER page scrolls to the iframe's top — otherwise // the user sees the bottom of the iframe after each view change. function scrollDiagToTop() { try { window.scrollTo({ top: 0, behavior: 'smooth' }); } catch (e) { /* noop */ } if (window.parent && window.parent !== window) { try { window.parent.postMessage({ type: 'alfa-diag:scroll-to-top' }, '*'); } catch (e) { /* cross-origin / silent */ } } } function App() { const [view, setView] = useState('inicio'); // inicio | encuesta | resultados | gracias const [areaIdx, setAreaIdx] = useState(0); const [respuestas, setRespuestas] = useState({}); const [resultados, setResultados] = useState(null); const [leadData, setLeadData] = useState(null); const [pdfBlob, setPdfBlob] = useState(null); const [isSubmitting, setIsSubmitting] = useState(false); const [leadFormError, setLeadFormError] = useState(null); function handleStart() { setView('encuesta'); setAreaIdx(0); scrollDiagToTop(); } function handleAnswer(key, value) { setRespuestas(prev => ({...prev, [key]: value})); } function handleNextArea() { if (areaIdx === AREAS.length - 1) { // compute results const res = computeResultados(respuestas); setResultados(res); setView('resultados'); scrollDiagToTop(); } else { setAreaIdx(prev => prev + 1); scrollDiagToTop(); } } function handlePrevArea() { setAreaIdx(prev => Math.max(0, prev - 1)); scrollDiagToTop(); } async function handleLeadSubmit(form) { setLeadFormError(null); if (!form.nombre || !form.empresa || !form.cargo || !form.email || !form.email.includes('@')) { setLeadFormError('Por favor completa todos los campos con información válida.'); return; } setIsSubmitting(true); setLeadData(form); // Fire-and-forget submission to ActiveCampaign. // We do NOT await this — the PDF download must never be blocked // by network conditions or AC availability. if (typeof window.submitToActiveCampaign === 'function') { window.submitToActiveCampaign(form); } try { const blob = await generatePDF(form, resultados); setPdfBlob(blob); triggerDownload(blob, form); setView('gracias'); scrollDiagToTop(); } catch (err) { console.error(err); setLeadFormError('Hubo un error generando el PDF. Intenta de nuevo.'); } finally { setIsSubmitting(false); } } function handleReDownload() { if (pdfBlob && leadData) triggerDownload(pdfBlob, leadData); } // progress const totalQ = AREAS.length * 6; const respCount = Object.keys(respuestas).length; const pct = Math.round((respCount / totalQ) * 100); return ( <>