diff --git a/public/locales/en/modules/weather.json b/public/locales/en/modules/weather.json index 9801bb9079d..2568164b646 100644 --- a/public/locales/en/modules/weather.json +++ b/public/locales/en/modules/weather.json @@ -10,6 +10,12 @@ "displayCityName":{ "label":"Display City Name" }, + "displayWeekly":{ + "label": "Display Weekly Forecast" + }, + "forecastDays":{ + "label": "Days To Display" + }, "location": { "label": "Weather location" } diff --git a/src/server/api/routers/weather.ts b/src/server/api/routers/weather.ts index ac83728b3a8..871c33dca4a 100644 --- a/src/server/api/routers/weather.ts +++ b/src/server/api/routers/weather.ts @@ -18,6 +18,8 @@ const weatherSchema = z.object({ temperature: z.number(), }), daily: z.object({ + time: z.array(z.string()), + weathercode: z.array(z.number()), temperature_2m_max: z.array(z.number()), temperature_2m_min: z.array(z.number()), }), diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index 1ace6244729..91b8311a958 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -1,4 +1,4 @@ -import { Center, Flex, Group, Skeleton, Stack, Text, Title } from '@mantine/core'; +import { Card, Center, Flex, Group, Stack, Text, Title } from '@mantine/core'; import { useElementSize } from '@mantine/hooks'; import { IconArrowDownRight, @@ -7,9 +7,11 @@ import { IconMapPin, } from '@tabler/icons-react'; import { useTranslation } from 'react-i18next'; +import { Weather } from '~/server/api/routers/weather'; import { api } from '~/utils/api'; import { defineWidget } from '../helper'; +import { WidgetLoading } from '../loading'; import { IWidget } from '../widgets'; import { WeatherIcon } from './WeatherIcon'; @@ -25,6 +27,17 @@ const definition = defineWidget({ type: 'switch', defaultValue: false, }, + displayWeekly: { + type: 'switch', + defaultValue: false, + }, + forecastDays: { + type: 'slider', + defaultValue: 5, + min: 1, + max: 7, + step: 1, + }, location: { type: 'location', defaultValue: { @@ -55,24 +68,7 @@ function WeatherTile({ widget }: WeatherTileProps) { const { t } = useTranslation('modules/weather'); if (isLoading) { - return ( - - - - - - - - - - - ); + return ; } if (isError) { @@ -83,56 +79,114 @@ function WeatherTile({ widget }: WeatherTileProps) { ); } - // TODO: add widgetWrapper that is generic and uses the definition return ( - - - - - {getPerferedUnit( - weather.current_weather.temperature, - widget.properties.displayInFahrenheit - )} - - + + {(widget?.properties.displayWeekly && ( + <> + + {widget.properties.displayCityName && ( + + + + {widget.properties.location.name} + + + )} + + 20 ? 'red' : 'blue'}> + {getPreferredUnit( + weather.current_weather.temperature, + widget.properties.displayInFahrenheit + )} + + + + + )) || ( + <> + + + + {getPreferredUnit( + weather.current_weather.temperature, + widget.properties.displayInFahrenheit + )} + + - {width > 200 && ( - - - {getPerferedUnit( - weather.daily.temperature_2m_max[0], - widget.properties.displayInFahrenheit + {width > 200 && ( + + + {getPreferredUnit( + weather.daily.temperature_2m_max[0], + widget.properties.displayInFahrenheit + )} + + {getPreferredUnit( + weather.daily.temperature_2m_min[0], + widget.properties.displayInFahrenheit + )} + )} - - {getPerferedUnit( - weather.daily.temperature_2m_min[0], - widget.properties.displayInFahrenheit - )} - - )} - {widget.properties.displayCityName && ( - - - {widget.properties.location.name} - + {widget.properties.displayCityName && ( + + + {widget.properties.location.name} + + )} + )} ); } -const getPerferedUnit = (value: number, isFahrenheit = false): string => +const getPreferredUnit = (value: number, isFahrenheit = false): string => isFahrenheit ? `${(value * (9 / 5) + 32).toFixed(1)}°F` : `${value.toFixed(1)}°C`; +interface ForecastProps { + weather: Weather; + widget: IWeatherWidget; +} + +function Forecast({ weather: { daily }, widget }: ForecastProps) { + const { width } = useElementSize(); + return ( + + {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( + + + + {time.split('-')[2]} + + + + {getPreferredUnit( + daily.temperature_2m_max[index], + widget.properties.displayInFahrenheit + )} + + + {getPreferredUnit( + daily.temperature_2m_min[index], + widget.properties.displayInFahrenheit + )} + + + + ))} + + ); +} + export default definition;