From 16eb587eaecbaa325ce7fdad54c8904ceb3ed2f5 Mon Sep 17 00:00:00 2001 From: marsalva Date: Sun, 8 Feb 2026 22:41:50 +0000 Subject: [PATCH] Actualizar fconfiguracion.html --- configuracion.html => fconfiguracion.html | 108 ++++++++++++++-------- 1 file changed, 68 insertions(+), 40 deletions(-) rename configuracion.html => fconfiguracion.html (76%) diff --git a/configuracion.html b/fconfiguracion.html similarity index 76% rename from configuracion.html rename to fconfiguracion.html index 48b30c0..d01419d 100644 --- a/configuracion.html +++ b/fconfiguracion.html @@ -24,7 +24,7 @@

- Configuración + Configuración Avanzada

@@ -56,17 +56,17 @@
- 2. Crear/Elegir Zona - + 2. Zonas Definidas +
-
+

Selecciona una provincia

3. Asignar Operarios - +

Selecciona una zona

@@ -123,7 +123,7 @@
- +
@@ -168,8 +168,8 @@ cont.innerHTML = ""; list.forEach(p => { const div = document.createElement('div'); - div.className = "p-2 hover:bg-blue-50 rounded cursor-pointer text-sm flex justify-between items-center group prov-item"; - div.innerHTML = `${p.name}`; + div.className = "p-2 hover:bg-blue-50 rounded cursor-pointer text-sm flex justify-between items-center group prov-item transition-colors"; + div.innerHTML = `${p.name}`; div.onclick = () => selectProvince(p.id, div); cont.appendChild(div); }); @@ -183,11 +183,12 @@ async function selectProvince(id, el) { currentProvId = id; - document.querySelectorAll('.prov-item').forEach(d => d.classList.remove('bg-blue-100', 'font-bold')); - el.classList.add('bg-blue-100', 'font-bold'); + document.querySelectorAll('.prov-item').forEach(d => d.classList.remove('bg-blue-100', 'font-bold', 'text-blue-700')); + el.classList.add('bg-blue-100', 'font-bold', 'text-blue-700'); document.getElementById('colZones').classList.remove('opacity-50', 'pointer-events-none'); document.getElementById('colOperators').classList.add('opacity-50', 'pointer-events-none'); + document.getElementById('listOperators').innerHTML = '

Selecciona una zona

'; loadZones(id); } @@ -197,19 +198,19 @@ const list = document.getElementById('listZones'); list.innerHTML = ""; - if(data.zones.length === 0) list.innerHTML = '

No hay zonas. Crea una.

'; + if(data.zones.length === 0) list.innerHTML = '

No hay zonas definidas en esta provincia.

'; data.zones.forEach(z => { const div = document.createElement('div'); - div.className = "p-3 border border-gray-100 rounded hover:border-blue-300 cursor-pointer bg-white mb-2 zone-item"; - let townsText = z.towns_names && z.towns_names.length > 0 ? z.towns_names.join(", ") : "Sin poblaciones"; + div.className = "p-3 border border-gray-100 rounded hover:border-blue-300 hover:shadow-sm cursor-pointer bg-white zone-item transition-all"; + let townsText = z.towns_names && z.towns_names.length > 0 ? z.towns_names.join(", ") : "Sin poblaciones asignadas"; div.innerHTML = ` -
- ${z.name} - ${z.owner_id ? `` : ''} +
+ ${z.name} + ${z.owner_id ? `` : ''}
-

${townsText}

+

${townsText}

`; div.onclick = () => selectZone(z.id, div); list.appendChild(div); @@ -221,16 +222,15 @@ if(!currentProvId) return; document.getElementById('newZoneName').value = ""; - // Cargar pueblos const res = await fetch(`${API_URL}/provinces/${currentProvId}/towns`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); const data = await res.json(); const list = document.getElementById('townsList'); list.innerHTML = ""; - if(data.towns.length === 0) list.innerHTML = '

No hay poblaciones cargadas.

'; + if(data.towns.length === 0) list.innerHTML = '

No hay poblaciones disponibles para esta provincia.

'; data.towns.forEach(t => { - list.innerHTML += ``; + list.innerHTML += ``; }); document.getElementById('zoneModal').classList.remove('hidden'); } @@ -240,46 +240,74 @@ const checks = document.querySelectorAll('.town-check:checked'); const townIds = Array.from(checks).map(c => c.value); - if(!name) { alert("Pon un nombre"); return; } + if(!name) { alert("Debes poner un nombre a la zona"); return; } - await fetch(`${API_URL}/zones`, { - method: 'POST', - headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` }, - body: JSON.stringify({ province_id: currentProvId, name, town_ids: townIds }) - }); - - document.getElementById('zoneModal').classList.add('hidden'); - loadZones(currentProvId); + try { + const res = await fetch(`${API_URL}/zones`, { + method: 'POST', + headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` }, + body: JSON.stringify({ province_id: currentProvId, name, town_ids: townIds }) + }); + if(res.ok) { + showToast("Zona creada correctamente"); + document.getElementById('zoneModal').classList.add('hidden'); + loadZones(currentProvId); + } else { showToast("Error al crear zona", true); } + } catch(e) { showToast("Error de conexión", true); } } - async function deleteZone(id) { - if(!confirm("¿Borrar zona?")) return; - await fetch(`${API_URL}/zones/${id}`, { method: 'DELETE', headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); - loadZones(currentProvId); + async function deleteZone(event, id) { + event.stopPropagation(); // Evita seleccionar la zona al borrar + if(!confirm("¿Estás seguro de borrar esta zona? Esta acción no se puede deshacer.")) return; + + try { + const res = await fetch(`${API_URL}/zones/${id}`, { method: 'DELETE', headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); + if(res.ok) { + showToast("Zona eliminada"); + loadZones(currentProvId); + // Resetear panel de operarios si estaba seleccionada esa zona + if(currentZoneId === id) { + document.getElementById('colOperators').classList.add('opacity-50', 'pointer-events-none'); + document.getElementById('listOperators').innerHTML = '

Selecciona una zona

'; + } + } else { showToast("No se pudo borrar", true); } + } catch(e) { showToast("Error de conexión", true); } } async function selectZone(id, el) { currentZoneId = id; - document.querySelectorAll('.zone-item').forEach(d => d.classList.remove('border-blue-500', 'bg-blue-50')); - el.classList.add('border-blue-500', 'bg-blue-50'); + document.querySelectorAll('.zone-item').forEach(d => d.classList.remove('border-blue-500', 'bg-blue-50', 'ring-1', 'ring-blue-500')); + el.classList.add('border-blue-500', 'bg-blue-50', 'ring-1', 'ring-blue-500'); document.getElementById('colOperators').classList.remove('opacity-50', 'pointer-events-none'); loadOperatorsForZone(id); } async function loadOperatorsForZone(zoneId) { + const list = document.getElementById('listOperators'); + list.innerHTML = '

Cargando operarios...

'; + const resOps = await fetch(`${API_URL}/operators`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); const dataOps = await resOps.json(); const resAssigned = await fetch(`${API_URL}/zones/${zoneId}/operators`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); - const dataAssigned = await resAssigned.json(); + const dataAssigned = await resAssigned.json(); const assignedSet = new Set(dataAssigned.assignedIds); - const list = document.getElementById('listOperators'); list.innerHTML = ""; + if(dataOps.operators.length === 0) { + list.innerHTML = '

No hay operarios registrados en el sistema.

'; + return; + } + dataOps.operators.forEach(op => { const checked = assignedSet.has(op.id) ? 'checked' : ''; - list.innerHTML += ``; + list.innerHTML += ` + + `; }); } @@ -292,8 +320,8 @@ headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` }, body: JSON.stringify({ operator_ids: ids }) }); - showToast("Asignación guardada ✅"); - } catch(e) { showToast("Error al guardar", true); } + showToast("Asignación guardada correctamente ✅"); + } catch(e) { showToast("Error al guardar asignación", true); } } function showToast(msg, isError = false) {