diff --git a/src/pages/dashboards/home/blocks/SitesateliteMap.tsx b/src/pages/dashboards/home/blocks/SitesateliteMap.tsx index 584dd70..0d74ed0 100644 --- a/src/pages/dashboards/home/blocks/SitesateliteMap.tsx +++ b/src/pages/dashboards/home/blocks/SitesateliteMap.tsx @@ -1,9 +1,6 @@ import { useEffect, useRef, useState, useMemo } from 'react'; import L from 'leaflet'; import 'leaflet/dist/leaflet.css'; -import 'leaflet.markercluster'; -import 'leaflet.markercluster/dist/MarkerCluster.css'; -import 'leaflet.markercluster/dist/MarkerCluster.Default.css'; import { sitePoints, SitePoint } from '../sitepoints'; // --------------------------------------------------------------------------- @@ -11,9 +8,13 @@ import { sitePoints, SitePoint } from '../sitepoints'; // pin for every Cell/Sector row from the uploaded Excel // (Sites_Coordinates_untuk_CC.xlsm -> "site coordinates 4G"). // +// No clustering — every site is shown as its own blue pin, directly at its +// real coordinates (previously multi-sector sites used a marker cluster +// plugin, which rendered green/yellow/orange group bubbles; that's removed). +// // SETUP REQUIRED: -// npm install leaflet leaflet.markercluster -// npm install --save-dev @types/leaflet @types/leaflet.markercluster +// npm install leaflet +// npm install --save-dev @types/leaflet // --------------------------------------------------------------------------- const DILI_CENTER: [number, number] = [-8.5586, 125.5736]; @@ -30,12 +31,11 @@ const groupByCoordinate = (points: SitePoint[]) => { return map; }; -// Signal-tower badge icon: colored circle background + white "broadcast -// tower" glyph, sized up slightly for pins that represent more than one -// cell/sector at the same coordinates. -const pinIcon = (multi: boolean) => { - const size = multi ? 30 : 26; - const bg = multi ? '#2563eb' : '#ef4444'; +// Signal-tower badge icon: blue circle background + white "broadcast tower" +// glyph. Same size/style for every site pin. +const pinIcon = () => { + const size = 28; + const bg = '#2563eb'; return L.divIcon({ className: '', @@ -65,8 +65,8 @@ const pinIcon = (multi: boolean) => { }; // --------------------------------------------------------------------------- -// "Signal detail" popup (blue pins only) — mimics the tabbed -// Signal / RAN 2G / RAN 3G / Alarm dialog from the reference screenshot. +// "Signal detail" popup — tabbed Signal / RAN 2G / RAN 3G / Alarm dialog, +// shown for every pin. // --------------------------------------------------------------------------- const QUALITY_LEVELS = ['Low', 'Moderate', 'Good', 'Very Good', 'Excellent']; @@ -206,7 +206,6 @@ const wireSignalPopup = (container: HTMLElement, site: string) => { const SitesSatelliteMap = () => { const mapContainerRef = useRef(null); const mapRef = useRef(null); - const clusterRef = useRef(null); const markerByKeyRef = useRef>(new Map()); const [search, setSearch] = useState(''); const [selectedCount, setSelectedCount] = useState(sitePoints.length); @@ -239,39 +238,15 @@ const SitesSatelliteMap = () => { { maxZoom: 19, opacity: 0.9 } ).addTo(map); - const cluster = L.markerClusterGroup({ maxClusterRadius: 50 }); - clusterRef.current = cluster; - + // Every site gets its own blue pin placed directly on the map — no + // clustering, no group bubbles. grouped.forEach((points, key) => { const [lat, lng] = key.split(',').map(Number); - const isMulti = points.length > 1; - const marker = L.marker([lat, lng], { icon: pinIcon(isMulti) }); - - if (isMulti) { - // Blue pin -> rich "Signal" dialog. - marker.bindPopup(buildSignalPopupHtml(points, lat, lng), { maxWidth: 320, minWidth: 290 }); - } else { - // Red pin -> simple cell/sector info (unchanged). - const site = points[0].site; - const location = points[0].location; - const rows = points - .map((p) => `${p.cell}${p.sector}`) - .join(''); - marker.bindPopup(` -
-
${site}
-
${location} · ${lat.toFixed(5)}, ${lng.toFixed(5)}
- ${rows}
-
- `); - } - + const marker = L.marker([lat, lng], { icon: pinIcon() }).addTo(map); + marker.bindPopup(buildSignalPopupHtml(points, lat, lng), { maxWidth: 320, minWidth: 290 }); markerByKeyRef.current.set(key, marker); - cluster.addLayer(marker); }); - map.addLayer(cluster); - // Wire up the rich popup's interactive bits (tabs + buttons) every time // one is opened, since Leaflet re-renders the DOM content on each open. const onPopupOpen = (e: L.PopupEvent) => { @@ -287,7 +262,6 @@ const SitesSatelliteMap = () => { map.off('popupopen', onPopupOpen); map.remove(); mapRef.current = null; - clusterRef.current = null; markerByKeyRef.current.clear(); }; }, [grouped]); @@ -314,9 +288,7 @@ const SitesSatelliteMap = () => { const key = `${first.lat.toFixed(6)},${first.lng.toFixed(6)}`; mapRef.current.setView([first.lat, first.lng], 17); const marker = markerByKeyRef.current.get(key); - if (marker && clusterRef.current) { - clusterRef.current.zoomToShowLayer(marker, () => marker.openPopup()); - } + if (marker) marker.openPopup(); } };