diff --git a/proveedores.html b/proveedores.html index ca7cc4e..a82bf80 100644 --- a/proveedores.html +++ b/proveedores.html @@ -91,6 +91,7 @@
+ @@ -302,6 +303,134 @@ } catch (e) { console.error("Error en loadInbox:", e); } } + // NUEVA FUNCIÓN PARA CONSTRUIR LA TARJETA HTML (Evita repetir código) + function buildServiceCard(svc) { + const raw = svc.raw_data || {}; + const isArchived = svc.status === 'archived'; + + const name = raw['Nombre Cliente'] || raw['CLIENTE'] || "S/N"; + const addr = raw['Dirección'] || raw['DOMICILIO'] || ""; + const pop = raw['Población'] || raw['POBLACION-PROVINCIA'] || ""; + const fullAddr = `${addr} ${pop}`.trim(); + const phone = (raw['Teléfono'] || raw['TELEFONOS'] || raw['TELEFONO'] || "").match(/[6789]\d{8}/)?.[0] || ""; + const guildName = allGuilds.find(g => g.id == raw['guild_id'])?.name || null; + const opName = raw['assigned_to_name'] || null; + + let badgeEstado = ''; + let bgClass = 'bg-white'; + let isLocked = false; + let lockedMsg = ''; + + const autoStatus = (svc.automation_status || '').toLowerCase(); + const sysStatus = (svc.status || '').toLowerCase(); + const linkedStatus = (raw['estado'] || raw['status'] || '').toLowerCase(); + + if (!isArchived) { + if (autoStatus.includes('bolsa') || autoStatus === 'in_progress' || sysStatus.includes('bolsa') || linkedStatus.includes('bolsa')) { + bgClass = 'bg-orange-50/40 border-orange-200 hover:border-orange-400'; + isLocked = true; + lockedMsg = 'Este servicio está en la BOLSA buscando operario.'; + badgeEstado = ` +
+ + En Bolsa + + Buscando operario... +
`; + } else if (raw['assigned_to'] || (sysStatus === 'imported' && opName)) { + bgClass = 'bg-emerald-50/40 border-emerald-200 hover:border-emerald-400'; + isLocked = true; + lockedMsg = 'Servicio ASIGNADO. Ve al Panel Operativo para gestionarlo.'; + badgeEstado = ` +
+ + Asignado + + ${opName || 'Operario'} +
`; + } else if (sysStatus === 'imported') { + bgClass = 'bg-blue-50/40 border-blue-200 hover:border-blue-400'; + isLocked = true; + lockedMsg = 'Este servicio ya se traspasó al Panel Operativo.'; + badgeEstado = ` +
+ + En Panel + + Esperando acción +
`; + } else if (autoStatus === 'failed') { + bgClass = 'bg-red-50/40 border-red-200 hover:border-red-400'; + isLocked = false; + badgeEstado = ` +
+ + Fallo Bolsa + + Nadie aceptó +
`; + } else { + bgClass = 'bg-white border-slate-200'; + badgeEstado = ` +
+ + Sin Asignar + +
`; + } + } else { + bgClass = 'bg-gray-50 border-gray-200 archived'; + badgeEstado = ` +
+ + Archivado + +
`; + } + + const card = document.createElement('div'); + card.id = `card-${svc.id}`; + card.className = `service-card p-5 rounded-2xl border ${bgClass} flex items-center justify-between transition-all group fade-in ${isLocked ? 'locked' : ''}`; + + card.onclick = (e) => { + if (e.target.closest('a') || e.target.closest('button')) return; + if (isArchived) { + showToast("⚠️ Este servicio está ARCHIVADO.", true); + } else if (isLocked) { + card.classList.remove('shake'); + void card.offsetWidth; + card.classList.add('shake'); + showToast(`🔒 ${lockedMsg}`, true); + } else { + openEditor(svc.id); + } + }; + + card.innerHTML = ` +
+
+ ${svc.provider === 'multiasistencia' ? 'MULTI' : 'HOME'} + +
+
+ +
+
+

${name}

+

${fullAddr}

