Files
wtr/components/weather/stations-explorer.tsx

46 lines
2.4 KiB
TypeScript

"use client";
import { useMemo, useState } from "react";
import type { SynopStation } from "@/types/imgw";
import { StationGrid } from "@/components/weather/station-grid";
import { StationSearch } from "@/components/weather/station-search";
export type StationSort = "alphabetical" | "temperature-desc" | "temperature-asc" | "humidity-desc" | "pressure-desc";
export type StationFilter = "all" | "warmest" | "coldest" | "windy" | "rainy";
function compareNumbers(a: number | null, b: number | null, direction: "asc" | "desc") {
if (a === null) return 1;
if (b === null) return -1;
return direction === "asc" ? a - b : b - a;
}
export function StationsExplorer({ stations }: { stations: SynopStation[] }) {
const [query, setQuery] = useState("");
const [sort, setSort] = useState<StationSort>("alphabetical");
const [filter, setFilter] = useState<StationFilter>("all");
const visibleStations = useMemo(() => {
const searched = stations.filter((station) => station.name.toLocaleLowerCase("pl").includes(query.trim().toLocaleLowerCase("pl")));
const sorted = [...searched].sort((a, b) => {
if (sort === "temperature-desc") return compareNumbers(a.temperature, b.temperature, "desc");
if (sort === "temperature-asc") return compareNumbers(a.temperature, b.temperature, "asc");
if (sort === "humidity-desc") return compareNumbers(a.humidity, b.humidity, "desc");
if (sort === "pressure-desc") return compareNumbers(a.pressure, b.pressure, "desc");
return a.name.localeCompare(b.name, "pl");
});
if (filter === "all") return sorted;
const key = { warmest: "temperature", coldest: "temperature", windy: "windSpeed", rainy: "rainfall" }[filter] as keyof SynopStation;
return [...sorted].sort((a, b) => compareNumbers(a[key] as number | null, b[key] as number | null, filter === "coldest" ? "asc" : "desc")).slice(0, 12);
}, [filter, query, sort, stations]);
return (
<section className="space-y-4">
<div>
<p className="text-xs font-semibold uppercase tracking-[0.18em] text-sky-700 dark:text-sky-300">Stacje synoptyczne</p>
<h2 className="mt-2 text-2xl font-semibold tracking-tight">Pogoda w Polsce</h2>
</div>
<StationSearch query={query} onQueryChange={setQuery} sort={sort} onSortChange={setSort} filter={filter} onFilterChange={setFilter} />
<StationGrid stations={visibleStations} />
</section>
);
}