From 1645964410da0d30c84a0f4d084ec6743f707c9d Mon Sep 17 00:00:00 2001 From: marsalva Date: Sun, 22 Feb 2026 22:46:29 +0000 Subject: [PATCH] Actualizar menu.html --- menu.html | 86 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 16 deletions(-) diff --git a/menu.html b/menu.html index e9cacd4..a818f4e 100644 --- a/menu.html +++ b/menu.html @@ -58,13 +58,13 @@ - +

Solicitar
Servicios

- +
@@ -91,6 +91,9 @@ ? 'http://localhost:3000' : 'https://integrarepara-api.integrarepara.es'; + let userZones = []; + let userGuilds = []; + // --- SISTEMA DE TEMA DINÁMICO --- async function applyTheme() { try { @@ -122,7 +125,6 @@ // Aplicamos los colores corporativos de la empresa await applyTheme(); - lucide.createIcons(); const rawName = localStorage.getItem("userName") || "Operario"; @@ -131,26 +133,43 @@ const options = { weekday: 'long', day: 'numeric', month: 'long' }; document.getElementById('headerDate').innerText = new Date().toLocaleDateString('es-ES', options); + await fetchUserData(); // Para saber los gremios y zonas del operario fetchBadges(); }); + // 1. Obtener zonas y gremios del operario + async function fetchUserData() { + try { + const res = await fetch(`${API_URL}/auth/me`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); + const data = await res.json(); + if (data.ok && data.user) { + // zones suele venir como array de objetos: [{"cps": "11204"}] + userZones = Array.isArray(data.user.zones) ? data.user.zones.map(z => z.cps) : []; + // Necesitamos cargar los gremios de otra ruta porque auth/me no los trae por defecto + const resG = await fetch(`${API_URL}/admin/users`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); + const dataG = await resG.json(); + if(dataG.ok) { + const myUser = dataG.users.find(u => u.id === data.user.id); + if(myUser) userGuilds = myUser.guilds || []; + } + } + } catch(e) {} + } + async function fetchBadges() { try { - const res = await fetch(`${API_URL}/services/active`, { + // 1. Pedimos los servicios ASIGNADOS AL OPERARIO (para el badge naranja) + const resActive = await fetch(`${API_URL}/services/active`, { headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } }); - const data = await res.json(); + const dataActive = await resActive.json(); - if (data.ok) { - const services = data.services.filter(s => s.provider !== 'SYSTEM_BLOCK'); - + if (dataActive.ok) { + const myServices = dataActive.services.filter(s => s.provider !== 'SYSTEM_BLOCK'); let sinCitaCount = 0; - let conCitaCount = 0; - - services.forEach(s => { + myServices.forEach(s => { const raw = s.raw_data || {}; - if (raw.scheduled_date) conCitaCount++; - else sinCitaCount++; + if (!raw.scheduled_date) sinCitaCount++; }); if (sinCitaCount > 0) { @@ -158,12 +177,47 @@ b1.innerText = `${sinCitaCount} pendiente${sinCitaCount > 1 ? 's' : ''}`; b1.classList.remove('hidden'); } - if (conCitaCount > 0) { - const b2 = document.getElementById('badgeCitas'); - b2.innerText = `${conCitaCount} cita${conCitaCount > 1 ? 's' : ''}`; + } + + // 2. Pedimos la "Bolsa de Trabajo" (servicios sin asignar que cuadran con CP y Gremio) + // Usamos la ruta genérica de scraped pero filtramos en frontend para que sea más rápido. + const resScraped = await fetch(`${API_URL}/providers/scraped`, { + headers: { "Authorization": `Bearer ${localStorage.getItem("token")}` } + }); + const dataScraped = await resScraped.json(); + + if (dataScraped.ok) { + let bolsaCount = 0; + dataScraped.services.forEach(s => { + // Descartamos si ya tiene asignado o si es un bloqueo + if(s.assigned_to || s.provider === 'SYSTEM_BLOCK') return; + + const raw = s.raw_data || {}; + const dbStatus = raw.status_operativo; + + // Si está anulado/finalizado, descartar + if(s.status === 'archived' || (dbStatus && ['anulado', 'terminado', 'finalizado'].includes(dbStatus.toLowerCase()))) return; + + // Check de Gremio y Zona + const sGuild = String(s.guild_id || raw.guild_id); + const sCp = String(raw['Código Postal'] || raw['CP'] || "").trim(); + + const matchGuild = userGuilds.includes(Number(sGuild)) || userGuilds.includes(String(sGuild)); + const matchZone = userZones.some(z => sCp.startsWith(z)); // Coincidencia parcial (ej: zona "11" coge "11204") + + // Si cuadra (o si el operario no tiene filtros estrictos configurados, se lo enseñamos) + if((userGuilds.length === 0 || matchGuild) && (userZones.length === 0 || matchZone)) { + bolsaCount++; + } + }); + + if (bolsaCount > 0) { + const b2 = document.getElementById('badgeBolsa'); + b2.innerText = `${bolsaCount} libre${bolsaCount > 1 ? 's' : ''}`; b2.classList.remove('hidden'); } } + } catch (e) { console.log("Error cargando badges"); } }