fix: clarify local weather data sources

This commit is contained in:
zv
2026-06-02 16:45:05 +02:00
parent fe73bc23ef
commit 93c9b40931
5 changed files with 39 additions and 17 deletions

View File

@@ -32,14 +32,15 @@ export function DashboardPage() {
const forecastLatitude = hasActiveLocationCoordinates ? activeLocation?.latitude : stationPosition?.latitude;
const forecastLongitude = hasActiveLocationCoordinates ? activeLocation?.longitude : stationPosition?.longitude;
const forecastLocationName = hasActiveLocationCoordinates ? activeLocation?.name ?? selectedStation?.name : selectedStation?.name;
const { data: currentWeather } = useCurrentWeather(forecastLatitude, forecastLongitude);
const { data: currentWeather, isPending: isCurrentWeatherPending } = useCurrentWeather(forecastLatitude, forecastLongitude);
const isCurrentWeatherLoading = Number.isFinite(forecastLatitude) && Number.isFinite(forecastLongitude) && isCurrentWeatherPending;
if (isPending) return <PageLoadingSkeleton />;
if (isError || !stations?.length || !selectedStation) return <ErrorState onRetry={() => refetch()} description={t("dashboard.error")} />;
return (
<div className="space-y-10">
<LocationSearch stations={stations} positions={positions} />
<WeatherHero station={selectedStation} currentWeather={currentWeather} locationName={activeLocation?.name} distanceKm={activeLocation?.distanceKm} />
<WeatherHero station={selectedStation} currentWeather={currentWeather} currentWeatherLoading={isCurrentWeatherLoading} locationName={activeLocation?.name} distanceKm={activeLocation?.distanceKm} />
<ForecastPanel latitude={forecastLatitude} longitude={forecastLongitude} locationName={forecastLocationName ?? selectedStation.name} />
<FavoritesSection stations={stations} />
<FeaturedStationsSection stations={stations} />

View File

@@ -1,7 +1,7 @@
"use client";
import { motion } from "framer-motion";
import { Droplets, Gauge, MapPin, Navigation, Umbrella, Wind } from "lucide-react";
import { AlertTriangle, Droplets, Gauge, MapPin, Navigation, Umbrella, Wind } from "lucide-react";
import {
calculateFeelsLike,
formatDateTime,
@@ -20,8 +20,10 @@ import { WeatherIcon } from "@/components/weather/weather-icon";
import { WeatherEffects } from "@/components/weather/weather-effects";
import { useI18n } from "@/lib/i18n";
export function WeatherHero({ station, currentWeather, locationName, distanceKm }: { station: SynopStation; currentWeather?: ImgwCurrentWeather | null; locationName?: string; distanceKm?: number }) {
export function WeatherHero({ station, currentWeather, currentWeatherLoading = false, locationName, distanceKm }: { station: SynopStation; currentWeather?: ImgwCurrentWeather | null; currentWeatherLoading?: boolean; locationName?: string; distanceKm?: number }) {
const { language, t } = useI18n();
const displayedLocationName = locationName ?? station.name;
const hasDistantFallback = !currentWeather && !currentWeatherLoading && distanceKm !== undefined && distanceKm >= 30;
const displayedStation = currentWeather ? {
...station,
measuredAt: currentWeather.measuredAt,
@@ -52,9 +54,19 @@ export function WeatherHero({ station, currentWeather, locationName, distanceKm
<div className="absolute -right-20 -top-20 size-72 rounded-full bg-white/15 blur-3xl" />
<div className="absolute -bottom-24 -left-16 size-72 rounded-full bg-cyan-200/15 blur-3xl" />
<div className="relative z-10">
<div className="flex flex-wrap items-center gap-3">
<span className="flex items-center gap-1.5 text-sm font-medium text-white/85"><MapPin className="size-4" />{locationName ?? station.name}</span>
{locationName && <span className="text-xs text-white/65">{t("location.heroSource", { station: station.name, distance: distanceKm ?? 0 })}</span>}
<div>
<span className="flex items-center gap-1.5 text-sm font-medium text-white/85"><MapPin className="size-4" />{displayedLocationName}</span>
<div className="mt-1.5 space-y-1 text-xs text-white/65">
<p>{currentWeatherLoading
? t("location.heroHybridLoading", { station: station.name })
: currentWeather
? t("location.heroHybridSource", { location: displayedLocationName })
: locationName
? t("location.heroStationFallbackWithDistance", { station: station.name, distance: distanceKm ?? 0 })
: t("location.heroStationFallback", { station: station.name })}</p>
{currentWeather && locationName && <p>{t("location.heroNearestStation", { station: station.name, distance: distanceKm ?? 0 })}</p>}
{hasDistantFallback && <p className="flex items-start gap-1.5 text-amber-100"><AlertTriangle className="mt-0.5 size-3.5 shrink-0" />{t("location.heroDistantFallback")}</p>}
</div>
</div>
<div className="mt-8 flex items-end justify-between gap-3 sm:mt-10">
<div>
@@ -62,7 +74,7 @@ export function WeatherHero({ station, currentWeather, locationName, distanceKm
{formatTemperature(displayedStation.temperature, language)}
</div>
<p className="mt-5 text-xl font-medium tracking-tight sm:text-2xl">{getWeatherDescription(displayedStation, language, currentWeather?.condition)}</p>
<p className="mt-1 text-sm text-white/75">{t("weather.feelsLike")} {formatTemperature(feelsLike, language)} · {t("weather.measurement")} {formatDateTime(displayedStation.measuredAt, language)}{currentWeather ? ` · ${t("weather.hybridAnalysis")}` : ""}</p>
<p className="mt-1 text-sm text-white/75">{t("weather.feelsLike")} {formatTemperature(feelsLike, language)} · {t("weather.measurement")} {formatDateTime(displayedStation.measuredAt, language)}</p>
</div>
<WeatherIcon mood={mood} condition={currentWeather?.condition} className="mb-4 size-20 text-white/80 sm:size-28" />
</div>