feat(map): fetch all schools for map view, add reference pin, cap radius at 5mi
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 45s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m6s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 31s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
All checks were successful
Build and Push Docker Images / Build Backend (FastAPI) (push) Successful in 45s
Build and Push Docker Images / Build Frontend (Next.js) (push) Successful in 1m6s
Build and Push Docker Images / Build Pipeline (Meltano + dbt + Airflow) (push) Successful in 31s
Build and Push Docker Images / Trigger Portainer Update (push) Successful in 1s
- Remove 10-mile radius option; cap backend radius max at 5 miles - Raise backend page_size max to 500 so map can fetch all schools in one call - HomeView: when map view is active, fetch all schools within radius (page_size=500) instead of showing only the paginated first page; falls back to initial SSR schools while loading - SchoolMap/LeafletMapInner: accept referencePoint prop and render a distinctive coral circle pin at the search postcode location Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,12 +23,14 @@ interface LeafletMapInnerProps {
|
||||
schools: School[];
|
||||
center: [number, number];
|
||||
zoom: number;
|
||||
referencePoint?: [number, number];
|
||||
onMarkerClick?: (school: School) => void;
|
||||
}
|
||||
|
||||
export default function LeafletMapInner({ schools, center, zoom, onMarkerClick }: LeafletMapInnerProps) {
|
||||
export default function LeafletMapInner({ schools, center, zoom, referencePoint, onMarkerClick }: LeafletMapInnerProps) {
|
||||
const mapRef = useRef<L.Map | null>(null);
|
||||
const mapContainerRef = useRef<HTMLDivElement>(null);
|
||||
const refMarkerRef = useRef<L.Marker | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
if (!mapContainerRef.current) return;
|
||||
@@ -43,13 +45,36 @@ export default function LeafletMapInner({ schools, center, zoom, onMarkerClick }
|
||||
}).addTo(mapRef.current);
|
||||
}
|
||||
|
||||
// Clear existing markers
|
||||
// Clear existing school markers (not the reference pin)
|
||||
mapRef.current.eachLayer((layer) => {
|
||||
if (layer instanceof L.Marker) {
|
||||
if (layer instanceof L.Marker && layer !== refMarkerRef.current) {
|
||||
mapRef.current!.removeLayer(layer);
|
||||
}
|
||||
});
|
||||
|
||||
// Add reference pin (search location)
|
||||
if (refMarkerRef.current) {
|
||||
refMarkerRef.current.remove();
|
||||
refMarkerRef.current = null;
|
||||
}
|
||||
if (referencePoint && mapRef.current) {
|
||||
const refIcon = L.divIcon({
|
||||
html: `<div style="
|
||||
width: 20px; height: 20px;
|
||||
background: #e07256;
|
||||
border: 3px solid white;
|
||||
border-radius: 50%;
|
||||
box-shadow: 0 2px 8px rgba(0,0,0,0.35);
|
||||
"></div>`,
|
||||
iconSize: [20, 20],
|
||||
iconAnchor: [10, 10],
|
||||
className: '',
|
||||
});
|
||||
refMarkerRef.current = L.marker(referencePoint, { icon: refIcon, zIndexOffset: 1000 })
|
||||
.addTo(mapRef.current)
|
||||
.bindPopup('<strong>Search location</strong>');
|
||||
}
|
||||
|
||||
// Add markers for schools
|
||||
schools.forEach((school) => {
|
||||
if (school.latitude && school.longitude && mapRef.current) {
|
||||
@@ -89,7 +114,7 @@ export default function LeafletMapInner({ schools, center, zoom, onMarkerClick }
|
||||
return () => {
|
||||
// Don't destroy map on every update, just clean markers
|
||||
};
|
||||
}, [schools, center, zoom, onMarkerClick]);
|
||||
}, [schools, center, zoom, referencePoint, onMarkerClick]);
|
||||
|
||||
// Cleanup map on unmount
|
||||
useEffect(() => {
|
||||
|
||||
Reference in New Issue
Block a user