/* global React */ // Reportes (HU.5.2 · HU.5.3) // Builder de reportes + plantillas + historial de generaciones const { useState: useStateRp, useMemo: useMemoRp } = React; function ReportesScreen({ roleId, user, onOpenDetalle }) { const I = window.Icons; const templates = window.REPORT_TEMPLATES; const recientes = window.REPORTES_RECIENTES; // Builder state const [tplId, setTplId] = useStateRp('consol_pais'); const [mech, setMech] = useStateRp('MESICIC'); const [period, setPeriod] = useStateRp('2024 — 2026'); const [inst, setInst] = useStateRp(roleId === 'institucion' ? 'Min. de Hacienda' : 'Todas (47)'); const [estado, setEstado] = useStateRp('Todos'); const [formato, setFormato] = useStateRp('PDF'); const [includeLogo, setIncludeLogo] = useStateRp(true); const [includeAnexos, setIncludeAnexos] = useStateRp(true); const tpl = templates.find(t => t.id === tplId) || templates[0]; // Estimación de filas según filtros const filasEstimadas = useMemoRp(() => { let base = mech === 'MESICIC' ? 118 : mech === 'UNCAC' ? 156 : mech === 'OCDE' ? 253 : 527; if (estado === 'Cumplidos') base = Math.round(base * 0.35); if (estado === 'Parciales') base = Math.round(base * 0.47); if (estado === 'No cumplidos') base = Math.round(base * 0.15); if (inst !== 'Todas (47)' && roleId !== 'institucion') base = Math.round(base / 8); if (roleId === 'institucion') base = 23; return base; }, [mech, estado, inst, roleId]); return (
{/* Header */}
{user.org}

Reportes

Genera reportes exportables en Excel y PDF {roleId === 'institucion' ? ' sobre la cartera de tu institución.' : ' con encabezado institucional, listos para uso interno o envío internacional.'}

{/* Builder + Preview */}
{/* Left: template + filters */}

1 · Tipo de reporte

Elige una plantilla. Cada una define la estructura final del archivo.

{templates.map(t => { const ICON = I[t.icon]; return ( ); })}

2 · Filtros del reporte

Define el alcance del reporte. Los filtros se combinan entre sí.

3 · Formato de salida

Define la presentación. Todos los formatos incluyen encabezado institucional CGR.

{tpl.format.concat(tpl.id === 'plazos_riesgo' ? ['CSV'] : []).map(f => ( ))}
{/* Right: live preview */}
{/* Recent reports */}

Reportes generados recientemente

Tus últimos reportes y los de tu equipo · disponibles por 90 días
{recientes.map(r => ( ))}
ID Reporte Generado Por Formato Tamaño
{r.id} {r.titulo}
{r.filas} registros
{r.generado} {r.autor} {r.formato.toUpperCase()} {r.peso}
); } Object.assign(window, { ReportesScreen });