feat: add interactive daily forecast details
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { Language, TranslationKey } from "@/lib/i18n";
|
||||
import { translate } from "@/lib/i18n";
|
||||
import type { HourlyForecast } from "@/types/forecast";
|
||||
|
||||
export function getForecastConditionKey(code: number | null): TranslationKey {
|
||||
if (code === 0) return "forecast.condition.clear";
|
||||
@@ -26,3 +27,38 @@ export function formatForecastRainfall(value: number | null, language: Language)
|
||||
if (value === null) return "—";
|
||||
return `${new Intl.NumberFormat(language === "pl" ? "pl-PL" : "en-GB", { maximumFractionDigits: 1 }).format(value)} mm`;
|
||||
}
|
||||
|
||||
export function formatForecastWind(value: number | null, language: Language) {
|
||||
if (value === null) return "—";
|
||||
return `${new Intl.NumberFormat(language === "pl" ? "pl-PL" : "en-GB", {
|
||||
minimumFractionDigits: 1,
|
||||
maximumFractionDigits: 1,
|
||||
}).format(value)} m/s`;
|
||||
}
|
||||
|
||||
function getWarsawForecastHour(date = new Date()) {
|
||||
const parts = new Intl.DateTimeFormat("en-CA", {
|
||||
timeZone: "Europe/Warsaw",
|
||||
year: "numeric",
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
hourCycle: "h23",
|
||||
}).formatToParts(date);
|
||||
const getPart = (type: Intl.DateTimeFormatPartTypes) => parts.find((part) => part.type === type)?.value ?? "";
|
||||
|
||||
return `${getPart("year")}-${getPart("month")}-${getPart("day")}T${getPart("hour")}:00`;
|
||||
}
|
||||
|
||||
export function getUpcomingHourlyForecast(hours: HourlyForecast[], limit = 24) {
|
||||
const currentHour = getWarsawForecastHour();
|
||||
return hours.filter((hour) => hour.time >= currentHour).slice(0, limit);
|
||||
}
|
||||
|
||||
export function getHourlyForecastForDay(hours: HourlyForecast[], date: string) {
|
||||
return hours.filter((hour) => hour.time.startsWith(`${date}T`));
|
||||
}
|
||||
|
||||
export function isForecastHourPast(time: string) {
|
||||
return time < getWarsawForecastHour();
|
||||
}
|
||||
|
||||
32
lib/i18n.tsx
32
lib/i18n.tsx
@@ -85,6 +85,22 @@ const translations = {
|
||||
"forecast.hourly": "Najbliższe 24 godziny",
|
||||
"forecast.daily": "Prognoza 7-dniowa",
|
||||
"forecast.today": "Dzisiaj",
|
||||
"forecast.openDayDetails": "Otwórz szczegółową prognozę dla: {day}",
|
||||
"forecast.dayDetails": "Prognoza szczegółowa",
|
||||
"forecast.closeDetails": "Zamknij prognozę szczegółową",
|
||||
"forecast.hourlyForDay": "Przebieg godzinowy",
|
||||
"forecast.temperatureChart": "Temperatura w ciągu dnia",
|
||||
"forecast.temperatureChartDescription": "Temperatura powietrza i temperatura odczuwalna według modelu.",
|
||||
"forecast.rainfallChart": "Opad w ciągu dnia",
|
||||
"forecast.rainfallChartDescription": "Przewidywana suma opadu oraz prawdopodobieństwo opadu.",
|
||||
"forecast.temperature": "Temperatura",
|
||||
"forecast.apparentTemperature": "Odczuwalna",
|
||||
"forecast.precipitation": "Opad",
|
||||
"forecast.precipitationProbability": "Prawdopodobieństwo",
|
||||
"forecast.sunrise": "Wschód słońca",
|
||||
"forecast.sunset": "Zachód słońca",
|
||||
"forecast.maxWind": "Maks. wiatr",
|
||||
"forecast.pastHour": "Miniona godzina",
|
||||
"forecast.source": "Źródło prognozy:",
|
||||
"forecast.error": "Nie udało się pobrać prognozy Open-Meteo.",
|
||||
"forecast.emptyTitle": "Brak prognozy",
|
||||
@@ -227,6 +243,22 @@ const translations = {
|
||||
"forecast.hourly": "Next 24 hours",
|
||||
"forecast.daily": "7-day forecast",
|
||||
"forecast.today": "Today",
|
||||
"forecast.openDayDetails": "Open detailed forecast for: {day}",
|
||||
"forecast.dayDetails": "Detailed forecast",
|
||||
"forecast.closeDetails": "Close detailed forecast",
|
||||
"forecast.hourlyForDay": "Hourly conditions",
|
||||
"forecast.temperatureChart": "Temperature throughout the day",
|
||||
"forecast.temperatureChartDescription": "Air temperature and apparent temperature according to the model.",
|
||||
"forecast.rainfallChart": "Rainfall throughout the day",
|
||||
"forecast.rainfallChartDescription": "Forecast rainfall total and precipitation probability.",
|
||||
"forecast.temperature": "Temperature",
|
||||
"forecast.apparentTemperature": "Feels like",
|
||||
"forecast.precipitation": "Rainfall",
|
||||
"forecast.precipitationProbability": "Probability",
|
||||
"forecast.sunrise": "Sunrise",
|
||||
"forecast.sunset": "Sunset",
|
||||
"forecast.maxWind": "Max. wind",
|
||||
"forecast.pastHour": "Past hour",
|
||||
"forecast.source": "Forecast source:",
|
||||
"forecast.error": "Unable to load the Open-Meteo forecast.",
|
||||
"forecast.emptyTitle": "Forecast unavailable",
|
||||
|
||||
Reference in New Issue
Block a user