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();
}