diff --git a/src/lib/vigilance.ts b/src/lib/vigilance.ts index 0021c87..636264c 100644 --- a/src/lib/vigilance.ts +++ b/src/lib/vigilance.ts @@ -190,6 +190,27 @@ export async function getVigilanceSnapshot(): Promise { } } +/** + * Détermine quelle echeance du bulletin couvre l'instant présent. + * + * Le bulletin Météo France publié à 16h Paris reste valide jusqu'au prochain + * bulletin (~6h Paris le lendemain). Pendant la nuit (de minuit à 6h), on se + * retrouve techniquement dans le J+1 du bulletin, qui correspond pour + * l'utilisateur à "aujourd'hui réel". + * + * Logique : si l'instant présent est avant la fin du J, on utilise J ; sinon J1. + */ +export function currentEcheance(snapshot: VigilanceSnapshot): 'J' | 'J1' { + const now = new Date().toISOString(); + const jEnd = snapshot.alerts + .filter((a) => a.echeance === 'J') + .map((a) => a.endTime) + .sort() + .slice(-1)[0]; + if (jEnd && now < jEnd) return 'J'; + return 'J1'; +} + export function maxColorByDepartement(snapshot: VigilanceSnapshot, echeance: 'J' | 'J1' = 'J'): Map { const map = new Map(); for (const a of snapshot.alerts) { diff --git a/src/pages/departement/[code].astro b/src/pages/departement/[code].astro index bfe2626..ec0c8d0 100644 --- a/src/pages/departement/[code].astro +++ b/src/pages/departement/[code].astro @@ -2,7 +2,7 @@ import Base from '../../layouts/Base.astro'; import VigilanceChip from '../../components/VigilanceChip.astro'; import VigilanceLegend from '../../components/VigilanceLegend.astro'; -import { getVigilanceSnapshot, alertsForDepartement } from '../../lib/vigilance'; +import { getVigilanceSnapshot, alertsForDepartement, currentEcheance } from '../../lib/vigilance'; import { getDepartement, isDrom } from '../../lib/departements'; import { PHENOMENA, COLOR_LABEL } from '../../lib/phenomena'; import { ADVICE, EMERGENCY_NUMBERS } from '../../lib/advice'; @@ -73,10 +73,19 @@ if (!drom) { const stationLabel = hourly ? `${hourly.stationName} (${hourly.distKm} km)` : null; -const today = snapshot ? alertsForDepartement(snapshot, dept.code, 'J') : []; -const tomorrow = snapshot ? alertsForDepartement(snapshot, dept.code, 'J1') : []; +// "Aujourd'hui" = écheance courante (J ou J1 selon l'heure) +// "Demain" = J1 si on est encore sur J, sinon pas dispo (bulletin n'a pas J2) +const ech = snapshot ? currentEcheance(snapshot) : 'J'; +const today = snapshot ? alertsForDepartement(snapshot, dept.code, ech) : []; +const tomorrow = (snapshot && ech === 'J') ? alertsForDepartement(snapshot, dept.code, 'J1') : []; const highest = today[0]; const adviceFor = highest && ADVICE[highest.phenomenonId]; + +const labelDate = (iso: string) => new Date(iso).toLocaleDateString('fr-FR', { + weekday: 'long', day: 'numeric', month: 'long', timeZone: 'Europe/Paris', +}); +const todayLabel = today[0] ? labelDate(today[0].beginTime) : ''; +const tomorrowLabel = tomorrow[0] ? labelDate(tomorrow[0].beginTime) : ''; --- -

Aucune vigilance particulière aujourd'hui.

+

+ Aucune vigilance particulière {todayLabel ? `pour ${todayLabel}` : "aujourd'hui"}. +

Le département est en niveau vert pour tous les phénomènes.

) @@ -126,7 +137,9 @@ const adviceFor = highest && ADVICE[highest.phenomenonId]; { !drom && !error && today.length > 0 && ( <> -

Alertes en cours

+

+ Alertes en cours {todayLabel ? `— ${todayLabel}` : ''} +

    {today.map((a) => { const phen = PHENOMENA[a.phenomenonId]; @@ -162,7 +175,9 @@ const adviceFor = highest && ADVICE[highest.phenomenonId]; { !drom && !error && tomorrow.length > 0 && (
    -

    Prévision pour demain

    +

    + Prévision {tomorrowLabel ? `— ${tomorrowLabel}` : 'pour demain'} +

      {tomorrow.map((a) => (
    • diff --git a/src/pages/index.astro b/src/pages/index.astro index 7f10221..749fb24 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -4,7 +4,7 @@ import FranceMap from '../components/FranceMap.astro'; import DepartementGrid from '../components/DepartementGrid.astro'; import VigilanceLegend from '../components/VigilanceLegend.astro'; import VigilanceChip from '../components/VigilanceChip.astro'; -import { getVigilanceSnapshot, maxColorByDepartement, activeAlerts } from '../lib/vigilance'; +import { getVigilanceSnapshot, maxColorByDepartement, activeAlerts, currentEcheance } from '../lib/vigilance'; import { getDepartement } from '../lib/departements'; import type { VigilanceAlert } from '../lib/vigilance'; @@ -18,14 +18,18 @@ try { error = (e as Error).message; } -const colorsByDept = snapshot ? maxColorByDepartement(snapshot, 'J') : new Map(); -const alertsToday = snapshot ? activeAlerts(snapshot, 2) : []; +// Determine l'écheance "aujourd'hui réel" — peut être J ou J1 selon l'heure +// (entre minuit et la publication du bulletin suivant ~6h, J du bulletin = hier). +const ech = snapshot ? currentEcheance(snapshot) : 'J'; +const colorsByDept = snapshot ? maxColorByDepartement(snapshot, ech) : new Map(); +const alertsToday = snapshot + ? snapshot.alerts.filter((a) => a.echeance === ech && a.colorId >= 2) + : []; -// Group all today's alerts (any level) by department, for tooltip + active alerts list. const alertsByDept = new Map(); if (snapshot) { for (const a of snapshot.alerts) { - if (a.echeance !== 'J') continue; + if (a.echeance !== ech) continue; if (a.colorId < 2) continue; const list = alertsByDept.get(a.departement) ?? []; list.push(a); @@ -53,6 +57,16 @@ const productDate = snapshot?.productDatetime timeZone: 'Europe/Paris', }) : 'inconnu'; + +// Date de validité de l'écheance affichée (pour clarifier au visiteur) +const dayLabel = (() => { + if (!snapshot) return ''; + const sample = snapshot.alerts.find((a) => a.echeance === ech); + if (!sample) return ''; + return new Date(sample.beginTime).toLocaleDateString('fr-FR', { + weekday: 'long', day: 'numeric', month: 'long', timeZone: 'Europe/Paris', + }); +})(); --- @@ -63,7 +77,14 @@ const productDate = snapshot?.productDatetime

      Carte des alertes Vigilance par département, conseils officiels et numéros d'urgence. - Bulletin Météo France du {productDate} (heure de Paris). + {dayLabel && ( + <> + Affichage pour {dayLabel}. + + )} +

      +

      + Bulletin Météo France émis le {productDate} (heure de Paris).