Actualizar frontend/src/pages/Programa.jsx
This commit is contained in:
@@ -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>
|
||||
<td>{num(e.cantidad)}</td>
|
||||
</tr>
|
||||
))}
|
||||
) : (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>
|
||||
|
||||
Reference in New Issue
Block a user