From f16ee3f0eebed85a8cd4edf1dac35ec61dc31526 Mon Sep 17 00:00:00 2001 From: marsalva Date: Wed, 25 Feb 2026 08:12:11 +0000 Subject: [PATCH] =?UTF-8?q?A=C3=B1adir=20js/layout.js?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- js/layout.js | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 js/layout.js diff --git a/js/layout.js b/js/layout.js new file mode 100644 index 0000000..426379d --- /dev/null +++ b/js/layout.js @@ -0,0 +1,45 @@ +// === RASTREADOR FANTASMA GPS (MODO DE CAMINO) === +// Se ejecuta silenciosamente cada 30 segundos +setInterval(async () => { + if (!localStorage.getItem("token") || localStorage.getItem("role") !== "operario") return; + + const TRACK_API = window.location.hostname === 'localhost' || window.location.hostname === '127.0.0.1' + ? 'http://localhost:3000' + : 'https://integrarepara-api.integrarepara.es'; + + try { + // 1. Buscamos el ID del estado "De Camino" + const resSt = await fetch(`${TRACK_API}/statuses`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); + const dataSt = await resSt.json(); + if (!dataSt.ok) return; + + const caminoSt = dataSt.statuses.find(s => s.name.toLowerCase().includes('camino')); + if (!caminoSt) return; + + // 2. Consultamos si tenemos algún servicio activo ahora mismo + const resSvc = await fetch(`${TRACK_API}/services/active`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); + const dataSvc = await resSvc.json(); + if (!dataSvc.ok) return; + + // 3. Filtramos los que están "De Camino" + const enRuta = dataSvc.services.filter(s => String(s.raw_data?.status_operativo) === String(caminoSt.id)); + + if (enRuta.length > 0) { + // 4. Si estamos en ruta, encendemos el GPS y enviamos las coordenadas + navigator.geolocation.getCurrentPosition(async (pos) => { + const lat = pos.coords.latitude; + const lng = pos.coords.longitude; + + for (let s of enRuta) { + await fetch(`${TRACK_API}/services/${s.id}/location`, { + method: 'POST', + headers: { "Content-Type": "application/json", "Authorization": `Bearer ${localStorage.getItem("token")}` }, + body: JSON.stringify({ lat, lng }) + }); + } + }, () => {}, { enableHighAccuracy: true, timeout: 10000 }); // Alta precisión para que el movimiento sea real + } + } catch (e) { + // Falla en silencio para no molestar al operario + } +}, 30000); // 30 segundos \ No newline at end of file