import StopDataProvider from "../data/StopDataProvider"; import './map.css'; import { useEffect, useRef, useState } from 'react'; import { useApp } from "../AppContext"; import Map, { AttributionControl, GeolocateControl, Layer, NavigationControl, Popup, Source, type MapRef, type MapLayerMouseEvent, type StyleSpecification } from "react-map-gl/maplibre"; import { loadStyle } from "app/maps/styleloader"; import type { Feature as GeoJsonFeature, Point } from 'geojson'; import LineIcon from "~/components/LineIcon"; import { Link } from "react-router"; // Default minimal fallback style before dynamic loading const defaultStyle: StyleSpecification = { version: 8, glyphs: `${window.location.origin}/maps/fonts/{fontstack}/{range}.pbf`, sprite: `${window.location.origin}/maps/spritesheet/sprite`, sources: {}, layers: [] }; // Componente principal del mapa export default function StopMap() { const [stops, setStops] = useState[]>([]); const [popupInfo, setPopupInfo] = useState(null); const { mapState, updateMapState, theme } = useApp(); const mapRef = useRef(null); const [mapStyleKey, setMapStyleKey] = useState("light"); // Style state for Map component const [mapStyle, setMapStyle] = useState(defaultStyle); // Handle click events on clusters and individual stops const onMapClick = (e: MapLayerMouseEvent) => { const features = e.features; if (!features || features.length === 0) return; const feature = features[0]; const props: any = feature.properties; handlePointClick(feature); }; useEffect(() => { StopDataProvider.getStops().then(data => { const features: GeoJsonFeature[] = data.map(s => ({ type: "Feature", geometry: { type: "Point", coordinates: [s.longitude as number, s.latitude as number] }, properties: { stopId: s.stopId, name: s.name.original, lines: s.lines } })); setStops(features); }); }, []); useEffect(() => { const styleName = "carto"; loadStyle(styleName, theme) .then(style => setMapStyle(style)) .catch(error => console.error("Failed to load map style:", error)); }, [mapStyleKey, theme]); useEffect(() => { const handleMapChange = () => { if (!mapRef.current) return; const map = mapRef.current.getMap(); if (!map) return; const center = map.getCenter(); const zoom = map.getZoom(); updateMapState([center.lat, center.lng], zoom); }; if (mapRef.current) { const map = mapRef.current.getMap(); if (map) { map.on('moveend', handleMapChange); } } return () => { if (mapRef.current) { const map = mapRef.current.getMap(); if (map) { map.off('moveend', handleMapChange); } } }; }, [mapRef.current]); const getLatitude = (center: any) => Array.isArray(center) ? center[0] : center.lat; const getLongitude = (center: any) => Array.isArray(center) ? center[1] : center.lng; const handlePointClick = (feature: any) => { const props: any = feature.properties; // fetch full stop to get lines array StopDataProvider.getStopById(props.stopId).then(stop => { if (!stop) return; setPopupInfo({ geometry: feature.geometry, properties: { stopId: stop.stopId, name: stop.name.original, lines: stop.lines } }); }); }; return ( {popupInfo && ( setPopupInfo(null)} >

{popupInfo.properties.name}

{popupInfo.properties.lines.map((line: string) => ( ))}
Ver parada
)}
); }