From 6a16e5da70b9f7ad6209f7dc0a85a807dde1d487 Mon Sep 17 00:00:00 2001 From: hillaliy Date: Wed, 28 Feb 2024 09:28:58 +0200 Subject: [PATCH 1/7] Add weekly forecast to weather widget --- src/server/api/routers/weather.ts | 2 + src/widgets/weather/WeatherTile.tsx | 128 +++++++++++++++++-------- src/widgets/weather/WeeklyForecast.tsx | 36 +++++++ 3 files changed, 126 insertions(+), 40 deletions(-) create mode 100644 src/widgets/weather/WeeklyForecast.tsx 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..c4a2f49a641 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -12,6 +12,7 @@ import { api } from '~/utils/api'; import { defineWidget } from '../helper'; import { IWidget } from '../widgets'; import { WeatherIcon } from './WeatherIcon'; +import Forecast from './WeeklyForecast'; const definition = defineWidget({ id: 'weather', @@ -25,6 +26,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: { @@ -85,50 +97,86 @@ 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'}> + {getPerferedUnit( + weather.current_weather.temperature, + widget.properties.displayInFahrenheit + )} + + + + + ) : ( + + + + + {getPerferedUnit( + weather.current_weather.temperature, + widget.properties.displayInFahrenheit + )} + + - {width > 200 && ( - - - {getPerferedUnit( - weather.daily.temperature_2m_max[0], - widget.properties.displayInFahrenheit - )} - - {getPerferedUnit( - weather.daily.temperature_2m_min[0], - widget.properties.displayInFahrenheit + {width > 200 && ( + + + {getPerferedUnit( + weather.daily.temperature_2m_max[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} + + )} + )} - + ); } diff --git a/src/widgets/weather/WeeklyForecast.tsx b/src/widgets/weather/WeeklyForecast.tsx new file mode 100644 index 00000000000..6f8f0c5bf85 --- /dev/null +++ b/src/widgets/weather/WeeklyForecast.tsx @@ -0,0 +1,36 @@ +import { Card, Flex, Text } from '@mantine/core'; +import { useElementSize } from '@mantine/hooks'; + +import { WeatherIcon } from './WeatherIcon'; + +const Forecast = ({ daily, getPerferedUnit, widget }) => { + const { width } = useElementSize(); + return ( + + {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( + + + + {time.split('-')[2]} + + + + {getPerferedUnit( + daily.temperature_2m_max[index], + widget.properties.displayInFahrenheit + )} + + + {getPerferedUnit( + daily.temperature_2m_min[index], + widget.properties.displayInFahrenheit + )} + + + + ))} + + ); +}; + +export default Forecast; From 15e60c6284a37658f55cb9b6d275e0d14d70e945 Mon Sep 17 00:00:00 2001 From: hillaliy Date: Sun, 3 Mar 2024 21:22:41 +0200 Subject: [PATCH 2/7] change the styling for height and width to the h and w parameters --- src/widgets/weather/WeatherTile.tsx | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index c4a2f49a641..5fdc33a9bc6 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -68,13 +68,7 @@ function WeatherTile({ widget }: WeatherTileProps) { if (isLoading) { return ( - + @@ -99,13 +93,7 @@ function WeatherTile({ widget }: WeatherTileProps) { return ( <> {widget?.properties.displayWeekly ? ( - + Date: Sun, 3 Mar 2024 22:08:17 +0200 Subject: [PATCH 3/7] Add translate and new disign --- public/locales/en/modules/weather.json | 6 ++++++ src/widgets/weather/WeatherTile.tsx | 18 ++++-------------- src/widgets/weather/WeeklyForecast.tsx | 8 ++++---- 3 files changed, 14 insertions(+), 18 deletions(-) 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/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index 5fdc33a9bc6..2c8babcc854 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 { Center, Flex, Group, Stack, Text, Title } from '@mantine/core'; import { useElementSize } from '@mantine/hooks'; import { IconArrowDownRight, @@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next'; import { api } from '~/utils/api'; import { defineWidget } from '../helper'; +import { WidgetLoading } from '../loading'; import { IWidget } from '../widgets'; import { WeatherIcon } from './WeatherIcon'; import Forecast from './WeeklyForecast'; @@ -67,18 +68,7 @@ function WeatherTile({ widget }: WeatherTileProps) { const { t } = useTranslation('modules/weather'); if (isLoading) { - return ( - - - - - - - - - - - ); + return ; } if (isError) { @@ -93,7 +83,7 @@ function WeatherTile({ widget }: WeatherTileProps) { return ( <> {widget?.properties.displayWeekly ? ( - + { return ( {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( - + - + {time.split('-')[2]} - + {getPerferedUnit( daily.temperature_2m_max[index], widget.properties.displayInFahrenheit )} - + {getPerferedUnit( daily.temperature_2m_min[index], widget.properties.displayInFahrenheit From 92ac100251045f85f7a624f7e1ab1556013671d5 Mon Sep 17 00:00:00 2001 From: hillaliy Date: Mon, 4 Mar 2024 06:35:15 +0200 Subject: [PATCH 4/7] fix space between --- src/widgets/weather/WeatherTile.tsx | 2 +- src/widgets/weather/WeeklyForecast.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index 2c8babcc854..08ba460a70f 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -83,7 +83,7 @@ function WeatherTile({ widget }: WeatherTileProps) { return ( <> {widget?.properties.displayWeekly ? ( - + { const { width } = useElementSize(); return ( - + {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( From 7f82e7755b115fc5d309ae9e492cbf36c7f04182 Mon Sep 17 00:00:00 2001 From: hillaliy Date: Mon, 4 Mar 2024 06:35:15 +0200 Subject: [PATCH 5/7] fix space between --- src/widgets/weather/WeatherTile.tsx | 2 +- src/widgets/weather/WeeklyForecast.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index 2c8babcc854..08ba460a70f 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -83,7 +83,7 @@ function WeatherTile({ widget }: WeatherTileProps) { return ( <> {widget?.properties.displayWeekly ? ( - + { const { width } = useElementSize(); return ( - + {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( From 5686b1f58b1488282d00478f02916fbf54727716 Mon Sep 17 00:00:00 2001 From: hillaliy Date: Wed, 6 Mar 2024 19:38:25 +0200 Subject: [PATCH 6/7] fixed --- src/widgets/weather/WeeklyForecast.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/widgets/weather/WeeklyForecast.tsx b/src/widgets/weather/WeeklyForecast.tsx index d1ac3492355..f3dc76c791f 100644 --- a/src/widgets/weather/WeeklyForecast.tsx +++ b/src/widgets/weather/WeeklyForecast.tsx @@ -6,11 +6,7 @@ import { WeatherIcon } from './WeatherIcon'; const Forecast = ({ daily, getPerferedUnit, widget }) => { const { width } = useElementSize(); return ( -<<<<<<< HEAD -======= - ->>>>>>> 92ac100251045f85f7a624f7e1ab1556013671d5 {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( From 0e2769c58110119611159b5f04fbc40bdbdd8ad8 Mon Sep 17 00:00:00 2001 From: hillaliy Date: Fri, 8 Mar 2024 06:51:19 +0200 Subject: [PATCH 7/7] Combine two files --- src/widgets/weather/WeatherTile.tsx | 74 ++++++++++++++++++-------- src/widgets/weather/WeeklyForecast.tsx | 36 ------------- 2 files changed, 51 insertions(+), 59 deletions(-) delete mode 100644 src/widgets/weather/WeeklyForecast.tsx diff --git a/src/widgets/weather/WeatherTile.tsx b/src/widgets/weather/WeatherTile.tsx index 08ba460a70f..91b8311a958 100644 --- a/src/widgets/weather/WeatherTile.tsx +++ b/src/widgets/weather/WeatherTile.tsx @@ -1,4 +1,4 @@ -import { Center, Flex, Group, 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,13 +7,13 @@ 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'; -import Forecast from './WeeklyForecast'; const definition = defineWidget({ id: 'weather', @@ -79,11 +79,10 @@ function WeatherTile({ widget }: WeatherTileProps) { ); } - // TODO: add widgetWrapper that is generic and uses the definition return ( - <> - {widget?.properties.displayWeekly ? ( - + + {(widget?.properties.displayWeekly && ( + <> 20 ? 'red' : 'blue'}> - {getPerferedUnit( + {getPreferredUnit( weather.current_weather.temperature, widget.properties.displayInFahrenheit )} - - - ) : ( - + + + )) || ( + <> - {getPerferedUnit( + {getPreferredUnit( weather.current_weather.temperature, widget.properties.displayInFahrenheit )} @@ -134,12 +127,12 @@ function WeatherTile({ widget }: WeatherTileProps) { {width > 200 && ( <Group noWrap spacing="xs"> <IconArrowUpRight /> - {getPerferedUnit( + {getPreferredUnit( weather.daily.temperature_2m_max[0], widget.properties.displayInFahrenheit )} <IconArrowDownRight /> - {getPerferedUnit( + {getPreferredUnit( weather.daily.temperature_2m_min[0], widget.properties.displayInFahrenheit )} @@ -152,13 +145,48 @@ function WeatherTile({ widget }: WeatherTileProps) { <Text style={{ whiteSpace: 'nowrap' }}>{widget.properties.location.name}</Text> </Group> )} - </Stack> + </> )} - </> + </Stack> ); } -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 ( + <Flex align="center" direction="row" justify="space-between" w="100%" px="sm"> + {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( + <Card key={index} padding="0.25rem"> + <Flex direction="column" align="center"> + <Text fw={700} lh="1.25rem"> + {time.split('-')[2]} + </Text> + <WeatherIcon size={width < 300 ? 30 : 50} code={daily.weathercode[index]} /> + <Text fz="sm" lh="1rem"> + {getPreferredUnit( + daily.temperature_2m_max[index], + widget.properties.displayInFahrenheit + )} + </Text> + <Text fz="sm" lh="1rem" color="grey"> + {getPreferredUnit( + daily.temperature_2m_min[index], + widget.properties.displayInFahrenheit + )} + </Text> + </Flex> + </Card> + ))} + </Flex> + ); +} + export default definition; diff --git a/src/widgets/weather/WeeklyForecast.tsx b/src/widgets/weather/WeeklyForecast.tsx deleted file mode 100644 index f3dc76c791f..00000000000 --- a/src/widgets/weather/WeeklyForecast.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import { Card, Flex, Text } from '@mantine/core'; -import { useElementSize } from '@mantine/hooks'; - -import { WeatherIcon } from './WeatherIcon'; - -const Forecast = ({ daily, getPerferedUnit, widget }) => { - const { width } = useElementSize(); - return ( - <Flex align="center" direction="row" justify="space-between" w="100%" px="sm"> - {daily.time.slice(0, widget.properties.forecastDays).map((time: any, index: number) => ( - <Card key={index} padding="0.25rem"> - <Flex direction="column" align="center"> - <Text fw={700} lh="1.25rem"> - {time.split('-')[2]} - </Text> - <WeatherIcon size={width < 300 ? 30 : 50} code={daily.weathercode[index]} /> - <Text fz="sm" lh="1rem"> - {getPerferedUnit( - daily.temperature_2m_max[index], - widget.properties.displayInFahrenheit - )} - </Text> - <Text fz="sm" lh="1rem" color="grey"> - {getPerferedUnit( - daily.temperature_2m_min[index], - widget.properties.displayInFahrenheit - )} - </Text> - </Flex> - </Card> - ))} - </Flex> - ); -}; - -export default Forecast;