From 78d887de9a663adb4b94b6aa40bebb924624b159 Mon Sep 17 00:00:00 2001 From: Sean Edmunds Date: Tue, 14 Jul 2026 16:30:41 -0500 Subject: [PATCH] Updates to weather modal --- .../WeatherModal/CurrentWeather.tsx | 45 +--- .../WeatherModal/ExtendedForecastCard.tsx | 57 +--- .../WeatherModal/ExtendedForecastDetails.tsx | 244 ++++++++++++++++++ src/components/WeatherModal/WeatherGraphs.tsx | 38 ++- src/components/WeatherModal/WeatherModal.tsx | 40 ++- src/types/index.ts | 1 + src/types/weatherIcon.ts | 41 +++ 7 files changed, 362 insertions(+), 104 deletions(-) create mode 100644 src/components/WeatherModal/ExtendedForecastDetails.tsx create mode 100644 src/types/weatherIcon.ts diff --git a/src/components/WeatherModal/CurrentWeather.tsx b/src/components/WeatherModal/CurrentWeather.tsx index 39dd7f9..3058100 100644 --- a/src/components/WeatherModal/CurrentWeather.tsx +++ b/src/components/WeatherModal/CurrentWeather.tsx @@ -3,52 +3,10 @@ import { useCommonHooks } from 'hooks'; import { FaCloud, FaLocationArrow, FaSun, FaWind } from 'react-icons/fa'; import { WiBarometer, WiHumidity, WiRain, WiSunrise, WiSunset } from 'react-icons/wi'; import { textClasses } from 'styles'; -import type { MeteoWeather } from 'types'; +import { type MeteoWeather, WeatherCodes } from 'types'; import WeatherFeaturePill from './WeatherFeaturePill'; import WeatherIcon from './WeatherIcon'; -const WeatherCodes: { [key: number]: string } = { - 0: 'Clear sky', - - 1: 'Mainly clear', - 2: 'Partly cloudy', - 3: 'Overcast', - - 45: 'Fog', - 48: 'Depositing rime fog', - - 51: 'Drizzle: Light', - 53: 'Drizzle: Moderate', - 55: 'Drizzle: Dense', - - 56: 'Freezing Drizzle: Light', - 57: 'Freezing Drizzle: Dense', - - 61: 'Rain: Slight', - 63: 'Rain: Moderate', - 65: 'Rain: Heavy', - - 66: 'Freezing Rain: Light', - 67: 'Freezing Rain: Heavy', - - 71: 'Snowfall: Slight', - 73: 'Snowfall: Moderate', - 75: 'Snowfall: Heavy', - - 77: 'Snow grains', - - 80: 'Rain showers: Slight', - 81: 'Rain showers: Moderate', - 82: 'Rain showers: Violent', - - 85: 'Snow showers: Slight', - 86: 'Snow showers: Heavy', - - 95: 'Thunderstorm: Slight or moderate', - 96: 'Thunderstorm with slight hail', - 99: 'Thunderstorm with heavy hail', -} as const; - export default function CurrentWeather({ current, }: { @@ -321,7 +279,6 @@ export default function CurrentWeather({ diff --git a/src/components/WeatherModal/ExtendedForecastCard.tsx b/src/components/WeatherModal/ExtendedForecastCard.tsx index 3defff5..a9c5234 100644 --- a/src/components/WeatherModal/ExtendedForecastCard.tsx +++ b/src/components/WeatherModal/ExtendedForecastCard.tsx @@ -1,52 +1,16 @@ import { Card, Group, SimpleGrid, Stack, Text } from '@mantine/core'; import { useCommonHooks } from 'hooks'; import { textClasses } from 'styles'; -import type { Daily } from 'types'; +import { type Daily, WeatherCodes } from 'types'; import WeatherIcon from './WeatherIcon'; -const WeatherCodes: { [key: number]: string } = { - 0: 'Clear sky', - - 1: 'Mainly clear', - 2: 'Partly cloudy', - 3: 'Overcast', - - 45: 'Fog', - 48: 'Depositing rime fog', - - 51: 'Drizzle: Light', - 53: 'Drizzle: Moderate', - 55: 'Drizzle: Dense', - - 56: 'Freezing Drizzle: Light', - 57: 'Freezing Drizzle: Dense', - - 61: 'Rain: Slight', - 63: 'Rain: Moderate', - 65: 'Rain: Heavy', - - 66: 'Freezing Rain: Light', - 67: 'Freezing Rain: Heavy', - - 71: 'Snowfall: Slight', - 73: 'Snowfall: Moderate', - 75: 'Snowfall: Heavy', - - 77: 'Snow grains', - - 80: 'Rain showers: Slight', - 81: 'Rain showers: Moderate', - 82: 'Rain showers: Violent', - - 85: 'Snow showers: Slight', - 86: 'Snow showers: Heavy', - - 95: 'Thunderstorm: Slight or moderate', - 96: 'Thunderstorm with slight hail', - 99: 'Thunderstorm with heavy hail', -} as const; - -export default function ExtendedForecastCard({ daily }: { daily: Daily | undefined }) { +export default function ExtendedForecastCard({ + daily, + setSelectedDay, +}: { + daily: Daily | undefined; + setSelectedDay: any; +}) { const { isMobile, theme } = useCommonHooks(); const forecast = daily?.time.map((_: any, index: number) => { const time = new Date(daily.time[index]); @@ -59,8 +23,8 @@ export default function ExtendedForecastCard({ daily }: { daily: Daily | undefin precipitationHours: daily.precipitation_hours?.[index], precipitationProbability: daily.precipitation_probability_max?.[index], precipitationSum: daily.precipitation_sum?.[index], - sunrise: daily.sunrise[index], - sunset: daily.sunset[index], + sunrise: new Date(daily.sunrise[0] || 0).toLocaleTimeString(), + sunset: new Date(daily.sunset[0] || 0).toLocaleTimeString(), sunshineDuration: daily.sunshine_duration?.[index], temperatureMax: daily.temperature_2m_max?.[index], temperatureMin: daily.temperature_2m_min?.[index], @@ -108,6 +72,7 @@ export default function ExtendedForecastCard({ daily }: { daily: Daily | undefin style={{ borderRadius: '8px', }} + onClick={() => setSelectedDay(item)} > { + e.stopPropagation(); + }} + shadow='xl' + p={0} + > + + + {selectedDay.time.toLocaleDateString('en-US', { weekday: 'long' })} + + {selectedDay.time.toLocaleDateString()} + + + + + {WeatherCodes[Number(selectedDay.weatherCode)]} + + + + + + + Wind + + } + rightSide={{selectedDay.windSpeed?.toFixed(0)}mph} + highlight='right' + /> + + + Gusts + + } + rightSide={{selectedDay.windGusts?.toFixed(0)}mph} + highlight='right' + /> + + + + + + {selectedDay.windDirection?.toFixed(0)}° + + + + + + + + UV {selectedDay.uvIndexMax?.toFixed(0)} + + + + + + } + rightSide={{selectedDay.sunrise}} + highlight='left' + /> + + + + } + rightSide={{selectedDay.sunset}} + highlight='left' + /> + + + + + + + + High Temp + + } + rightSide={ + + {selectedDay.temperatureMax.toFixed(0)}°F + + } + highlight='right' + /> + + + + + Low Temp + + } + rightSide={ + + {selectedDay.temperatureMin.toFixed(0)}°F + + } + highlight='right' + /> + + + + + + + Feels Like High + + } + rightSide={ + + {selectedDay.apparentTemperatureMax.toFixed(0)}°F + + } + highlight='right' + /> + + + + + Feels Like Temp + + } + rightSide={ + + {selectedDay.apparentTemperatureMin.toFixed(0)}°F + + } + highlight='right' + /> + + + + + + + Precipitation % + + } + rightSide={{selectedDay.precipitationProbability}%} + highlight='right' + /> + + + + + Precipitation In. + + } + rightSide={{selectedDay.precipitationSum.toFixed(2)} in.} + highlight='right' + /> + + + + + ); +} diff --git a/src/components/WeatherModal/WeatherGraphs.tsx b/src/components/WeatherModal/WeatherGraphs.tsx index 19f0819..215ba1c 100644 --- a/src/components/WeatherModal/WeatherGraphs.tsx +++ b/src/components/WeatherModal/WeatherGraphs.tsx @@ -1,4 +1,5 @@ -import { Stack } from '@mantine/core'; +import { Group, Select, Stack } from '@mantine/core'; +import { useState } from 'react'; import { Area, AreaChart, @@ -11,16 +12,18 @@ import { XAxis, YAxis, } from 'recharts'; +import { selectClasses } from 'styles'; import type { Hourly } from 'types'; import WeatherTooltip from './WeatherTooltip'; export default function WeatherGraphs({ hourly }: { hourly: Hourly | undefined }) { const colorPrecipitation = 'colorPrecipitation'; const colorHumidity = 'colorHumidity'; - + const [timeFrame, setTimeFrame] = useState(24); const later = new Date(); const now = new Date(); - later.setDate(now.getDate() + 1); + + later.setTime(now.getTime() + timeFrame * 60 * 60 * 1000); const hourlyForecast = hourly?.time ?.map((_: any, index: number) => { return { @@ -31,6 +34,7 @@ export default function WeatherGraphs({ hourly }: { hourly: Hourly | undefined } endTime: hourly.time[index + 1], probabilityOfPrecipitation: hourly.precipitation_probability?.[index], temperature: hourly.temperature_2m?.[index].toFixed(0), + apparentTemperature: hourly.apparent_temperature?.[index].toFixed(0), relativeHumidity: hourly.relative_humidity_2m?.[index].toFixed(0), }; }) @@ -42,8 +46,32 @@ export default function WeatherGraphs({ hourly }: { hourly: Hourly | undefined } background: 'var(--mantine-color-search-0)', padding: '.5rem', borderRadius: '8px', + position: 'relative', + marginTop: '.5rem', }} > + +