Actualizar servicios.html

This commit is contained in:
2026-03-02 23:04:04 +00:00
parent dd9566f1e1
commit c01f8431aa

View File

@@ -572,70 +572,73 @@ async function searchClientByPhone(phone) {
} }
function buildGridCard(s) { function buildGridCard(s) {
const raw = s.raw_data || {}; const raw = s.raw_data || {};
const name = raw["Nombre Cliente"] || raw["CLIENTE"] || "Asegurado Sin Nombre"; const name = raw["Nombre Cliente"] || raw["CLIENTE"] || "Asegurado Sin Nombre";
const addr = raw["Dirección"] || raw["DOMICILIO"] || "---"; const addr = raw["Dirección"] || raw["DOMICILIO"] || "---";
const pop = raw["Población"] || raw["POBLACION-PROVINCIA"] || ""; const pop = raw["Población"] || raw["POBLACION-PROVINCIA"] || "";
const fullAddr = `${addr} ${pop}`.trim(); const fullAddr = `${addr} ${pop}`.trim();
const cita = raw.scheduled_date ? `${raw.scheduled_date} | ${raw.scheduled_time}` : 'Pendiente Cita'; const cita = raw.scheduled_date ? `${raw.scheduled_date.split('-').reverse().slice(0,2).join('/')} | ${raw.scheduled_time}` : 'Pte. Cita';
const companyName = raw['Compañía'] || raw['COMPAÑIA'] || raw['Procedencia'] || (s.provider === 'MANUAL' ? 'PARTICULAR' : 'ASEGURADORA'); const companyName = raw['Compañía'] || raw['COMPAÑIA'] || raw['Procedencia'] || (s.provider === 'MANUAL' ? 'PARTICULAR' : 'ASEGURADORA');
const isUrgent = s.is_urgent === true || (raw['Urgente'] && raw['Urgente'].toLowerCase() === 'sí') || (raw['URGENTE'] && raw['URGENTE'].toLowerCase() === 'si'); const isUrgent = s.is_urgent === true || (raw['Urgente'] && raw['Urgente'].toLowerCase() === 'sí') || (raw['URGENTE'] && raw['URGENTE'].toLowerCase() === 'si');
const stateInfo = s._stateInfo; const stateInfo = s._stateInfo;
const colorData = colorDict[stateInfo.color] || colorDict['gray']; const colorData = colorDict[stateInfo.color] || colorDict['gray'];
let iconEstado = 'tag'; let iconEstado = 'tag';
if(raw.scheduled_date) iconEstado = 'calendar'; if(raw.scheduled_date) iconEstado = 'calendar';
if(stateInfo.name.toLowerCase().includes('camino')) iconEstado = 'car'; if(stateInfo.name.toLowerCase().includes('camino')) iconEstado = 'car';
if(stateInfo.name.toLowerCase().includes('reparaci') || stateInfo.name.toLowerCase().includes('trabaja')) iconEstado = 'wrench'; if(stateInfo.name.toLowerCase().includes('reparaci') || stateInfo.name.toLowerCase().includes('trabaja')) iconEstado = 'wrench';
if(stateInfo.name.toLowerCase().includes('incidencia') || stateInfo.name.toLowerCase().includes('pausado')) iconEstado = 'alert-triangle'; if(stateInfo.name.toLowerCase().includes('incidencia') || stateInfo.name.toLowerCase().includes('pausado')) iconEstado = 'alert-triangle';
const inProgressBadge = s.automation_status === 'in_progress' ? `<span class="absolute -top-3 -right-3 bg-amber-400 text-white px-3 py-1 rounded-full text-[10px] font-black uppercase shadow-lg border-2 border-white flex items-center gap-1 animate-pulse z-10"><i data-lucide="bot" class="w-3 h-3"></i> En Bolsa</span>` : ''; const inProgressBadge = s.automation_status === 'in_progress' ? `<span class="absolute -top-3 -right-3 bg-amber-400 text-white px-3 py-1 rounded-full text-[10px] font-black uppercase shadow-lg border-2 border-white flex items-center gap-1 animate-pulse z-10"><i data-lucide="bot" class="w-3 h-3"></i> En Bolsa</span>` : '';
return ` return `
<div class="bg-white p-5 rounded-3xl border border-slate-200 shadow-sm card-hover text-left flex flex-col justify-between relative cursor-pointer" onclick="openDetail(${s.id})"> <div class="bg-white p-5 rounded-3xl border border-slate-200 shadow-sm card-hover text-left flex flex-col justify-between relative cursor-pointer" onclick="openDetail(${s.id})">
${inProgressBadge} ${inProgressBadge}
<div class="space-y-3"> <div class="space-y-3">
<div class="flex items-start justify-between w-full gap-2"> <div class="flex items-start justify-between w-full gap-2">
<span class="text-[9px] font-black ${colorData.bg} ${colorData.text} px-2.5 py-1.5 rounded-lg uppercase tracking-wider flex items-center gap-1.5 truncate border ${colorData.border}"> <span class="text-[9px] font-black ${colorData.bg} ${colorData.text} px-2.5 py-1.5 rounded-lg uppercase tracking-wider flex items-center gap-1.5 truncate border ${colorData.border}">
<div class="w-2 h-2 rounded-full ${colorData.dot}"></div> <div class="w-2 h-2 rounded-full ${colorData.dot}"></div>
<span class="truncate">${stateInfo.name}</span> <span class="truncate">${stateInfo.name}</span>
</span> </span>
${isUrgent ? `<span class="bg-red-500 text-white px-2 py-1 rounded-lg text-[9px] font-black uppercase shadow-sm animate-pulse shrink-0">🔥 URGENTE</span>` : `<span class="text-[10px] text-slate-400 font-bold uppercase bg-slate-50 border border-slate-100 px-2.5 py-1 rounded-lg shrink-0">#${s.service_ref}</span>`} ${isUrgent ? `<span class="bg-red-500 text-white px-2 py-1 rounded-lg text-[9px] font-black uppercase shadow-sm animate-pulse shrink-0">🔥 URGENTE</span>` : `<span class="text-[10px] text-slate-400 font-bold uppercase bg-slate-50 border border-slate-100 px-2.5 py-1 rounded-lg shrink-0">#${s.service_ref}</span>`}
</div>
</div> <div>
<p class="text-[9px] font-black text-blue-500 uppercase tracking-widest mb-0.5 truncate">${companyName}</p>
<h4 class="font-black text-slate-800 uppercase text-base leading-tight line-clamp-2" title="${name}">${name}</h4>
</div>
<div> <div class="bg-slate-50/50 p-3 rounded-xl border border-slate-100">
<p class="text-[9px] font-black text-blue-500 uppercase tracking-widest mb-0.5 truncate">${companyName}</p> <p class="text-[10px] text-slate-600 font-medium uppercase line-clamp-2 flex items-start gap-1.5" title="${fullAddr}">
<h4 class="font-black text-slate-800 uppercase text-base leading-tight line-clamp-2" title="${name}">${name}</h4> <i data-lucide="map-pin" class="w-3.5 h-3.5 mt-0.5 text-slate-400 shrink-0"></i> ${fullAddr}
</div> </p>
</div>
</div>
<div class="bg-slate-50/50 p-3 rounded-xl border border-slate-100"> <div class="flex items-center justify-between mt-4 pt-4 border-t border-slate-100 gap-2">
<p class="text-[10px] text-slate-600 font-medium uppercase line-clamp-2 flex items-start gap-1.5" title="${fullAddr}"> <div class="flex items-center gap-1 min-w-0 flex-1">
<i data-lucide="map-pin" class="w-3.5 h-3.5 mt-0.5 text-slate-400 shrink-0"></i> ${fullAddr} <div class="bg-slate-100 p-1 rounded-lg text-slate-500 shrink-0"><i data-lucide="hard-hat" class="w-3 h-3"></i></div>
</p> <span class="text-[10px] font-black text-slate-600 uppercase truncate flex-1" style="max-width: 70px;" title="${s.assigned_name || 'Sin asignar'}">${s.assigned_name || 'Sin asignar'}</span>
</div>
<div class="flex items-center gap-0.5 shrink-0">
<button onclick="event.stopPropagation(); window.location.href='trazabilidad.html?id=${s.id}'" class="p-1.5 text-slate-300 hover:text-blue-600 transition-colors" title="Ver Historial">
<i data-lucide="history" class="w-4 h-4"></i>
</button>
<button onclick="event.stopPropagation(); openDetail(${s.id}, true)" class="p-1.5 text-slate-300 hover:text-amber-600 transition-colors" title="Editar Ficha">
<i data-lucide="edit-3" class="w-4 h-4"></i>
</button>
</div> </div>
</div>
<div class="flex items-center justify-between mt-4 pt-4 border-t border-slate-100"> <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-2 min-w-0"> <i data-lucide="${iconEstado}" class="w-3 h-3"></i>
<div class="bg-slate-100 p-1.5 rounded-lg text-slate-500 shrink-0"><i data-lucide="hard-hat" class="w-3.5 h-3.5"></i></div> <span class="text-[9px] font-black uppercase whitespace-nowrap">${raw.scheduled_date ? cita.split('|')[0] : 'Pte. Cita'}</span>
<span class="text-[10px] font-black text-slate-600 uppercase truncate" title="${s.assigned_name || 'Sin asignar'}">${s.assigned_name || 'Sin asignar'}</span> </div>
<button onclick="event.stopPropagation(); window.location.href='trazabilidad.html?id=${s.id}'" class="p-1.5 bg-slate-50 text-slate-400 hover:text-blue-600 rounded-lg transition-colors border border-slate-100" title="Ver Historial"> </div>
<i data-lucide="history" class="w-3.5 h-3.5"></i> </div>`;
</button> }
</div>
${raw.scheduled_date ? `
<div class="flex items-center gap-1.5 text-blue-600 shrink-0 ml-2 bg-blue-50 px-2 py-1 rounded-md border border-blue-100">
<i data-lucide="${iconEstado}" class="w-3.5 h-3.5"></i>
<span class="text-[9px] font-black uppercase">${cita}</span>
</div>` : ''}
</div>
</div>`;
}
function shakeCard(element, status) { function shakeCard(element, status) {
element.classList.add('shake'); element.classList.add('shake');