style: reduce frontend visual effects
This commit is contained in:
@@ -12,7 +12,7 @@ import {
|
||||
formatWind,
|
||||
getWeatherDescription,
|
||||
getWeatherMoodFromData,
|
||||
moodGradient,
|
||||
moodAccentClass,
|
||||
} from "@/lib/weather-utils";
|
||||
import type { SynopStation } from "@/types/imgw";
|
||||
import type { ImgwCurrentWeather } from "@/types/imgw-current";
|
||||
@@ -37,6 +37,7 @@ export function WeatherHero({ station, currentWeather, currentWeatherLoading = f
|
||||
rainfall: currentWeather.precipitation10m ?? station.rainfall,
|
||||
} : station;
|
||||
const mood = getWeatherMoodFromData(displayedStation);
|
||||
const moodAccent = moodAccentClass(mood);
|
||||
const feelsLike = currentWeather?.feelsLike ?? calculateFeelsLike(displayedStation.temperature, displayedStation.humidity, displayedStation.windSpeed);
|
||||
const metrics = [
|
||||
{ icon: Droplets, label: t("weather.humidity"), value: formatHumidity(displayedStation.humidity, language) },
|
||||
@@ -50,13 +51,18 @@ export function WeatherHero({ station, currentWeather, currentWeatherLoading = f
|
||||
initial={{ opacity: 0, y: 18 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.55, ease: "easeOut" }}
|
||||
className={`relative isolate overflow-hidden rounded-panel bg-gradient-to-br ${moodGradient(mood)} px-5 py-6 text-white shadow-card sm:px-8 sm:py-8 lg:px-10`}
|
||||
className="relative isolate overflow-hidden rounded-panel border border-border/70 bg-surface-raised px-5 py-6 shadow-card sm:px-8 sm:py-8 lg:px-10"
|
||||
>
|
||||
<WeatherEffects station={displayedStation} mood={mood} precipitation10m={currentWeather?.precipitation10m} thunderstorm={currentWeather?.condition === "thunderstorm"} />
|
||||
<WeatherEffects precipitation10m={currentWeather?.precipitation10m} thunderstorm={currentWeather?.condition === "thunderstorm"} />
|
||||
<div className="relative z-10">
|
||||
<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">
|
||||
<div className="flex flex-wrap items-center gap-2">
|
||||
<span className="flex items-center gap-1.5 text-sm font-medium text-muted"><MapPin className="size-4" />{displayedLocationName}</span>
|
||||
<span className={`rounded-control border px-2.5 py-1 text-[0.68rem] font-semibold uppercase tracking-[0.14em] ${moodAccent}`}>
|
||||
{getWeatherDescription(displayedStation, language, currentWeather?.condition)}
|
||||
</span>
|
||||
</div>
|
||||
<div className="mt-2 space-y-1 text-xs text-muted">
|
||||
<p>{currentWeatherLoading
|
||||
? t("location.heroHybridLoading", { station: station.name })
|
||||
: hasFullHybridAnalysis
|
||||
@@ -67,7 +73,7 @@ export function WeatherHero({ station, currentWeather, currentWeatherLoading = f
|
||||
? t("location.heroStationFallbackWithDistance", { station: station.name, distance: distanceKm ?? 0 })
|
||||
: t("location.heroStationFallback", { station: station.name })}</p>
|
||||
{hasFullHybridAnalysis && 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>}
|
||||
{hasDistantFallback && <p className="flex items-start gap-1.5 text-warning"><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">
|
||||
@@ -76,20 +82,20 @@ export function WeatherHero({ station, currentWeather, currentWeatherLoading = f
|
||||
{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)}</p>
|
||||
<p className="mt-1 text-sm text-muted">{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" />
|
||||
<WeatherIcon mood={mood} condition={currentWeather?.condition} className="mb-4 size-20 text-accent sm:size-28" />
|
||||
</div>
|
||||
<div className="mt-8 grid grid-cols-2 gap-2.5 sm:mt-10 lg:grid-cols-4">
|
||||
{metrics.map(({ icon: Icon, label, value }) => (
|
||||
<div key={label} className="rounded-card border border-white/20 bg-white/10 p-3.5 backdrop-blur-xl">
|
||||
<div className="flex items-center gap-2 text-xs text-white/70"><Icon className="size-3.5" />{label}</div>
|
||||
<div key={label} className="rounded-card border border-border/60 bg-surface-muted p-3.5">
|
||||
<div className="flex items-center gap-2 text-xs text-muted"><Icon className="size-3.5 text-accent" />{label}</div>
|
||||
<p className="mt-2 text-base font-semibold">{value}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{displayedStation.windDirection !== null && (
|
||||
<p className="mt-4 flex items-center gap-1.5 text-xs text-white/70">
|
||||
<p className="mt-4 flex items-center gap-1.5 text-xs text-muted">
|
||||
<Navigation className="size-3.5" style={{ transform: `rotate(${displayedStation.windDirection}deg)` }} />
|
||||
{t("weather.windDirection")}: {displayedStation.windDirection}°
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user