+
+ #${svc.service_ref} + ${guildName ? `${guildName}` : ''} +
+
+
+
+ ${badgeEstado} +
`; + + return card; + } + function renderFilteredInbox() { const container = document.getElementById('inboxContainer'); const search = document.getElementById('searchBox').value.toUpperCase(); @@ -326,147 +455,45 @@ }); container.innerHTML = ""; + if(filtered.length === 0) { container.innerHTML = '
No se encontraron expedientes con estos filtros.
'; return; } - filtered.forEach(svc => { - const raw = svc.raw_data || {}; - const isArchived = svc.status === 'archived'; + // SEPARAR ACTIVOS Y ARCHIVADOS + const activeServices = filtered.filter(svc => svc.status !== 'archived'); + const archivedServices = filtered.filter(svc => svc.status === 'archived'); + + // 1. RENDERIZAR ACTIVOS + activeServices.forEach(svc => container.appendChild(buildServiceCard(svc))); + + // 2. RENDERIZAR ARCHIVADOS AL FINAL (CON ACORDEÓN) + if (archivedServices.length > 0) { + // Si el usuario busca algo específico o filtra solo archivados, abrimos el acordeón automáticamente + const isAutoExpanded = (search.length > 0 || status === 'archived'); + + const divider = document.createElement('div'); + divider.className = "mt-10 mb-4 border-t border-slate-200 pt-8 fade-in"; + divider.innerHTML = ` + + `; + container.appendChild(divider); + + const archContainer = document.createElement('div'); + archContainer.id = 'archivedCardsContainer'; + archContainer.className = `space-y-4 fade-in ${isAutoExpanded ? '' : 'hidden'}`; - const name = raw['Nombre Cliente'] || raw['CLIENTE'] || "S/N"; - const addr = raw['Dirección'] || raw['DOMICILIO'] || ""; - const pop = raw['Población'] || raw['POBLACION-PROVINCIA'] || ""; - const fullAddr = `${addr} ${pop}`.trim(); - const phone = (raw['Teléfono'] || raw['TELEFONOS'] || raw['TELEFONO'] || "").match(/[6789]\d{8}/)?.[0] || ""; - const guildName = allGuilds.find(g => g.id == raw['guild_id'])?.name || null; - const opName = raw['assigned_to_name'] || null; + archivedServices.forEach(svc => archContainer.appendChild(buildServiceCard(svc))); + container.appendChild(archContainer); + } - let badgeEstado = ''; - let bgClass = 'bg-white'; - let isLocked = false; - let lockedMsg = ''; - - // LA LÓGICA TOTALMENTE MODIFICADA CON EL CHIVATO DE DEPURACIÓN - const autoStatus = (svc.automation_status || '').toLowerCase(); - const sysStatus = (svc.status || '').toLowerCase(); - const linkedStatus = (raw['estado'] || raw['status'] || '').toLowerCase(); - - if (!isArchived) { - // 1. EN BOLSA / EN COLA - if (autoStatus.includes('bolsa') || autoStatus === 'in_progress' || sysStatus.includes('bolsa') || linkedStatus.includes('bolsa')) { - bgClass = 'bg-orange-50/40 border-orange-200 hover:border-orange-400'; - isLocked = true; - lockedMsg = 'Este servicio está en la BOLSA buscando operario.'; - badgeEstado = ` -
- - En Bolsa - - Buscando operario... -
`; - } - // 2. ASIGNADO A UN OPERARIO - else if (raw['assigned_to'] || (sysStatus === 'imported' && opName)) { - bgClass = 'bg-emerald-50/40 border-emerald-200 hover:border-emerald-400'; - isLocked = true; - lockedMsg = 'Servicio ASIGNADO. Ve al Panel Operativo para gestionarlo.'; - badgeEstado = ` -
- - Asignado - - ${opName || 'Operario'} -
`; - } - // 3. TRASPASADO AL PANEL, PERO SIN BOLSA NI OPERARIO (Pausa/Manual) - else if (sysStatus === 'imported') { - bgClass = 'bg-blue-50/40 border-blue-200 hover:border-blue-400'; - isLocked = true; - lockedMsg = 'Este servicio ya se traspasó al Panel Operativo.'; - badgeEstado = ` -
- - En Panel - - Esperando acción -
`; - } - // 4. FALLO DE ASIGNACIÓN (Se acaban los operarios en cola) - else if (autoStatus === 'failed') { - bgClass = 'bg-red-50/40 border-red-200 hover:border-red-400'; - isLocked = false; - badgeEstado = ` -
- - Fallo Bolsa - - Nadie aceptó -
`; - } - // 5. NUEVO EN EL BUZÓN (Gris) - else { - bgClass = 'bg-white border-slate-200'; - badgeEstado = ` -
- - Sin Asignar - - sys:${sysStatus}|auto:${autoStatus} -
`; - } - } else { - bgClass = 'bg-gray-50 border-gray-200 archived'; - badgeEstado = ` -
- - Archivado - -
`; - } - - const card = document.createElement('div'); - card.id = `card-${svc.id}`; - card.className = `service-card p-5 rounded-2xl border ${bgClass} flex items-center justify-between transition-all group fade-in ${isLocked ? 'locked' : ''}`; - - card.onclick = (e) => { - if (e.target.closest('a') || e.target.closest('button')) return; - if (isArchived) { - showToast("⚠️ Este servicio está ARCHIVADO.", true); - } else if (isLocked) { - card.classList.remove('shake'); - void card.offsetWidth; - card.classList.add('shake'); - showToast(`🔒 ${lockedMsg}`, true); - } else { - openEditor(svc.id); - } - }; - - card.innerHTML = ` -
-
- ${svc.provider === 'multiasistencia' ? 'MULTI' : 'HOME'} - -
-
- -
-
-

${name}

-

${fullAddr}

-
- #${svc.service_ref} - ${guildName ? `${guildName}` : ''} -
-
-
-
- ${badgeEstado} -
`; - container.appendChild(card); - }); lucide.createIcons(); }