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 { api } from "../lib/api";
|
||||||
import { Loader, ErrorBox, Filters, Select } from "../components/UI";
|
import { Loader, ErrorBox, Filters, Select } from "../components/UI";
|
||||||
import {
|
import {
|
||||||
@@ -22,6 +22,9 @@ export default function Programa({ inicial = null, onConsumirInicial } = {}) {
|
|||||||
const [reload, setReload] = useState(0);
|
const [reload, setReload] = useState(0);
|
||||||
// Programa que se debe seleccionar automaticamente al llegar por enlace (Leads).
|
// Programa que se debe seleccionar automaticamente al llegar por enlace (Leads).
|
||||||
const [progPendiente, setProgPendiente] = useState(inicial?.programa || null);
|
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(() => { api.leadsFiltros().then(setFiltros).catch(() => {}); }, []);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -199,12 +202,57 @@ export default function Programa({ inicial = null, onConsumirInicial } = {}) {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{(data.matriz_etiq || []).length === 0 ? (
|
{(data.matriz_etiq || []).length === 0 ? (
|
||||||
<tr><td colSpan={2} style={{ padding: 30, textAlign: "center", color: "#94a3b8" }}>Sin datos</td></tr>
|
<tr><td colSpan={2} style={{ padding: 30, textAlign: "center", color: "#94a3b8" }}>Sin datos</td></tr>
|
||||||
) : (data.matriz_etiq || []).map((e) => (
|
) : (data.matriz_etiq || []).map((e) => {
|
||||||
<tr key={e.estado}>
|
const abierto = !!expEstado[e.estado];
|
||||||
<td className="col-name">{e.estado}</td>
|
const tieneAsesores = (e.asesores || []).length > 0;
|
||||||
<td>{num(e.cantidad)}</td>
|
return (
|
||||||
</tr>
|
<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 && (
|
{(data.matriz_etiq || []).length > 0 && (
|
||||||
<tr className="total-row">
|
<tr className="total-row">
|
||||||
<td className="col-name" style={{ position: "sticky", bottom: 0, background: "#eff6ff" }}>Total</td>
|
<td className="col-name" style={{ position: "sticky", bottom: 0, background: "#eff6ff" }}>Total</td>
|
||||||
|
|||||||
Reference in New Issue
Block a user