Actualizar servicios.html
This commit is contained in:
@@ -6,7 +6,6 @@
|
|||||||
<title>Servicios - IntegraRepara</title>
|
<title>Servicios - IntegraRepara</title>
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<script src="https://unpkg.com/lucide@latest"></script>
|
<script src="https://unpkg.com/lucide@latest"></script>
|
||||||
<script src="https://maps.googleapis.com/maps/api/js?key=TU_API_KEY_AQUI&libraries=places&callback=initAutocomplete" async defer></script>
|
|
||||||
<style>
|
<style>
|
||||||
.fade-in { animation: fadeIn 0.3s ease-in-out; }
|
.fade-in { animation: fadeIn 0.3s ease-in-out; }
|
||||||
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
@keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } }
|
||||||
@@ -263,7 +262,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="toast" class="fixed bottom-5 right-5 bg-slate-800 text-white px-6 py-3 rounded-lg shadow-2xl transform translate-y-20 opacity-0 transition-all duration-300 z-50 flex items-center gap-3"><span id="toastMsg">Msg</span></div>
|
<div id="toast" class="fixed bottom-5 right-5 bg-slate-800 text-white px-6 py-3 rounded-lg shadow-2xl hidden"><span id="toastMsg"></span></div>
|
||||||
|
|
||||||
<script src="js/layout.js"></script>
|
<script src="js/layout.js"></script>
|
||||||
<script>
|
<script>
|
||||||
@@ -281,14 +280,19 @@
|
|||||||
loadProvinces(); // Cargar provincias al inicio
|
loadProvinces(); // Cargar provincias al inicio
|
||||||
});
|
});
|
||||||
|
|
||||||
function initAutocomplete() {
|
// 1. FUNCIÓN GLOBAL PARA GOOGLE MAPS (Solución al error "initAutocomplete is not a function")
|
||||||
|
window.initAutocomplete = function() {
|
||||||
const input = document.getElementById("sAddress");
|
const input = document.getElementById("sAddress");
|
||||||
if(input) {
|
if(input) {
|
||||||
autocomplete = new google.maps.places.Autocomplete(input, { types: ['geocode'] });
|
// Solo cargamos si el script de Google se cargó bien
|
||||||
input.addEventListener('keydown', function(e) { if (e.key === "Enter") e.preventDefault(); });
|
try {
|
||||||
|
autocomplete = new google.maps.places.Autocomplete(input, { types: ['geocode'] });
|
||||||
|
input.addEventListener('keydown', function(e) { if (e.key === "Enter") e.preventDefault(); });
|
||||||
|
} catch(e) { console.warn("Google Maps no cargó correctamente (revisa tu API Key)"); }
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
|
// --- NAVEGACIÓN ---
|
||||||
function toggleView(view) {
|
function toggleView(view) {
|
||||||
document.getElementById('servicesListView').classList.add('hidden');
|
document.getElementById('servicesListView').classList.add('hidden');
|
||||||
document.getElementById('createServiceView').classList.add('hidden');
|
document.getElementById('createServiceView').classList.add('hidden');
|
||||||
@@ -296,16 +300,8 @@
|
|||||||
document.getElementById('servicesListView').classList.remove('hidden');
|
document.getElementById('servicesListView').classList.remove('hidden');
|
||||||
fetchServices();
|
fetchServices();
|
||||||
} else {
|
} else {
|
||||||
if(document.getElementById('editServiceId').value !== "") {
|
if(document.getElementById('editServiceId').value !== "") resetForm();
|
||||||
document.getElementById('editServiceId').value = "";
|
|
||||||
document.querySelector('form').reset();
|
|
||||||
document.getElementById('formTitle').innerHTML = '<i data-lucide="file-plus" class="text-green-600"></i> Alta de Nuevo Servicio';
|
|
||||||
document.getElementById('sDate').valueAsDate = new Date();
|
|
||||||
document.getElementById('sCreateStatus').disabled = false;
|
|
||||||
lucide.createIcons();
|
|
||||||
}
|
|
||||||
document.getElementById('createServiceView').classList.remove('hidden');
|
document.getElementById('createServiceView').classList.remove('hidden');
|
||||||
window.scrollTo(0,0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,6 +332,7 @@
|
|||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// --- AUTO ASIGNACIÓN ---
|
||||||
async function checkAutoAssign(townId) {
|
async function checkAutoAssign(townId) {
|
||||||
if(!townId) return;
|
if(!townId) return;
|
||||||
|
|
||||||
@@ -343,13 +340,16 @@
|
|||||||
const res = await fetch(`${API_URL}/towns/${townId}/auto-assign`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
|
const res = await fetch(`${API_URL}/towns/${townId}/auto-assign`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } });
|
||||||
const data = await res.json();
|
const data = await res.json();
|
||||||
|
|
||||||
|
const zoneInput = document.getElementById('sZoneName');
|
||||||
const opSelect = document.getElementById('sOperator');
|
const opSelect = document.getElementById('sOperator');
|
||||||
const info = document.getElementById('zoneInfo');
|
const info = document.getElementById('zoneInfo');
|
||||||
|
|
||||||
if(data.found) {
|
if(data.found) {
|
||||||
|
zoneInput.value = data.zone_name;
|
||||||
|
|
||||||
info.innerHTML = `Detectada zona: <b>${data.zone_name}</b>`;
|
info.innerHTML = `Detectada zona: <b>${data.zone_name}</b>`;
|
||||||
info.classList.remove('hidden');
|
info.classList.remove('hidden');
|
||||||
|
|
||||||
opSelect.innerHTML = '<option value="">-- Seleccionar de Zona --</option>';
|
opSelect.innerHTML = '<option value="">-- Seleccionar de Zona --</option>';
|
||||||
data.operators.forEach(op => {
|
data.operators.forEach(op => {
|
||||||
opSelect.innerHTML += `<option value="${op.id}" class="font-bold text-blue-600">⭐ ${op.full_name}</option>`;
|
opSelect.innerHTML += `<option value="${op.id}" class="font-bold text-blue-600">⭐ ${op.full_name}</option>`;
|
||||||
@@ -364,6 +364,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
zoneInput.value = "(Sin zona asignada)";
|
||||||
info.classList.add('hidden');
|
info.classList.add('hidden');
|
||||||
loadOperators(document.getElementById('sGuild').value); // Volver a lógica normal
|
loadOperators(document.getElementById('sGuild').value); // Volver a lógica normal
|
||||||
}
|
}
|
||||||
@@ -684,4 +685,34 @@
|
|||||||
const json = await res.json();
|
const json = await res.json();
|
||||||
|
|
||||||
if (json.ok) {
|
if (json.ok) {
|
||||||
showToast(isEdit ? "✅ Actual
|
showToast(isEdit ? "✅ Actualizado" : "✅ Creado");
|
||||||
|
toggleView('list');
|
||||||
|
} else {
|
||||||
|
showToast("❌ " + (json.error || "Error"), true);
|
||||||
|
}
|
||||||
|
} catch (e) { showToast("Error conexión", true); }
|
||||||
|
finally { btn.disabled = false; btn.innerText = "GUARDAR"; }
|
||||||
|
}
|
||||||
|
|
||||||
|
async function deleteService() {
|
||||||
|
if(!currentServiceId || !confirm("¿Borrar servicio permanentemente?")) return;
|
||||||
|
try {
|
||||||
|
const res = await fetch(`${API_URL}/services/${currentServiceId}`, {
|
||||||
|
method: 'DELETE',
|
||||||
|
headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` }
|
||||||
|
});
|
||||||
|
if(res.ok) { showToast("Eliminado"); closeDetailPanel(); fetchServices(); }
|
||||||
|
} catch(e) { showToast("Error", true); }
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeDetailPanel() { document.getElementById('serviceDetailPanel').classList.add('hidden'); }
|
||||||
|
function showToast(msg, isError = false) {
|
||||||
|
const t = document.getElementById('toast'), m = document.getElementById('toastMsg');
|
||||||
|
t.className = `fixed bottom-5 right-5 px-6 py-3 rounded-lg shadow-2xl transition-all duration-300 z-50 flex items-center gap-3 ${isError ? 'bg-red-600' : 'bg-slate-800'} text-white`;
|
||||||
|
m.innerText = msg; t.classList.remove('translate-y-20', 'opacity-0');
|
||||||
|
setTimeout(() => t.classList.add('translate-y-20', 'opacity-0'), 3000);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<script src="https://maps.googleapis.com/maps/api/js?key=TU_API_KEY_AQUI&libraries=places&callback=initAutocomplete" async defer></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user