diff --git a/client/src/components/MapView.jsx b/client/src/components/MapView.jsx index 481c2eb..b1ac461 100644 --- a/client/src/components/MapView.jsx +++ b/client/src/components/MapView.jsx @@ -1,10 +1,22 @@ -import { useEffect, useState, useMemo } from 'react'; +import { useEffect, useState, useMemo, Component } from 'react'; import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet'; import MarkerClusterGroup from 'react-leaflet-cluster'; import L from 'leaflet'; -import 'leaflet/dist/leaflet.css'; import { fetchMapPhotos } from '../api/photos.js'; +class MapErrorBoundary extends Component { + state = { error: null }; + static getDerivedStateFromError(e) { return { error: e }; } + render() { + if (this.state.error) return ( +
+ Map failed to load: {this.state.error.message} +
+ ); + return this.props.children; + } +} + // Custom dot icon — avoids Leaflet's broken default asset URLs in Vite const dotIcon = (color = '#4d9eff') => L.divIcon({ @@ -37,10 +49,14 @@ export default function MapView({ onOpenPhoto }) { .catch(e => setError(e.message)); }, []); + const validPoints = useMemo(() => + (points ?? []).filter(p => Number.isFinite(p.lat) && Number.isFinite(p.lon)), + [points]); + const center = useMemo(() => { - if (!points?.length) return [20, 0]; - return centroid(points); - }, [points]); + if (!validPoints.length) return [20, 0]; + return centroid(validPoints); + }, [validPoints]); if (error) return (

{error}

@@ -50,7 +66,7 @@ export default function MapView({ onOpenPhoto }) {

Loading map…

); - if (points.length === 0) return ( + if (validPoints.length === 0) return (

No geotagged photos.

Photos with GPS metadata will appear here once indexed.

@@ -58,6 +74,7 @@ export default function MapView({ onOpenPhoto }) { ); return ( +
- {points.map(p => ( + {validPoints.map(p => (
@@ -101,5 +118,6 @@ export default function MapView({ onOpenPhoto }) {
+ ); } diff --git a/client/src/main.jsx b/client/src/main.jsx index d9cc93c..3492447 100644 --- a/client/src/main.jsx +++ b/client/src/main.jsx @@ -1,6 +1,7 @@ import { StrictMode } from 'react'; import { createRoot } from 'react-dom/client'; import './index.css'; +import 'leaflet/dist/leaflet.css'; import App from './App.jsx'; createRoot(document.getElementById('root')).render(