diff --git a/servicios.html b/servicios.html
index 60c656b..d503c0c 100644
--- a/servicios.html
+++ b/servicios.html
@@ -11,6 +11,15 @@
@keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
.no-scrollbar::-webkit-scrollbar { display: none; }
.card-hover:hover { transform: translateY(-2px); transition: all 0.2s; box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.05); }
+
+ /* ANIMACIÓN DE TEMBLOR (SHAKE) PARA TARJETAS BLOQUEADAS */
+ .shake { animation: shake 0.4s cubic-bezier(.36,.07,.19,.97) both; }
+ @keyframes shake {
+ 10%, 90% { transform: translate3d(-2px, 0, 0); }
+ 20%, 80% { transform: translate3d(4px, 0, 0); }
+ 30%, 50%, 70% { transform: translate3d(-6px, 0, 0); }
+ 40%, 60% { transform: translate3d(6px, 0, 0); }
+ }
@@ -240,8 +249,9 @@
-
-
Guardado correctamente
+
+
+ Guardado correctamente
@@ -303,7 +313,17 @@
const assigned = filteredData.filter(s => s.raw_data.scheduled_date && s.raw_data.scheduled_date !== "" && s.raw_data.status_operativo !== 'sin_asignar');
document.getElementById('unassigned-list').innerHTML = unassigned.length > 0
- ? unassigned.map(s => cardTemplate(s, 'rose', s.assigned_name ? 'Pausado' : 'Sin Asignar')).join('')
+ ? unassigned.map(s => {
+ let color = 'rose';
+ let label = s.assigned_name ? 'Pausado' : 'Sin Asignar';
+
+ // COLORES INTELIGENTES PARA LA BOLSA DE TRABAJO
+ if (!s.assigned_name) {
+ if (s.automation_status === 'in_progress') { color = 'amber'; label = 'Buscando (WA)'; }
+ if (s.automation_status === 'failed') { color = 'orange'; label = 'En Bolsa'; }
+ }
+ return cardTemplate(s, color, label);
+ }).join('')
: '
Vacío
';
document.getElementById('pending-list').innerHTML = pending.length > 0
@@ -337,23 +357,69 @@
if(raw.status_operativo === 'incidencia') iconEstado = 'alert-triangle';
if(raw.status_operativo === 'terminado') iconEstado = 'check-circle';
+ // DICCIONARIO DE COLORES BLINDADO PARA TAILWIND JIT
+ const colorClasses = {
+ 'rose': 'bg-rose-100 text-rose-600',
+ 'blue': 'bg-blue-100 text-blue-600',
+ 'emerald': 'bg-emerald-100 text-emerald-600',
+ 'amber': 'bg-amber-100 text-amber-600',
+ 'orange': 'bg-orange-100 text-orange-600',
+ 'red': 'bg-red-100 text-red-600',
+ 'purple': 'bg-purple-100 text-purple-600'
+ };
+ const badgeClass = colorClasses[color] || 'bg-slate-100 text-slate-600';
+
+ // LÓGICA DE BLOQUEO (No se puede abrir si está buscando o en bolsa, a menos que ya tenga operario y sea pausa)
+ const isBlocked = !s.assigned_name && (s.automation_status === 'in_progress' || s.automation_status === 'failed');
+ const clickAction = isBlocked ? `shakeCard(this, '${s.automation_status}')` : `openDetail(${s.id})`;
+ const cursorStyle = isBlocked ? 'cursor-not-allowed' : 'cursor-pointer';
+
return `
-
-
+
+
- ${label}
+ ${label}
#${s.service_ref}
-
${name}
-
${addr}
+
${name}
+
${addr}
${s.assigned_name || 'Sin asignar'}
- ${raw.scheduled_date ? `
${cita}
` : ''}
+ ${raw.scheduled_date && !isBlocked ? `
${cita}
` : ''}
`;
}
+ // FUNCIÓN QUE HACE TEMBLAR LA TARJETA
+ function shakeCard(element, status) {
+ element.classList.add('shake');
+ setTimeout(() => element.classList.remove('shake'), 400);
+
+ if (status === 'in_progress') {
+ showToast("⏳ El robot está asignando este servicio por WhatsApp...", "warning");
+ } else {
+ showToast("📍 Este servicio está en la bolsa esperando a que un operario lo coja.", "warning");
+ }
+ }
+
+ function showToast(msg, type = 'success') {
+ const toast = document.getElementById('toastAppt');
+ const iconContainer = document.getElementById('toastIconContainer');
+ document.getElementById('toastMsg').innerText = msg;
+
+ if (type === 'warning') {
+ toast.classList.replace('bg-emerald-600', 'bg-amber-500');
+ iconContainer.innerHTML = '
';
+ } else {
+ toast.classList.replace('bg-amber-500', 'bg-emerald-600');
+ iconContainer.innerHTML = '
';
+ }
+ lucide.createIcons();
+ toast.classList.remove('hidden');
+ setTimeout(() => { toast.classList.add('hidden'); }, 3500);
+ }
+
function openDetail(id) {
const s = localData.find(x => x.id === id);
if (!s) return;
@@ -373,9 +439,7 @@
document.getElementById('detDesc').innerHTML = (raw["Descripción"] || raw["DESCRIPCION"] || "Sin notas.").replace(/\n/g, '
');
- // LÓGICA DE PANELES LATERALES
if (s.assigned_name && raw.status_operativo !== 'sin_asignar') {
- // TIENE OPERARIO: Mostrar panel de fechas
document.getElementById('panelAsignado').classList.remove('hidden');
document.getElementById('panelSinAsignar').classList.add('hidden');
@@ -384,11 +448,9 @@
document.getElementById('timeInput').value = raw.scheduled_time || "";
document.getElementById('detStatusMap').value = raw.status_operativo || 'citado';
} else {
- // NO TIENE OPERARIO (O FUE PAUSADO): Mostrar panel de re-asignación
document.getElementById('panelAsignado').classList.add('hidden');
document.getElementById('panelSinAsignar').classList.remove('hidden');
- // Pre-cargar el gremio si el robot lo detectó previamente
if(raw.guild_id) {
document.getElementById('reGremio').value = raw.guild_id;
loadOps(raw.guild_id, 'reOperario');
@@ -408,11 +470,7 @@
const time = document.getElementById('timeInput').value;
const statusMap = document.getElementById('detStatusMap').value;
- // Si lo mandan a "sin_asignar", borrar operario en BD
- let assigned_to = undefined;
- if (statusMap === 'sin_asignar') {
- assigned_to = null;
- } else if(!date && statusMap !== 'incidencia' && statusMap !== 'terminado') {
+ if (statusMap !== 'sin_asignar' && !date && statusMap !== 'incidencia' && statusMap !== 'terminado') {
if(!confirm("No has asignado Fecha. ¿Deseas continuar?")) return;
}
@@ -422,7 +480,6 @@
btn.disabled = true;
try {
- // Si cambiamos a sin_asignar, usamos la ruta de scraped para borrar el assigned_to
if(statusMap === 'sin_asignar') {
await fetch(`${API_URL}/providers/scraped/${id}`, {
method: 'PUT',
@@ -459,8 +516,8 @@
});
const data = await res.json();
if(data.ok) { closeDetailModal(); showToast("Enviado a la rueda de WhatsApp"); refreshPanel(); }
- else { alert(data.error || "No hay operarios en esa zona para ese gremio"); btn.innerHTML = 'Mandar a la Cola'; }
- } catch (e) { alert("Error"); btn.innerHTML = 'Mandar a la Cola'; }
+ else { alert(data.error || "No hay operarios en esa zona para ese gremio"); btn.innerHTML = '
Mandar a la Cola
Rueda automática (WA)
'; lucide.createIcons(); }
+ } catch (e) { alert("Error"); }
}
async function assignManualFromPanel() {
@@ -489,13 +546,6 @@
} catch (e) { alert("Error"); }
}
- function showToast(msg) {
- document.getElementById('toastMsg').innerText = msg;
- const toast = document.getElementById('toastAppt');
- toast.classList.remove('hidden');
- setTimeout(() => { toast.classList.add('hidden'); }, 3000);
- }
-
async function saveNewService(e) {
e.preventDefault();
const action = e.submitter.value;