Actualizar frontend/src/pages/Programa.jsx

This commit is contained in:
2026-09-10 11:26:19 -05:00
parent 1e1f1e930b
commit e01121a64d

View File

@@ -1,4 +1,4 @@
import { useState, useEffect, useMemo } from "react";
import { useState, useEffect, useMemo, Fragment } from "react";
import { api } from "../lib/api";
import { Loader, ErrorBox, Filters, Select } from "../components/UI";
import {
@@ -22,6 +22,9 @@ export default function Programa({ inicial = null, onConsumirInicial } = {}) {
const [reload, setReload] = useState(0);
// Programa que se debe seleccionar automaticamente al llegar por enlace (Leads).
const [progPendiente, setProgPendiente] = useState(inicial?.programa || null);
// Expansion de la tabla Estado/Objecion (mismo patron que el apartado Leads)
const [expEstado, setExpEstado] = useState({}); // estado -> abierto
const [expEstAse, setExpEstAse] = useState({}); // "estado|asesor" -> abierto
useEffect(() => { api.leadsFiltros().then(setFiltros).catch(() => {}); }, []);
useEffect(() => {
@@ -199,12 +202,57 @@ export default function Programa({ inicial = null, onConsumirInicial } = {}) {
<tbody>
{(data.matriz_etiq || []).length === 0 ? (
<tr><td colSpan={2} style={{ padding: 30, textAlign: "center", color: "#94a3b8" }}>Sin datos</td></tr>
) : (data.matriz_etiq || []).map((e) => (
<tr key={e.estado}>
<td className="col-name">{e.estado}</td>
) : (data.matriz_etiq || []).map((e) => {
const abierto = !!expEstado[e.estado];
const tieneAsesores = (e.asesores || []).length > 0;
return (
<Fragment key={e.estado}>
<tr>
<td className="col-name">
{tieneAsesores && (
<button
onClick={() => setExpEstado((p) => ({ ...p, [e.estado]: !p[e.estado] }))}
style={{ border: "none", background: "transparent", cursor: "pointer",
fontWeight: 700, marginRight: 6, color: "#2563eb", fontSize: 14 }}>
{abierto ? "−" : "+"}
</button>
)}
{e.estado}
</td>
<td>{num(e.cantidad)}</td>
</tr>
{abierto && (e.asesores || []).map((a) => {
const keyA = e.estado + "|" + a.asesor;
const abiertoA = !!expEstAse[keyA];
const tieneTel = (a.telefonos || []).length > 0;
return (
<Fragment key={keyA}>
<tr style={{ background: "#f8fafc" }}>
<td className="col-name" style={{ paddingLeft: 30, color: "#475569", fontSize: 12 }}>
{tieneTel && (
<button
onClick={() => setExpEstAse((p) => ({ ...p, [keyA]: !p[keyA] }))}
style={{ border: "none", background: "transparent", cursor: "pointer",
fontWeight: 700, marginRight: 6, color: "#7c3aed", fontSize: 13 }}>
{abiertoA ? "−" : "+"}
</button>
)}
{a.asesor}
</td>
<td style={{ color: "#475569", fontSize: 12 }}>{num(a.cantidad)}</td>
</tr>
{abiertoA && (a.telefonos || []).map((t, i) => (
<tr key={keyA + "-" + t + "-" + i} style={{ background: "#fcfdff" }}>
<td className="col-name" style={{ paddingLeft: 60, color: "#94a3b8", fontSize: 11 }}>📞 {t}</td>
<td></td>
</tr>
))}
</Fragment>
);
})}
</Fragment>
);
})}
{(data.matriz_etiq || []).length > 0 && (
<tr className="total-row">
<td className="col-name" style={{ position: "sticky", bottom: 0, background: "#eff6ff" }}>Total</td>