diff --git a/frontend/src/components/Map/SargassesMap.css b/frontend/src/components/Map/SargassesMap.css index 258f246..92049f8 100644 --- a/frontend/src/components/Map/SargassesMap.css +++ b/frontend/src/components/Map/SargassesMap.css @@ -1,3 +1,10 @@ +/* ── Placeholder avant chargement du style ── */ +.smap-placeholder { + width: 100%; + height: 100vh; + background: #3ab5e6; /* couleur océan = pas de flash blanc */ +} + /* ── Logo ── */ .smap-logo { position: absolute; diff --git a/frontend/src/components/Map/SargassesMap.jsx b/frontend/src/components/Map/SargassesMap.jsx index 4593c92..03ad255 100644 --- a/frontend/src/components/Map/SargassesMap.jsx +++ b/frontend/src/components/Map/SargassesMap.jsx @@ -154,7 +154,7 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep, const [spotScores, setSpotScores] = useState({}); const [viewState, setViewState] = useState(INITIAL_VIEW); const [layerOpacity, setLayerOpacity] = useState(1); - const [mapStyle, setMapStyle] = useState(FALLBACK_STYLE); + const [mapStyle, setMapStyle] = useState(null); // null = style not yet ready const [dataDate, setDataDate] = useState(null); const tilesOrigin = window.location.origin; @@ -170,12 +170,17 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep, .catch(() => {}); }, []); - // Load cartoon map style + // Load cartoon map style once — map is only mounted when style is ready, + // preventing the setStyle() race condition that silently drops custom sources. useEffect(() => { - fetch('https://tiles.openfreemap.org/styles/bright') + const ctrl = new AbortController(); + const timeout = setTimeout(() => ctrl.abort(), 4000); // 4 s timeout + fetch('https://tiles.openfreemap.org/styles/bright', { signal: ctrl.signal }) .then(r => r.json()) .then(style => setMapStyle(cartoonizeStyle(style))) - .catch(() => {}); // keep positron on error + .catch(() => setMapStyle(FALLBACK_STYLE)) // positron fallback on error/timeout + .finally(() => clearTimeout(timeout)); + return () => ctrl.abort(); }, []); // Load coastal spots once @@ -221,6 +226,10 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep, const OBS_STYLES = makeLayerStyles(false, layerOpacity); const FORE_STYLES = makeLayerStyles(true, layerOpacity); + if (!mapStyle) { + return
; + } + return (