feat: add configurable wind units
This commit is contained in:
@@ -15,6 +15,7 @@ import {
|
||||
formatForecastWind,
|
||||
getForecastCondition,
|
||||
} from "@/lib/forecast-utils";
|
||||
import { useWeatherStore } from "@/lib/store";
|
||||
import type { DailyForecast, ForecastSource, HourlyForecast } from "@/types/forecast";
|
||||
|
||||
function formatHour(value: string | null) {
|
||||
@@ -53,6 +54,7 @@ export function DayForecastModal({
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const { language, locale, t } = useI18n();
|
||||
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
|
||||
const closeButtonRef = useRef<HTMLButtonElement>(null);
|
||||
const portalRoot = typeof document === "undefined" ? null : document.body;
|
||||
const maximumWind = useMemo(() => getMaximumWind(hours), [hours]);
|
||||
@@ -135,7 +137,7 @@ export function DayForecastModal({
|
||||
</div>
|
||||
<div className="grid grid-cols-2 gap-2 sm:min-w-[22rem]">
|
||||
<DayMetric icon={Droplets} label={t("forecast.precipitation")} value={formatForecastRainfall(day.precipitation, language)} />
|
||||
<DayMetric icon={Wind} label={t("forecast.maxWind")} value={formatForecastWind(maximumWind, language)} />
|
||||
<DayMetric icon={Wind} label={t("forecast.maxWind")} value={formatForecastWind(maximumWind, language, windSpeedUnit)} />
|
||||
<DayMetric icon={Sunrise} label={t("forecast.sunrise")} value={formatHour(day.sunrise)} />
|
||||
<DayMetric icon={Sunset} label={t("forecast.sunset")} value={formatHour(day.sunset)} />
|
||||
</div>
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
getHourlyForecastForDay,
|
||||
getUpcomingHourlyForecast,
|
||||
} from "@/lib/forecast-utils";
|
||||
import { useWeatherStore } from "@/lib/store";
|
||||
import type { DailyForecast, HourlyForecast } from "@/types/forecast";
|
||||
|
||||
function formatHour(value: string) {
|
||||
@@ -59,6 +60,7 @@ function HourlySummaryMetric({ icon: Icon, label, value }: { icon: LucideIcon; l
|
||||
|
||||
function HourlyForecastSummary({ hours }: { hours: HourlyForecast[] }) {
|
||||
const { language, t } = useI18n();
|
||||
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
|
||||
const minimumTemperature = getMinimum(hours.map((hour) => hour.temperature));
|
||||
const maximumTemperature = getMaximum(hours.map((hour) => hour.temperature));
|
||||
const maximumWind = getMaximum(hours.map((hour) => hour.windSpeed));
|
||||
@@ -73,7 +75,7 @@ function HourlyForecastSummary({ hours }: { hours: HourlyForecast[] }) {
|
||||
<p className="text-[0.68rem] font-semibold uppercase tracking-[0.14em] text-muted">{t("forecast.nextHoursOverview")}</p>
|
||||
<div className="mt-3 grid grid-cols-4 gap-2">
|
||||
<HourlySummaryMetric icon={ThermometerSun} label={t("forecast.temperatureRange")} value={temperatureRange} />
|
||||
<HourlySummaryMetric icon={Wind} label={t("forecast.maxWind")} value={formatForecastWind(maximumWind, language)} />
|
||||
<HourlySummaryMetric icon={Wind} label={t("forecast.maxWind")} value={formatForecastWind(maximumWind, language, windSpeedUnit)} />
|
||||
<HourlySummaryMetric icon={CloudRain} label={t("forecast.rainfallTotal")} value={formatForecastRainfall(rainfallTotal, language)} />
|
||||
<HourlySummaryMetric icon={Droplets} label={t("forecast.maxProbability")} value={maximumRainfallProbability === null ? "—" : `${maximumRainfallProbability}%`} />
|
||||
</div>
|
||||
@@ -113,6 +115,7 @@ function DailyForecastRow({ day, index, onSelect }: { day: DailyForecast; index:
|
||||
|
||||
export function ForecastPanel({ latitude, longitude, locationName }: { latitude?: number; longitude?: number; locationName: string }) {
|
||||
const { language, t } = useI18n();
|
||||
const windSpeedUnit = useWeatherStore((state) => state.windSpeedUnit);
|
||||
const { data: forecast, isPending, isError, refetch } = useForecast(latitude, longitude);
|
||||
const [selectedDay, setSelectedDay] = useState<DailyForecast | null>(null);
|
||||
const closeDayDetails = useCallback(() => setSelectedDay(null), []);
|
||||
@@ -167,7 +170,7 @@ export function ForecastPanel({ latitude, longitude, locationName }: { latitude?
|
||||
</p>
|
||||
<p className="flex items-center justify-center gap-1" title={t("weather.wind")}>
|
||||
<Wind className="size-3 text-accent" />
|
||||
{formatForecastWind(hour.windSpeed, language)}
|
||||
{formatForecastWind(hour.windSpeed, language, windSpeedUnit)}
|
||||
</p>
|
||||
<p className="flex items-center justify-center gap-1" title={t("forecast.precipitation")}>
|
||||
<CloudRain className="size-3 text-accent" />
|
||||
|
||||
Reference in New Issue
Block a user