/* global React */
/* DocumentPreview — renders a SOP doc faithfully to the Google Doc reference. */
const { useMemo: useMemoDP } = React;
/* ---- inline rich-text: **bold** + paragraphs + bullets ---- */
function renderRichText(text, key = "rt") {
if (!text) return null;
const lines = String(text).split(/\n/);
const nodes = [];
let buf = []; // paragraph buffer (string lines)
let listBuf = []; // bullet buffer (string lines)
let idx = 0;
const flushPara = () => {
if (!buf.length) return;
const txt = buf.join(" ").trim();
if (txt) {
nodes.push(
{/* ----- COVER ----- */}
{/* ----- INTRO ----- */}
{hasIntro && {renderRichText(doc.intro, "intro")}
}
{/* ----- OBJECTIVE + SCOPE (inline lead-style, matches reference) ----- */}
{(hasObjective || hasScope) && (
{hasObjective && (
Objetivo. {doc.objective}
)}
{hasScope && (
Alcance. {doc.scope}
)}
)}
{/* ----- RESUMEN DEL FLUJO ----- */}
{hasFlow && (
<>
Resumen del flujo
{doc.flow.filter(Boolean).map((step, i, arr) => (
{i + 1}.
{step}
{i < arr.length - 1 && ↓
}
))}
>
)}
{/* ----- ROLES ----- */}
{hasRoles && (() => { const n = nextNum(); return (
<>
Roles y responsabilidades
{doc.roles.filter(r => r.name || r.desc).map(r => (
))}
>
); })()}
{/* ----- RESOURCES ----- */}
{hasResources && (() => { const n = nextNum(); return (
<>
Recursos y herramientas
{doc.resources.filter(r => r.name || r.desc).map(r => (
))}
>
); })()}
{/* ----- PROCEDURE ----- */}
{hasPhases && (() => { const n = nextNum(); return (
<>
Procedimiento paso a paso
{doc.phases.map(phase => {
const hasContent = phase.title || (phase.steps && phase.steps.some(s => s.title || s.body));
if (!hasContent) return null;
return (
Fase {phase.num}
{phase.title}
{(phase.steps || []).filter(s => s.title || s.body || (s.substeps && s.substeps.length)).map(step => (
{step.done && }
Paso {step.num}
{step.title}
{step.time && (
· {step.time}
)}
{step.body && (
{renderRichText(step.body, `step-${step.id}`)}
)}
{step.image && (
)}
{step.substeps && step.substeps.filter(ss => ss.text).map(ss => (
{ss.num}.
{ss.text}
))}
))}
);
})}
>
); })()}
{/* ----- DEFINITIONS ----- */}
{hasDefs && (() => { const n = nextNum(); return (
<>
Definiciones
{doc.definitions.filter(d => d.term || d.meaning).map(d => (
))}
>
); })()}
{/* ----- REFERENCES ----- */}
{hasRefs && (() => { const n = nextNum(); return (
<>
Referencias
{doc.references.filter(r => r.term || r.meaning).map(r => (
))}
>
); })()}
{/* ----- empty state ----- */}
{!hasIntro && !hasObjective && !hasScope && !hasFlow && !hasRoles && !hasResources && !hasPhases && !hasDefs && !hasRefs && (
Empieza rellenando los campos en el panel de la izquierda — el documento se actualizará aquí en tiempo real. Si tienes notas en bruto, pulsa Estructurar con IA y la app te lo organiza.
)}
{/* ----- FOOTER ----- */}
Ads&Law
SOP · {doc.title ? doc.title.slice(0, 60) : "Sin título"} · v{doc.version || "1.0"}
);
}
window.DocumentPreview = DocumentPreview;