diff --git a/frontend/src/components/Map/SargassesMap.jsx b/frontend/src/components/Map/SargassesMap.jsx
index 2065327..a8cc8f3 100644
--- a/frontend/src/components/Map/SargassesMap.jsx
+++ b/frontend/src/components/Map/SargassesMap.jsx
@@ -98,7 +98,7 @@ const makeLayerStyles = (isPrediction, opacity) => ({
});
// ── SVG Markers ───────────────────────────────────────────────────────────
-function SpotMarker({ level, isSelected, name }) {
+function SpotMarker({ level, scoreValue, isSelected, name }) {
const size = isSelected ? 36 : 28;
const shadow = 'filter: drop-shadow(2px 3px 0px rgba(0,0,0,0.35))';
@@ -122,15 +122,18 @@ function SpotMarker({ level, isSelected, name }) {
);
- if (level === 'low') return (
-
-
-
- );
+ if (level === 'low') {
+ const isWatch = (scoreValue ?? 0) >= 15;
+ return (
+
+
+
+ );
+ }
// No score yet
const s = isSelected ? 22 : 14;
@@ -191,7 +194,8 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep,
api.spots.score(s.id)
.then(d => {
const level = d?.score?.level;
- if (level) setSpotScores(prev => ({ ...prev, [s.id]: level }));
+ const value = d?.score?.value ?? 0;
+ if (level) setSpotScores(prev => ({ ...prev, [s.id]: { level, value } }));
})
.catch(() => {});
});
@@ -292,7 +296,9 @@ export default function SargassesMap({ onSpotSelect, selectedSpotId, activeStep,
const coords = getCoords(spot);
if (!coords) return null;
const isSelected = spot.id === selectedSpotId;
- const level = spotScores[spot.id];
+ const sc = spotScores[spot.id];
+ const level = sc?.level;
+ const scoreValue = sc?.value ?? 0;
return (
onSpotSelect(spot)}
>
-
+
);
})}
diff --git a/frontend/src/components/SpotPanel/SpotPanel.css b/frontend/src/components/SpotPanel/SpotPanel.css
index 193dcd7..d8db858 100644
--- a/frontend/src/components/SpotPanel/SpotPanel.css
+++ b/frontend/src/components/SpotPanel/SpotPanel.css
@@ -140,6 +140,7 @@
.eta--now { background: #fee2e2; color: #b91c1c; border-color: #fca5a5; }
.eta--soon { background: #fef9c3; color: #92400e; border-color: #fde68a; }
.eta--later { background: #fff7ed; color: #9a3412; border-color: #fed7aa; }
+.eta--watch { background: #fef3c7; color: #78350f; border-color: #fde68a; }
.eta--safe { background: #dcfce7; color: #15803d; border-color: #86efac; }
.spot-panel__eta-icon { font-size: 20px; line-height: 1; flex-shrink: 0; }
diff --git a/frontend/src/components/SpotPanel/SpotPanel.jsx b/frontend/src/components/SpotPanel/SpotPanel.jsx
index dc2dc54..edc1b91 100644
--- a/frontend/src/components/SpotPanel/SpotPanel.jsx
+++ b/frontend/src/components/SpotPanel/SpotPanel.jsx
@@ -3,7 +3,12 @@ import { api } from '../../api/client';
import usePushSubscription from '../../hooks/usePushSubscription';
import './SpotPanel.css';
-const LEVEL_LABEL = { low: 'OK', medium: 'Risque', high: 'Impact' };
+function scoreLabel(value, level) {
+ if (level === 'high') return 'Impact';
+ if (level === 'medium') return 'Risque';
+ if (value >= 15) return 'Veille';
+ return 'OK';
+}
const TYPE_ICON = { beach: '🏖', port: '⚓', surf: '🏄', fishing: '🎣' };
const TREND_CONFIG = {
@@ -23,13 +28,14 @@ function computeEta(score, horizons) {
return null;
}
-function etaLabel(etaHours) {
- if (etaHours === 0) return { icon: '🚨', label: 'Impact en cours', cls: 'eta--now' };
- if (etaHours === 6) return { icon: '⚠️', label: 'Impact prévu dans ~6h', cls: 'eta--soon' };
- if (etaHours === 12) return { icon: '⚠️', label: 'Impact prévu dans ~12h', cls: 'eta--soon' };
- if (etaHours === 24) return { icon: '🕐', label: 'Impact prévu dans ~24h', cls: 'eta--later' };
- if (etaHours === 48) return { icon: '🕐', label: 'Impact prévu dans ~48h', cls: 'eta--later' };
- return { icon: '✅', label: 'Aucun impact prévu (48h)', cls: 'eta--safe' };
+function etaLabel(etaHours, score) {
+ if (etaHours === 0) return { icon: '🚨', label: 'Impact en cours', cls: 'eta--now' };
+ if (etaHours === 6) return { icon: '⚠️', label: 'Impact prévu dans ~6h', cls: 'eta--soon' };
+ if (etaHours === 12) return { icon: '⚠️', label: 'Impact prévu dans ~12h', cls: 'eta--soon' };
+ if (etaHours === 24) return { icon: '🕐', label: 'Impact prévu dans ~24h', cls: 'eta--later' };
+ if (etaHours === 48) return { icon: '🕐', label: 'Impact prévu dans ~48h', cls: 'eta--later' };
+ if ((score ?? 0) >= 15) return { icon: '👁', label: 'Sargasses en surveillance', cls: 'eta--watch' };
+ return { icon: '✅', label: 'Aucun impact prévu (48h)', cls: 'eta--safe' };
}
const HORIZON_LABELS = { now: 'Maintenant', h6: '+6h', h12: '+12h', h24: '+24h', h48: '+48h' };
@@ -94,7 +100,7 @@ export default function SpotPanel({ spot, activeStep, onClose }) {
: (
<>
{activeStep === 'now' && (() => {
- const eta = etaLabel(computeEta(data?.score, data?.horizons));
+ const eta = etaLabel(computeEta(data?.score, data?.horizons), data?.score?.value);
return (
{eta.icon}
@@ -105,7 +111,7 @@ export default function SpotPanel({ spot, activeStep, onClose }) {
- {LEVEL_LABEL[lvl] ?? lvl}
+ {scoreLabel(displayScore.value, lvl)}
{displayScore.value}
/100