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(