Files
wtr/components/weather/station-detail-page.tsx

58 lines
3.2 KiB
TypeScript

"use client";
import Link from "next/link";
import { ArrowLeft, Heart, ShieldCheck } from "lucide-react";
import { useWeatherStation } from "@/hooks/use-weather-stations";
import { useWeatherStore } from "@/lib/store";
import { formatDateTime } from "@/lib/weather-utils";
import { cn } from "@/lib/utils";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { WeatherHero } from "@/components/weather/weather-hero";
import { WeatherDetailsGrid } from "@/components/weather/current-conditions-card";
import { SnapshotChart } from "@/components/charts/snapshot-chart";
import { PageLoadingSkeleton } from "@/components/states/loading-skeleton";
import { ErrorState } from "@/components/states/error-state";
import { useI18n } from "@/lib/i18n";
export function StationDetailPage({ id }: { id: string }) {
const { language, t } = useI18n();
const { data: station, isPending, isError, refetch } = useWeatherStation(id);
const favoriteIds = useWeatherStore((state) => state.favorites);
const toggleFavorite = useWeatherStore((state) => state.toggleFavorite);
if (isPending) return <PageLoadingSkeleton />;
if (isError || !station) return <ErrorState onRetry={() => refetch()} description={t("station.error")} />;
const favorite = favoriteIds.includes(station.id);
return (
<div className="space-y-6">
<div className="flex flex-wrap items-center justify-between gap-3">
<Link href="/" className="inline-flex items-center gap-2 rounded-control px-1 py-1 text-sm font-medium text-muted focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-accent"><ArrowLeft className="size-4" />{t("station.all")}</Link>
<Button variant="glass" onClick={() => toggleFavorite(station.id)}>
<Heart className={cn("size-4", favorite && "fill-rose-500 text-rose-500")} />
{favorite ? t("favorites.remove") : t("favorites.add")}
</Button>
</div>
<WeatherHero station={station} />
<section>
<p className="section-kicker">{t("station.label", { name: station.name })}</p>
<h1 className="mt-2 text-2xl font-semibold tracking-tight">{t("station.parameters")}</h1>
<p className="mb-4 mt-1 text-sm leading-6 text-muted">{t("station.parametersDescription")}</p>
<WeatherDetailsGrid station={station} />
</section>
<div className="grid gap-4 lg:grid-cols-[1.3fr_0.7fr]">
<SnapshotChart station={station} />
<Card className="p-5">
<div className="section-kicker flex items-center gap-2"><ShieldCheck className="size-5" /><p>{t("station.quality")}</p></div>
<h2 className="mt-4 text-xl font-semibold tracking-tight">{t("station.lastMeasurementImgw")}</h2>
<p className="mt-2 text-sm leading-6 text-muted">{t("station.qualityDescription")}</p>
<dl className="mt-6 space-y-3 text-sm">
<div><dt className="text-muted">{t("station.lastMeasurement")}</dt><dd className="mt-0.5 font-medium">{formatDateTime(station.measuredAt, language)}</dd></div>
<div><dt className="text-muted">{t("station.source")}</dt><dd className="mt-0.5 font-medium">{t("station.publicApi")}</dd></div>
</dl>
</Card>
</div>
</div>
);
}