Actualizar servicios.html

This commit is contained in:
2026-02-16 20:26:57 +00:00
parent 3b74d8907c
commit 39e393934c

View File

@@ -24,29 +24,39 @@
<div class="flex justify-between items-center mb-8"> <div class="flex justify-between items-center mb-8">
<div> <div>
<h2 class="text-2xl font-black text-slate-800 tracking-tight">PANEL OPERATIVO</h2> <h2 class="text-2xl font-black text-slate-800 tracking-tight">PANEL OPERATIVO</h2>
<p class="text-sm text-slate-500 font-medium">Gestión de expedientes aceptados y control de citas.</p> <p class="text-sm text-slate-500 font-medium">Tablero Kanban de gestión de expedientes.</p>
</div> </div>
<button onclick="openCreateModal()" class="bg-slate-900 hover:bg-blue-600 text-white px-6 py-3 rounded-2xl shadow-xl flex items-center gap-3 font-black text-xs uppercase tracking-widest transition-all active:scale-95"> <button onclick="openCreateModal()" class="bg-slate-900 hover:bg-blue-600 text-white px-6 py-3 rounded-2xl shadow-xl flex items-center gap-3 font-black text-xs uppercase tracking-widest transition-all active:scale-95">
<i data-lucide="plus-circle" class="w-5 h-5"></i> Nuevo Servicio <i data-lucide="plus-circle" class="w-5 h-5"></i> Nuevo Servicio
</button> </button>
</div> </div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8"> <div class="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-6">
<div class="space-y-4">
<div class="flex items-center gap-2 px-2"> <div class="space-y-4 bg-slate-100/50 p-4 rounded-[2rem] border border-slate-200/60">
<div class="w-2 h-2 rounded-full bg-blue-500"></div> <div class="flex items-center gap-2 px-2 pb-2 border-b border-slate-200">
<h3 class="font-black text-slate-400 uppercase text-[10px] tracking-widest">Asignados a Operario (Pendiente Cita)</h3> <div class="w-2.5 h-2.5 rounded-full bg-rose-500 shadow-[0_0_10px_rgba(244,63,94,0.5)]"></div>
<h3 class="font-black text-slate-600 uppercase text-[10px] tracking-widest">Sin Asignar / En Pausa</h3>
</div>
<div id="unassigned-list" class="space-y-3"></div>
</div>
<div class="space-y-4 bg-slate-100/50 p-4 rounded-[2rem] border border-slate-200/60">
<div class="flex items-center gap-2 px-2 pb-2 border-b border-slate-200">
<div class="w-2.5 h-2.5 rounded-full bg-blue-500 shadow-[0_0_10px_rgba(59,130,246,0.5)]"></div>
<h3 class="font-black text-slate-600 uppercase text-[10px] tracking-widest">Asignados (Falta Fecha)</h3>
</div> </div>
<div id="pending-list" class="space-y-3"></div> <div id="pending-list" class="space-y-3"></div>
</div> </div>
<div class="space-y-4"> <div class="space-y-4 bg-slate-100/50 p-4 rounded-[2rem] border border-slate-200/60">
<div class="flex items-center gap-2 px-2"> <div class="flex items-center gap-2 px-2 pb-2 border-b border-slate-200">
<div class="w-2 h-2 rounded-full bg-emerald-500"></div> <div class="w-2.5 h-2.5 rounded-full bg-emerald-500 shadow-[0_0_10px_rgba(16,185,129,0.5)]"></div>
<h3 class="font-black text-slate-400 uppercase text-[10px] tracking-widest">Servicios Citados / En Curso</h3> <h3 class="font-black text-slate-600 uppercase text-[10px] tracking-widest">Citados / En Curso</h3>
</div> </div>
<div id="assigned-list" class="space-y-3"></div> <div id="assigned-list" class="space-y-3"></div>
</div> </div>
</div> </div>
</main> </main>
</div> </div>
@@ -106,7 +116,7 @@
<div class="flex flex-col items-end text-right"> <div class="flex flex-col items-end text-right">
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Compañía Aseguradora</p> <p class="text-[9px] font-black text-slate-400 uppercase tracking-widest">Compañía Aseguradora</p>
<span id="detCompany" class="bg-white border border-slate-200 px-3 py-1 rounded-lg text-xs font-black text-slate-700 mt-1 uppercase shadow-sm"></span> <span id="detCompany" class="bg-white border border-slate-200 px-3 py-1 rounded-lg text-xs font-black text-slate-700 mt-1 uppercase shadow-sm truncate max-w-[250px]"></span>
</div> </div>
</div> </div>
@@ -134,8 +144,7 @@
<div> <div>
<p class="text-[9px] font-black text-slate-400 uppercase tracking-widest mb-2 ml-2">Descripción de la Avería</p> <p class="text-[9px] font-black text-slate-400 uppercase tracking-widest mb-2 ml-2">Descripción de la Avería</p>
<div class="bg-amber-50/60 border border-amber-100 p-5 rounded-[1.5rem] text-sm font-medium text-slate-700 min-h-[120px] max-h-48 overflow-y-auto no-scrollbar shadow-inner leading-relaxed" id="detDesc"> <div class="bg-amber-50/60 border border-amber-100 p-5 rounded-[1.5rem] text-sm font-medium text-slate-700 min-h-[120px] max-h-48 overflow-y-auto no-scrollbar shadow-inner leading-relaxed" id="detDesc"></div>
</div>
</div> </div>
</div> </div>
@@ -207,16 +216,30 @@
} }
function renderLists() { function renderLists() {
const pending = localData.filter(s => s.estado_operativo === 'asignado_operario'); // Lógica de separación en 3 columnas
const assigned = localData.filter(s => s.estado_operativo === 'citado'); const unassigned = localData.filter(s => !s.assigned_name);
const pending = localData.filter(s => s.assigned_name && (!s.raw_data.scheduled_date || s.raw_data.scheduled_date === ""));
const assigned = localData.filter(s => s.raw_data.scheduled_date && s.raw_data.scheduled_date !== "");
document.getElementById('unassigned-list').innerHTML = unassigned.length > 0
? unassigned.map(s => cardTemplate(s, 'rose', 'Sin Asignar')).join('')
: '<p class="text-center py-10 text-slate-300 text-xs font-bold uppercase border-2 border-dashed border-slate-200/50 rounded-[1.5rem]">Vacío</p>';
document.getElementById('pending-list').innerHTML = pending.length > 0 document.getElementById('pending-list').innerHTML = pending.length > 0
? pending.map(s => cardTemplate(s, 'blue', 'Asignado')).join('') ? pending.map(s => cardTemplate(s, 'blue', 'Falta Fecha')).join('')
: '<p class="text-center py-10 text-slate-300 text-xs font-bold uppercase border-2 border-dashed border-slate-100 rounded-[2rem]">Sin pendientes</p>'; : '<p class="text-center py-10 text-slate-300 text-xs font-bold uppercase border-2 border-dashed border-slate-200/50 rounded-[1.5rem]">Vacío</p>';
document.getElementById('assigned-list').innerHTML = assigned.length > 0 document.getElementById('assigned-list').innerHTML = assigned.length > 0
? assigned.map(s => cardTemplate(s, 'emerald', 'En Curso')).join('') ? assigned.map(s => {
: '<p class="text-center py-10 text-slate-300 text-xs font-bold uppercase border-2 border-dashed border-slate-100 rounded-[2rem]">Sin servicios citados</p>'; let color = 'emerald';
let label = 'Citado';
if(s.raw_data.status_operativo === 'trabajando') { color = 'amber'; label = 'Trabajando'; }
if(s.raw_data.status_operativo === 'incidencia') { color = 'red'; label = 'Incidencia'; }
if(s.raw_data.status_operativo === 'terminado') { color = 'purple'; label = 'Terminado'; }
return cardTemplate(s, color, label);
}).join('')
: '<p class="text-center py-10 text-slate-300 text-xs font-bold uppercase border-2 border-dashed border-slate-200/50 rounded-[1.5rem]">Vacío</p>';
lucide.createIcons(); lucide.createIcons();
} }
@@ -226,25 +249,26 @@
const addr = raw["Dirección"] || raw["DOMICILIO"] || "---"; const addr = raw["Dirección"] || raw["DOMICILIO"] || "---";
const cita = raw.scheduled_date ? `${raw.scheduled_date} | ${raw.scheduled_time}` : 'Pendiente Cita'; const cita = raw.scheduled_date ? `${raw.scheduled_date} | ${raw.scheduled_time}` : 'Pendiente Cita';
const estadoActual = raw.status_operativo || 'citado';
let iconEstado = 'calendar'; let iconEstado = 'calendar';
if(estadoActual === 'de_camino') iconEstado = 'car'; if(raw.status_operativo === 'de_camino') iconEstado = 'car';
if(estadoActual === 'trabajando') iconEstado = 'wrench'; if(raw.status_operativo === 'trabajando') iconEstado = 'wrench';
if(estadoActual === 'incidencia') iconEstado = 'alert-triangle'; if(raw.status_operativo === 'incidencia') iconEstado = 'alert-triangle';
if(estadoActual === 'terminado') iconEstado = 'check-circle'; if(raw.status_operativo === 'terminado') iconEstado = 'check-circle';
return ` return `
<div class="bg-white p-5 rounded-[2rem] border border-slate-100 shadow-sm card-hover text-left flex items-start justify-between gap-4 cursor-pointer" onclick="openDetail(${s.id})"> <div class="bg-white p-5 rounded-3xl border border-slate-100 shadow-sm card-hover text-left flex items-start justify-between gap-4 cursor-pointer" onclick="openDetail(${s.id})">
<div class="space-y-1"> <div class="space-y-1">
<span class="text-[8px] font-black bg-${color}-100 text-${color}-600 px-2 py-0.5 rounded-full uppercase">${label}</span> <div class="flex items-center gap-2 mb-2">
<h4 class="font-black text-slate-800 uppercase text-xs leading-tight mt-1">${name}</h4> <span class="text-[8px] font-black bg-${color}-100 text-${color}-600 px-2 py-0.5 rounded-md uppercase tracking-wider">${label}</span>
<span class="text-[8px] text-slate-400 font-bold uppercase border border-slate-100 px-1.5 py-0.5 rounded-md">#${s.service_ref}</span>
</div>
<h4 class="font-black text-slate-800 uppercase text-xs leading-tight">${name}</h4>
<p class="text-[10px] text-slate-400 font-bold uppercase truncate max-w-[200px]">${addr}</p> <p class="text-[10px] text-slate-400 font-bold uppercase truncate max-w-[200px]">${addr}</p>
<div class="flex items-center gap-3 mt-3"> <div class="flex items-center gap-3 mt-3 pt-2 border-t border-slate-50">
<div class="flex items-center gap-1.5"><i data-lucide="user" class="w-3 h-3 text-slate-400"></i><span class="text-[9px] font-black text-slate-600 uppercase">${s.assigned_name || 'Sin asignar'}</span></div> <div class="flex items-center gap-1.5"><i data-lucide="user" class="w-3 h-3 text-slate-400"></i><span class="text-[9px] font-black text-slate-600 uppercase">${s.assigned_name || 'Sin asignar'}</span></div>
${raw.scheduled_date ? `<div class="flex items-center gap-1.5 text-blue-600"><i data-lucide="${iconEstado}" class="w-3 h-3"></i><span class="text-[9px] font-black uppercase">${cita}</span></div>` : ''} ${raw.scheduled_date ? `<div class="flex items-center gap-1.5 text-blue-600"><i data-lucide="${iconEstado}" class="w-3 h-3"></i><span class="text-[9px] font-black uppercase">${cita}</span></div>` : ''}
</div> </div>
</div> </div>
<div class="text-slate-300"><i data-lucide="chevron-right"></i></div>
</div>`; </div>`;
} }
@@ -255,7 +279,7 @@
document.getElementById('detId').value = s.id; document.getElementById('detId').value = s.id;
document.getElementById('detRef').innerText = s.service_ref; document.getElementById('detRef').innerText = s.service_ref;
// --- NUEVO: ASIGNAR COMPAÑÍA --- // COMPAÑÍA ASEGURADORA
const companyName = raw['Compañía'] || raw['COMPAÑIA'] || raw['Procedencia'] || "Particular"; const companyName = raw['Compañía'] || raw['COMPAÑIA'] || raw['Procedencia'] || "Particular";
document.getElementById('detCompany').innerText = companyName; document.getElementById('detCompany').innerText = companyName;
@@ -267,7 +291,7 @@
document.getElementById('detPhoneLink').href = cleanPhone ? `tel:${cleanPhone}` : "#"; document.getElementById('detPhoneLink').href = cleanPhone ? `tel:${cleanPhone}` : "#";
document.getElementById('detAddrText').innerText = `${raw["Dirección"] || "Dirección no especificada"} ${raw["Población"] || ""}`; document.getElementById('detAddrText').innerText = `${raw["Dirección"] || "Dirección no especificada"} ${raw["Población"] || ""}`;
document.getElementById('detWorker').innerText = s.assigned_name || "Pendiente"; document.getElementById('detWorker').innerText = s.assigned_name || "Pendiente Asignar";
document.getElementById('detDesc').innerHTML = (raw["Descripción"] || raw["DESCRIPCION"] || "No hay notas adicionales del siniestro.") document.getElementById('detDesc').innerHTML = (raw["Descripción"] || raw["DESCRIPCION"] || "No hay notas adicionales del siniestro.")
.replace(/\n/g, '<br>'); .replace(/\n/g, '<br>');
@@ -306,8 +330,9 @@
if(res.ok) { if(res.ok) {
closeDetailModal(); closeDetailModal();
document.getElementById('toastAppt').classList.remove('hidden'); const toast = document.getElementById('toastAppt');
setTimeout(() => { document.getElementById('toastAppt').classList.add('hidden'); }, 3000); toast.classList.remove('hidden');
setTimeout(() => { toast.classList.add('hidden'); }, 3000);
refreshPanel(); refreshPanel();
} else { } else {
alert("Error en el servidor al guardar."); alert("Error en el servidor al guardar.");