From 14744a5ff75b8809cecd09b7322d3173184528e5 Mon Sep 17 00:00:00 2001 From: marsalva Date: Tue, 17 Feb 2026 22:09:13 +0000 Subject: [PATCH] Actualizar panel.html --- panel.html | 71 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/panel.html b/panel.html index 7b3f457..383e9ec 100644 --- a/panel.html +++ b/panel.html @@ -173,12 +173,16 @@ async function loadDashboardData(token) { try { - // 1. Pedimos todos los datos (el endpoint de scraped trae todos los del panel también) + // 1. Pedimos los expedientes vírgenes (Bandeja / Bolsa) const resScraped = await fetch(`${API_URL}/providers/scraped`, { headers: { "Authorization": `Bearer ${token}` } }); const dataScraped = await resScraped.json(); - if (dataScraped.ok) { - processDashboard(dataScraped.services); + // 2. Pedimos los expedientes en curso (Panel Operativo) + const resActive = await fetch(`${API_URL}/services/active`, { headers: { "Authorization": `Bearer ${token}` } }); + const dataActive = await resActive.json(); + + if (dataScraped.ok && dataActive.ok) { + processDashboard(dataScraped.services, dataActive.services); } } catch (e) { console.error("Error cargando dashboard:", e); @@ -186,31 +190,36 @@ } } - function processDashboard(allServices) { - // Filtrar SOLO LOS ACTIVOS reales (Ignoramos los archivados) - const activeServices = allServices.filter(s => s.status !== 'archived'); - + function processDashboard(scrapedList, activeList) { const todayStr = new Date().toISOString().split('T')[0]; - // --- CÁLCULO DE KPIs CORREGIDO --- + // 1. LIMPIAR DATOS + // Filtramos los archivados y los que ya están importados del Scraped (porque los importados ya vienen en activeList) + const trueScraped = scrapedList.filter(s => s.status !== 'archived' && s.status !== 'imported'); + const trueActive = activeList.filter(s => s.status !== 'archived'); - // 1. Total (Solución al fallo de la suma doble) - const totalActive = activeServices.length; + // Unimos todo en una gran lista para los gráficos globales + const allServices = [...trueScraped, ...trueActive]; - // 2. Sin Asignar - const unassignedCount = activeServices.filter(s => s.status === 'pending' && s.automation_status !== 'in_progress').length; - - // 3. En Rueda - const queueCount = activeServices.filter(s => s.status === 'pending' && s.automation_status === 'in_progress').length; + // --- CÁLCULO DE KPIs --- - // 4. Asignados sin cita (Pendientes) - const pendingCount = activeServices.filter(s => s.status === 'imported' && (!s.raw_data.scheduled_date || s.raw_data.scheduled_date === "")).length; - - // 5. Citas de hoy - const todayVisits = activeServices.filter(s => s.raw_data && s.raw_data.scheduled_date === todayStr); + // 1. Total (La suma de los dos mundos) + const totalActive = allServices.length; - // 6. Urgencias (NUEVO) - const urgentVisits = activeServices.filter(s => { + // 2. Sin Asignar (Los de scraped que no están en rueda) + const unassignedCount = trueScraped.filter(s => s.automation_status !== 'in_progress').length; + + // 3. En Rueda (Los de scraped buscando operario) + const queueCount = trueScraped.filter(s => s.automation_status === 'in_progress').length; + + // 4. Asignados sin cita (Los activos que no tienen fecha agendada) + const pendingCount = trueActive.filter(s => !s.raw_data.scheduled_date || s.raw_data.scheduled_date === "").length; + + // 5. Citas de hoy (Los activos con fecha de hoy) + const todayVisits = trueActive.filter(s => s.raw_data.scheduled_date === todayStr); + + // 6. Urgencias (Cualquiera que tenga la palabra URGENTE) + const urgentVisits = allServices.filter(s => { const raw = s.raw_data || {}; return raw['Urgente'] === 'Sí' || raw['Urgente'] === 'true' || raw['URGENTE'] === 'SI'; }); @@ -226,8 +235,8 @@ // --- RENDERIZAR WIDGETS --- renderTodaySchedule(todayVisits); renderUrgentSchedule(urgentVisits); - renderCompanyDistribution(activeServices); - renderLatestActivity(allServices); // Aquí pasamos todos para ver los recién entrados + renderCompanyDistribution(allServices); + renderLatestActivity(allServices); } // WIDGET 1: Agenda Hoy @@ -247,7 +256,7 @@ container.innerHTML = visits.map(s => { const raw = s.raw_data; const time = raw.scheduled_time ? raw.scheduled_time.substring(0,5) : "--:--"; - const op = s.current_worker_name || raw.assigned_to_name || "Sin Asignar"; + const op = s.assigned_name || raw.assigned_to_name || "Sin Asignar"; const name = raw['Nombre Cliente'] || raw['CLIENTE'] || "Asegurado"; const pop = raw['Población'] || raw['POBLACION-PROVINCIA'] || "Dirección no especificada"; @@ -295,7 +304,7 @@ container.innerHTML = visits.map(s => { const raw = s.raw_data; const name = raw['Nombre Cliente'] || raw['CLIENTE'] || "Asegurado"; - const op = s.current_worker_name || raw.assigned_to_name || "Buscando Operario..."; + const op = s.assigned_name || raw.assigned_to_name || "Buscando Operario..."; return `
@@ -309,12 +318,12 @@ } // WIDGET 3: Distribución Compañías - function renderCompanyDistribution(activeServices) { + function renderCompanyDistribution(allServices) { const container = document.getElementById("companyDistribution"); - if (activeServices.length === 0) { container.innerHTML = "

Sin datos

"; return; } + if (allServices.length === 0) { container.innerHTML = "

Sin datos

"; return; } const counts = {}; - activeServices.forEach(s => { + allServices.forEach(s => { const raw = s.raw_data || {}; let comp = (raw['Compañía'] || raw['COMPAÑIA'] || raw['Procedencia'] || (s.provider === 'MANUAL' ? 'PARTICULAR' : 'OTRA')).toUpperCase().trim(); if(comp.includes("HOMESERVE")) comp = "HOMESERVE"; @@ -342,7 +351,7 @@ // WIDGET 4: Última Actividad function renderLatestActivity(allServices) { const container = document.getElementById("latestActivity"); - // Ordenar por ID o Created At descendente y coger 5 + // Ordenar por fecha de creación descendente (el ID suele ser correlativo) const latest = allServices.sort((a, b) => b.id - a.id).slice(0, 5); if (latest.length === 0) { container.innerHTML = "

Sin actividad reciente

"; return; } @@ -369,7 +378,7 @@ let start = 0; const duration = 800; const range = end - start; - if(range === 0) { obj.innerText = "0"; return; } + if(range === 0) { obj.innerText = end; return; } const minTimer = 50; let stepTime = Math.abs(Math.floor(duration / range)); stepTime = Math.max(stepTime, minTimer);