106 lines
4.7 KiB
JavaScript
106 lines
4.7 KiB
JavaScript
// src/pages/Asesores.jsx
|
|
import { useState, useEffect, useCallback } from "react";
|
|
import { api } from "../lib/api";
|
|
import { Loader, ErrorBox } from "../components/UI";
|
|
|
|
const ESTADO_INFO = {
|
|
online: { txt: "En Línea", color: "#10b981", bg: "#d1fae5", fg: "#065f46" },
|
|
busy: { txt: "Ocupado", color: "#f59e0b", bg: "#fef9c3", fg: "#854d0e" },
|
|
offline:{ txt: "Fuera de Línea", color: "#94a3b8", bg: "#f1f5f9", fg: "#475569" },
|
|
};
|
|
|
|
export default function Asesores() {
|
|
const [agentes, setAgentes] = useState([]);
|
|
const [loading, setLoading] = useState(true);
|
|
const [error, setError] = useState(null);
|
|
const [cambiando, setCambiando] = useState(null);
|
|
|
|
const cargar = useCallback(() => {
|
|
setLoading(true); setError(null);
|
|
api.asesores()
|
|
.then((res)=>{ setAgentes(res.agentes||[]); setLoading(false); })
|
|
.catch((e)=>{ setError(e.message); setLoading(false); });
|
|
}, []);
|
|
|
|
useEffect(() => { cargar(); }, [cargar]);
|
|
|
|
async function toggle(ag) {
|
|
const online = ag.availability_status !== "online";
|
|
setCambiando(ag.id);
|
|
try {
|
|
await api.asesorEstado(ag.id, online);
|
|
setAgentes((prev)=>prev.map((a)=>a.id===ag.id ? {...a, availability_status: online?"online":"offline"} : a));
|
|
} catch (e) { /* noop */ }
|
|
setCambiando(null);
|
|
}
|
|
|
|
async function todos(online) {
|
|
setCambiando("all");
|
|
for (const ag of agentes) {
|
|
try { await api.asesorEstado(ag.id, online); } catch (e) {}
|
|
}
|
|
setAgentes((prev)=>prev.map((a)=>({...a, availability_status: online?"online":"offline"})));
|
|
setCambiando(null);
|
|
}
|
|
|
|
const total = agentes.length;
|
|
const enLinea = agentes.filter((a)=>a.availability_status==="online").length;
|
|
const ocupados = agentes.filter((a)=>a.availability_status==="busy").length;
|
|
const offline = total - enLinea - ocupados;
|
|
|
|
return (
|
|
<div>
|
|
<h1 className="page-title">👥 Asesores</h1>
|
|
|
|
{loading ? <Loader text="Cargando asesores de Chatwoot..." /> :
|
|
error ? <ErrorBox msg={error} /> :
|
|
<>
|
|
<div className="kpis" style={{gridTemplateColumns:"repeat(4,1fr)"}}>
|
|
<div className="kpi"><div className="ico">👥</div><div className="label">Total Asesores</div><div className="value">{total}</div></div>
|
|
<div className="kpi" style={{background:"#d1fae5"}}><div className="ico">🟢</div><div className="label">En Línea</div><div className="value" style={{color:"#065f46"}}>{enLinea}</div></div>
|
|
<div className="kpi" style={{background:"#fef9c3"}}><div className="ico">🟡</div><div className="label">Ocupados</div><div className="value" style={{color:"#854d0e"}}>{ocupados}</div></div>
|
|
<div className="kpi" style={{background:"#fee2e2"}}><div className="ico">🔴</div><div className="label">Fuera de Línea</div><div className="value" style={{color:"#991b1b"}}>{offline}</div></div>
|
|
</div>
|
|
|
|
<div style={{display:"flex",gap:10,marginBottom:16}}>
|
|
<button className="btn btn-primary" disabled={cambiando==="all"} onClick={()=>todos(true)}>🟢 Encender todos</button>
|
|
<button className="btn btn-ghost" disabled={cambiando==="all"} onClick={()=>todos(false)}>🔴 Apagar todos</button>
|
|
<button className="btn btn-ghost" title="Refrescar" style={{fontSize:18}} onClick={cargar}>🔄</button>
|
|
</div>
|
|
|
|
<div className="table-wrap">
|
|
<table>
|
|
<thead><tr><th>ASESOR</th><th>EMAIL</th><th>ROL</th><th>ESTADO</th><th>ACCIÓN</th></tr></thead>
|
|
<tbody>
|
|
{agentes.map((ag)=>{
|
|
const est = ESTADO_INFO[ag.availability_status] || ESTADO_INFO.offline;
|
|
const isOnline = ag.availability_status==="online";
|
|
return (
|
|
<tr key={ag.id}>
|
|
<td className="col-name">{ag.name || ag.available_name || "—"}</td>
|
|
<td>{ag.email || "—"}</td>
|
|
<td>{ag.role || "agent"}</td>
|
|
<td>
|
|
<span style={{background:est.bg,color:est.fg,padding:"3px 10px",borderRadius:20,
|
|
fontSize:11,fontWeight:700}}>● {est.txt}</span>
|
|
</td>
|
|
<td>
|
|
<button className="btn" disabled={cambiando===ag.id}
|
|
style={{padding:"5px 12px",fontSize:11,
|
|
background:isOnline?"#fee2e2":"#d1fae5",
|
|
color:isOnline?"#991b1b":"#065f46"}}
|
|
onClick={()=>toggle(ag)}>
|
|
{cambiando===ag.id ? "..." : (isOnline?"Apagar":"Encender")}
|
|
</button>
|
|
</td>
|
|
</tr>
|
|
);
|
|
})}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</>}
|
|
</div>
|
|
);
|
|
}
|