diff --git a/proveedores.html b/proveedores.html index f30c937..8dba49d 100644 --- a/proveedores.html +++ b/proveedores.html @@ -12,12 +12,22 @@ .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; } .no-scrollbar::-webkit-scrollbar { display: none; } .service-card { cursor: pointer; transition: all 0.2s ease; position: relative; } - .service-card:hover:not(.archived) { transform: translateY(-2px); border-color: #3b82f6; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); } - .archived { opacity: 0.7; grayscale: 100%; } + .service-card:hover:not(.archived):not(.locked) { transform: translateY(-2px); border-color: #3b82f6; box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); } + .archived { opacity: 0.7; filter: grayscale(100%); } + .locked { cursor: not-allowed; } /* Animación suave para el icono de esperando */ .pulse-slow { animation: pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: .5; } } + + /* Animación de temblor para las tarjetas bloqueadas */ + .shake { animation: shake 0.4s cubic-bezier(.36,.07,.19,.97) both; } + @keyframes shake { + 10%, 90% { transform: translate3d(-1px, 0, 0); } + 20%, 80% { transform: translate3d(2px, 0, 0); } + 30%, 50%, 70% { transform: translate3d(-4px, 0, 0); } + 40%, 60% { transform: translate3d(4px, 0, 0); } + } @@ -309,7 +319,7 @@ const raw = svc.raw_data || {}; const isArchived = svc.status === 'archived'; const statusLabel = isArchived ? 'ARCHIVADO' : 'SERVICIO ACTIVO'; - const statusClass = isArchived ? 'bg-gray-100 text-gray-500 border-gray-200' : 'bg-emerald-50 text-emerald-600 border-emerald-100'; + const name = raw['Nombre Cliente'] || raw['CLIENTE'] || "S/N"; const addr = raw['Dirección'] || raw['DOMICILIO'] || ""; const pop = raw['Población'] || raw['POBLACION-PROVINCIA'] || ""; @@ -318,25 +328,39 @@ const guildName = allGuilds.find(g => g.id == raw['guild_id'])?.name || null; const opName = raw['assigned_to_name'] || null; - // LOGICA DE ESTADO VISUAL + // LÓGICA DE ESTADO VISUAL Y BLOQUEO let badgeEstado = ''; + let bgClass = 'bg-white'; + let isLocked = false; + let lockedMsg = ''; + if (!isArchived) { if (svc.automation_status === 'in_progress') { + // EN COLA (Amarillo) + bgClass = 'bg-amber-50/40 border-amber-200'; + isLocked = true; + lockedMsg = 'Este servicio está actualmente en la rueda de WhatsApp buscando operario.'; badgeEstado = `
- + En Cola / Esperando
`; - } else if (raw['assigned_to']) { + } else if (raw['assigned_to'] || svc.status === 'imported') { + // ASIGNADO / TRASPASADO (Verde) + bgClass = 'bg-emerald-50/40 border-emerald-200'; + isLocked = true; + lockedMsg = 'Este servicio ya ha sido asignado o traspasado. Ve al Panel Operativo para gestionarlo.'; badgeEstado = `
- + Asignado - ${opName || 'Operario'} + ${opName || 'Operario asignado'}
`; } else { + // NORMAL (Blanco) + bgClass = 'bg-white border-slate-200'; badgeEstado = `
@@ -344,15 +368,32 @@
`; } + } else { + bgClass = 'bg-gray-50 border-gray-200 archived'; } const card = document.createElement('div'); - card.className = `service-card bg-white p-5 rounded-2xl border ${isArchived ? 'archived' : 'shadow-sm'} flex items-center justify-between transition-all group fade-in text-left`; + 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 text-left ${isLocked ? 'locked' : ''}`; + card.onclick = (e) => { if (e.target.closest('a') || e.target.closest('button')) return; - if (isArchived) showToast("⚠️ Este servicio está ARCHIVADO.", true); - else openEditor(svc.id); + + if (isArchived) { + showToast("⚠️ Este servicio está ARCHIVADO.", true); + } else if (isLocked) { + // Animación de temblor + card.classList.remove('shake'); + void card.offsetWidth; // Forzar reflow + card.classList.add('shake'); + showToast(`🔒 Bloqueado: ${lockedMsg}`, true); + } else { + openEditor(svc.id); + } }; + + const statusClass = isArchived ? 'bg-gray-100 text-gray-500 border-gray-200' : 'bg-blue-50 text-blue-600 border-blue-100'; + card.innerHTML = `
@@ -365,7 +406,6 @@

${name}

- ${statusLabel}

${fullAddr}

@@ -379,9 +419,9 @@ ${badgeEstado} ${!isArchived ? ` - `; container.appendChild(card); @@ -403,15 +443,14 @@ document.getElementById('impScrapedId').value = id; document.getElementById('impName').value = raw['Nombre Cliente'] || raw['CLIENTE'] || "S/N"; - // Permite editar telefono const rawPhone = raw['Teléfono'] || raw['TELEFONOS'] || raw['TELEFONO'] || ""; - document.getElementById('impPhone').value = rawPhone.match(/[6789]\d{8}/)?.[0] || rawPhone; + document.getElementById('impPhone').value = rawPhone.match(/[6789]\d{8}/)?.[0] || ""; const addr = raw['Dirección'] || raw['DOMICILIO'] || ""; const pop = raw['Población'] || raw['POBLACION-PROVINCIA'] || ""; document.getElementById('impAddress').value = `${addr} ${pop}`.trim(); document.getElementById('impCP').value = raw['Código Postal'] || raw['C.P.'] || ""; - document.getElementById('impDesc').value = raw['Descripción'] || raw['DESCRIPCION'] || ""; + document.getElementById('impDesc').value = raw['Descripción'] || ""; const isUrgent = raw['Urgente'] === 'Sí' || raw['Urgente'] === 'true' || raw['URGENTE'] === 'SI'; document.getElementById('impUrgent').value = isUrgent.toString(); @@ -462,7 +501,6 @@ return res.ok; } - // CAMBIO 2: Guardar Borrador ahora cierra el modal. async function saveDraftChanges(e) { const id = document.getElementById('impScrapedId').value; const btn = e.currentTarget; @@ -471,7 +509,7 @@ const ok = await saveFormToDB(id, getFormPayload()); if(ok) { showToast("✅ Cambios guardados correctamente"); - closeModal(); // Cierra el modal + closeModal(); loadInbox(); } else { showToast("❌ Error al guardar", true); } @@ -479,7 +517,6 @@ finally { btn.disabled = false; } } - // CAMBIO 3: Traspaso Manual bloquea si no hay operario asignado async function handleFinalImport(event) { event.preventDefault(); const btn = event.submitter; @@ -488,7 +525,6 @@ const id = document.getElementById('impScrapedId').value; const payload = getFormPayload(); - // VALIDACIÓN: ¿Hay operario seleccionado? if (!payload.assigned_to) { showToast("⚠️ ERROR: Selecciona un operario para hacer el traspaso manual.", true); return;