diff --git a/AGENTS.md b/AGENTS.md index 6403cd9..a470d29 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -43,6 +43,7 @@ Repozytorium nie ma obecnie skryptu testów, osobnego skryptu type-check ani for - Route handler prognozy pobiera pełne 7 dni Open-Meteo oraz godzinowe IMGW ALARO. W godzinach pokrytych przez ALARO parametry IMGW mają pierwszeństwo, Open-Meteo dostarcza prawdopodobieństwo opadu i dalszy horyzont, a awaria ALARO pozostawia działający fallback Open-Meteo. Dashboard pokazuje najbliższe 24 przyszłe godziny oraz wykresy pełnego bieżącego dnia, a widok szczegółowy dnia korzysta z pełnego zestawu godzin dla wybranej daty. - `synop.suma_opadu` jest akumulowaną sumą opadu. Nie używaj jej jako sygnału, że pada w tej chwili, ani do sterowania animacją deszczu. - Ostrzeżenia hydro zawierają jawne województwa, a ostrzeżenia meteo kody powiatów TERYT. Normalizuj oba warianty przez `lib/provinces.ts`; nie filtruj ostrzeżeń wyłącznie po opisach tekstowych. +- Listy ostrzeżeń zachowują priorytet lokalnego województwa, a wewnątrz każdej grupy pokazują ostrzeżenia meteorologiczne przed hydrologicznymi. W obrębie rodzaju zachowuj kolejność publikacji od najnowszych. - GPS wymaga świadomej zgody użytkownika i HTTPS. Zaokrąglaj współrzędne przed użyciem i utrzymuj widoczną atrybucję OpenStreetMap dla reverse geocodingu Nominatim. - Normalizuj zewnętrzne odpowiedzi i obsługuj `null`, puste pola oraz błędne wartości. Brak danych pokazuj jawnie zamiast uzupełniać estymacją. - Dla pobierania danych używaj TanStack Query z sensownym `queryKey`, cache i retry. W UI zachowuj loading, error, retry oraz empty states. diff --git a/README.md b/README.md index 1c051f3..db81f5c 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ Wyszukiwarka na stronie głównej obsługuje miejscowości w całej Polsce. Nazw Użytkownik może opcjonalnie udostępnić położenie GPS. Pozycja jest zaokrąglana do trzech miejsc po przecinku, czyli około 100 metrów, a nazwa miejscowości jest ustalana przez Nominatim / OpenStreetMap. Po zgodzie aplikacja wybiera lokalizację, najbliższą stację IMGW i prognozę. Geolocation API wymaga bezpiecznego kontekstu HTTPS. Wyjątkiem jest `localhost`; wejście z iPhone przez lokalny adres typu `http://192.168.x.x:3000` nie uruchomi systemowego pytania Safari. -Widok ostrzeżeń priorytetyzuje komunikaty dla województwa wynikającego z miejscowości lub stacji wybranej w pogodzie. Ostrzeżenia meteorologiczne IMGW przypisuje do regionów na podstawie kodów TERYT, a hydrologiczne na podstawie jawnych pól województwa z API. Pozostałe aktywne komunikaty są wyświetlane niżej. +Widok ostrzeżeń priorytetyzuje komunikaty dla województwa wynikającego z miejscowości lub stacji wybranej w pogodzie. W każdej grupie ostrzeżenia meteorologiczne, np. o burzach lub silnym wietrze, są wyświetlane przed hydrologicznymi. Ostrzeżenia meteorologiczne IMGW przypisuje do regionów na podstawie kodów TERYT, a hydrologiczne na podstawie jawnych pól województwa z API. Pozostałe aktywne komunikaty są wyświetlane niżej. ## Stack diff --git a/lib/imgw-api.ts b/lib/imgw-api.ts index 5cc6233..f6be9d3 100644 --- a/lib/imgw-api.ts +++ b/lib/imgw-api.ts @@ -56,6 +56,11 @@ async function fetchWarningsByKind(kind: WarningKind, signal?: AbortSignal): Pro return Array.isArray(rows) ? rows.map((warning, index) => normalizeWarning(warning, kind, index)) : []; } +function compareWarnings(a: WeatherWarning, b: WeatherWarning) { + if (a.kind !== b.kind) return a.kind === "meteo" ? -1 : 1; + return (b.publishedAt ?? "").localeCompare(a.publishedAt ?? ""); +} + export async function fetchWarnings(signal?: AbortSignal): Promise { const results = await Promise.allSettled([ fetchWarningsByKind("meteo", signal), @@ -65,5 +70,5 @@ export async function fetchWarnings(signal?: AbortSignal): Promise result.status === "rejected")) { throw new Error("Nie udało się pobrać ostrzeżeń IMGW."); } - return warnings.sort((a, b) => (b.publishedAt ?? "").localeCompare(a.publishedAt ?? "")); + return warnings.sort(compareWarnings); }