Filtro Citados + Con Retraso en servicios.html

This commit is contained in:
2026-09-27 17:36:52 +00:00
parent e38ffbfd00
commit 9c5f045ca0

View File

@@ -95,7 +95,7 @@
<span class="text-[10px] font-black text-slate-400 uppercase"><i data-lucide="loader-2" class="w-3 h-3 animate-spin inline"></i> Cargando estados...</span> <span class="text-[10px] font-black text-slate-400 uppercase"><i data-lucide="loader-2" class="w-3 h-3 animate-spin inline"></i> Cargando estados...</span>
</div> </div>
<div class="grid grid-cols-2 md:grid-cols-5 gap-3 mt-4"> <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-3 mt-4">
<div onclick="setKpiFilter('unassigned')" class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm flex items-center gap-3 cursor-pointer hover:bg-slate-50 transition-all group" id="box-unassigned"> <div onclick="setKpiFilter('unassigned')" class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm flex items-center gap-3 cursor-pointer hover:bg-slate-50 transition-all group" id="box-unassigned">
<div class="w-10 h-10 rounded-full bg-rose-50 flex items-center justify-center text-rose-500 shrink-0 group-hover:scale-110 transition-transform"><i data-lucide="inbox" class="w-5 h-5"></i></div> <div class="w-10 h-10 rounded-full bg-rose-50 flex items-center justify-center text-rose-500 shrink-0 group-hover:scale-110 transition-transform"><i data-lucide="inbox" class="w-5 h-5"></i></div>
<div> <div>
@@ -113,10 +113,17 @@
<div onclick="setKpiFilter('pending_start')" class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm flex items-center gap-3 cursor-pointer hover:bg-slate-50 transition-all group" id="box-pending-start"> <div onclick="setKpiFilter('pending_start')" class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm flex items-center gap-3 cursor-pointer hover:bg-slate-50 transition-all group" id="box-pending-start">
<div class="w-10 h-10 rounded-full bg-blue-50 flex items-center justify-center text-blue-500 shrink-0 group-hover:scale-110 transition-transform"><i data-lucide="play-circle" class="w-5 h-5"></i></div> <div class="w-10 h-10 rounded-full bg-blue-50 flex items-center justify-center text-blue-500 shrink-0 group-hover:scale-110 transition-transform"><i data-lucide="play-circle" class="w-5 h-5"></i></div>
<div> <div>
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Pte. Inicio</p> <p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Citados</p>
<h3 class="text-xl font-black text-slate-800 leading-none mt-0.5" id="kpi-pending-start">0</h3> <h3 class="text-xl font-black text-slate-800 leading-none mt-0.5" id="kpi-pending-start">0</h3>
</div> </div>
</div> </div>
<div onclick="setKpiFilter('late')" class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm flex items-center gap-3 cursor-pointer hover:bg-slate-50 transition-all group" id="box-late">
<div class="w-10 h-10 rounded-full bg-red-50 flex items-center justify-center text-red-500 shrink-0 group-hover:scale-110 transition-transform"><i data-lucide="alarm-clock" class="w-5 h-5"></i></div>
<div>
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Con Retraso</p>
<h3 class="text-xl font-black text-slate-800 leading-none mt-0.5" id="kpi-late">0</h3>
</div>
</div>
<div onclick="setKpiFilter('working')" class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm flex items-center gap-3 cursor-pointer hover:bg-slate-50 transition-all group" id="box-working"> <div onclick="setKpiFilter('working')" class="bg-white p-4 rounded-2xl border border-slate-200 shadow-sm flex items-center gap-3 cursor-pointer hover:bg-slate-50 transition-all group" id="box-working">
<div class="w-10 h-10 rounded-full bg-emerald-50 flex items-center justify-center text-emerald-500 shrink-0 group-hover:scale-110 transition-transform"><i data-lucide="hammer" class="w-5 h-5"></i></div> <div class="w-10 h-10 rounded-full bg-emerald-50 flex items-center justify-center text-emerald-500 shrink-0 group-hover:scale-110 transition-transform"><i data-lucide="hammer" class="w-5 h-5"></i></div>
<div> <div>
@@ -726,6 +733,7 @@
let kpiPendingStart = 0; let kpiPendingStart = 0;
let kpiWorking = 0; let kpiWorking = 0;
let kpiFinished = 0; let kpiFinished = 0;
let kpiLate = 0;
const filteredData = localData.filter(s => { const filteredData = localData.filter(s => {
const raw = s.raw_data || {}; const raw = s.raw_data || {};
@@ -737,6 +745,19 @@
const hasDate = raw.scheduled_date && raw.scheduled_date.trim() !== ""; const hasDate = raw.scheduled_date && raw.scheduled_date.trim() !== "";
const isFinal = stateInfo.is_final || stName.includes('finaliza') || stName.includes('anulad') || stName.includes('terminad') || s.status === 'archived'; const isFinal = stateInfo.is_final || stName.includes('finaliza') || stName.includes('anulad') || stName.includes('terminad') || s.status === 'archived';
let isLate = false;
let daysLate = 0;
if (!isFinal && raw.scheduled_date && raw.scheduled_date.trim() !== "") {
const schedDate = new Date(raw.scheduled_date + 'T00:00:00');
const today = new Date();
today.setHours(0,0,0,0);
const diffDays = Math.floor((today - schedDate) / 86400000);
if (diffDays > 2) { isLate = true; daysLate = diffDays; }
}
s._isLate = isLate;
s._daysLate = daysLate;
if (isLate) kpiLate++;
let category = 'none'; let category = 'none';
if (isFinal) { kpiFinished++; category = 'finished'; } if (isFinal) { kpiFinished++; category = 'finished'; }
@@ -774,6 +795,8 @@
matchesKpi = true; // 🛑 NUEVO: Si has tocado una pastilla, las cajas grandes ya no filtran matchesKpi = true; // 🛑 NUEVO: Si has tocado una pastilla, las cajas grandes ya no filtran
} else if (activeKpiFilter === 'ACTIVE') { } else if (activeKpiFilter === 'ACTIVE') {
matchesKpi = category !== 'finished'; matchesKpi = category !== 'finished';
} else if (activeKpiFilter === 'late') {
matchesKpi = isLate;
} else { } else {
matchesKpi = category === activeKpiFilter; matchesKpi = category === activeKpiFilter;
} }
@@ -786,6 +809,7 @@
document.getElementById('kpi-pending-start').innerText = kpiPendingStart; document.getElementById('kpi-pending-start').innerText = kpiPendingStart;
document.getElementById('kpi-working').innerText = kpiWorking; document.getElementById('kpi-working').innerText = kpiWorking;
document.getElementById('kpi-finished').innerText = kpiFinished; document.getElementById('kpi-finished').innerText = kpiFinished;
document.getElementById('kpi-late').innerText = kpiLate;
['unassigned', 'unscheduled', 'pending_start', 'working', 'finished'].forEach(k => { ['unassigned', 'unscheduled', 'pending_start', 'working', 'finished'].forEach(k => {
const box = document.getElementById(`box-${k}`); const box = document.getElementById(`box-${k}`);
@@ -795,7 +819,13 @@
} }
}); });
const grid = document.getElementById('servicesGrid');
const lateBox = document.getElementById('box-late');
if (lateBox) {
if (activeKpiFilter === 'late') lateBox.classList.add('ring-2', 'ring-red-500', 'bg-red-50');
else lateBox.classList.remove('ring-2', 'ring-red-500', 'bg-red-50');
}
const grid = document.getElementById('servicesGrid');
grid.innerHTML = filteredData.length > 0 grid.innerHTML = filteredData.length > 0
? filteredData.map(s => buildGridCard(s)).join('') ? filteredData.map(s => buildGridCard(s)).join('')
: `<div class="col-span-full py-20 text-center bg-white rounded-[2rem] border-2 border-dashed border-slate-200"> : `<div class="col-span-full py-20 text-center bg-white rounded-[2rem] border-2 border-dashed border-slate-200">
@@ -885,9 +915,9 @@
<div class="w-6 h-6 bg-slate-100 rounded-full flex items-center justify-center text-slate-500 shrink-0 border border-slate-200"><i data-lucide="hard-hat" class="w-3 h-3"></i></div> <div class="w-6 h-6 bg-slate-100 rounded-full flex items-center justify-center text-slate-500 shrink-0 border border-slate-200"><i data-lucide="hard-hat" class="w-3 h-3"></i></div>
<span class="text-[10px] font-black text-slate-600 uppercase truncate flex-1" title="${s.assigned_name || 'Sin asignar'}">${s.assigned_name || 'Sin asignar'}</span> <span class="text-[10px] font-black text-slate-600 uppercase truncate flex-1" title="${s.assigned_name || 'Sin asignar'}">${s.assigned_name || 'Sin asignar'}</span>
</div> </div>
<div class="flex items-center gap-1 text-blue-600 shrink-0 bg-blue-50 px-2 py-1 rounded-md border border-blue-100"> <div class="flex items-center gap-1 ${s._isLate ? 'text-red-600 bg-red-50 border-red-200' : 'text-blue-600 bg-blue-50 border-blue-100'} shrink-0 px-2 py-1 rounded-md border">
<i data-lucide="${iconEstado}" class="w-3 h-3"></i> <i data-lucide="${s._isLate ? 'alarm-clock' : iconEstado}" class="w-3 h-3"></i>
<span class="text-[9px] font-black uppercase whitespace-nowrap">${raw.scheduled_date ? cita.split('|')[0] : 'Pte. Cita'}</span> <span class="text-[9px] font-black uppercase whitespace-nowrap">${raw.scheduled_date ? cita.split('|')[0] : 'Pte. Cita'}${s._isLate ? ' · ' + s._daysLate + 'D RETRASO' : ''}</span>
</div> </div>
</div> </div>
</div>`; </div>`;