Updates to weather modal
All checks were successful
Deploy to production / build (push) Successful in 11s
All checks were successful
Deploy to production / build (push) Successful in 11s
This commit is contained in:
@@ -3,52 +3,10 @@ import { useCommonHooks } from 'hooks';
|
|||||||
import { FaCloud, FaLocationArrow, FaSun, FaWind } from 'react-icons/fa';
|
import { FaCloud, FaLocationArrow, FaSun, FaWind } from 'react-icons/fa';
|
||||||
import { WiBarometer, WiHumidity, WiRain, WiSunrise, WiSunset } from 'react-icons/wi';
|
import { WiBarometer, WiHumidity, WiRain, WiSunrise, WiSunset } from 'react-icons/wi';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { MeteoWeather } from 'types';
|
import { type MeteoWeather, WeatherCodes } from 'types';
|
||||||
import WeatherFeaturePill from './WeatherFeaturePill';
|
import WeatherFeaturePill from './WeatherFeaturePill';
|
||||||
import WeatherIcon from './WeatherIcon';
|
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({
|
export default function CurrentWeather({
|
||||||
current,
|
current,
|
||||||
}: {
|
}: {
|
||||||
@@ -321,7 +279,6 @@ export default function CurrentWeather({
|
|||||||
<FaSun
|
<FaSun
|
||||||
style={{
|
style={{
|
||||||
color: 'var(--mantine-color-accent-0)',
|
color: 'var(--mantine-color-accent-0)',
|
||||||
transform: `rotate(${-45 + (current.current.wind_direction_10m || 0)}deg)`,
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Box>
|
</Box>
|
||||||
|
|||||||
@@ -1,52 +1,16 @@
|
|||||||
import { Card, Group, SimpleGrid, Stack, Text } from '@mantine/core';
|
import { Card, Group, SimpleGrid, Stack, Text } from '@mantine/core';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
import { textClasses } from 'styles';
|
import { textClasses } from 'styles';
|
||||||
import type { Daily } from 'types';
|
import { type Daily, WeatherCodes } from 'types';
|
||||||
import WeatherIcon from './WeatherIcon';
|
import WeatherIcon from './WeatherIcon';
|
||||||
|
|
||||||
const WeatherCodes: { [key: number]: string } = {
|
export default function ExtendedForecastCard({
|
||||||
0: 'Clear sky',
|
daily,
|
||||||
|
setSelectedDay,
|
||||||
1: 'Mainly clear',
|
}: {
|
||||||
2: 'Partly cloudy',
|
daily: Daily | undefined;
|
||||||
3: 'Overcast',
|
setSelectedDay: any;
|
||||||
|
}) {
|
||||||
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 }) {
|
|
||||||
const { isMobile, theme } = useCommonHooks();
|
const { isMobile, theme } = useCommonHooks();
|
||||||
const forecast = daily?.time.map((_: any, index: number) => {
|
const forecast = daily?.time.map((_: any, index: number) => {
|
||||||
const time = new Date(daily.time[index]);
|
const time = new Date(daily.time[index]);
|
||||||
@@ -59,8 +23,8 @@ export default function ExtendedForecastCard({ daily }: { daily: Daily | undefin
|
|||||||
precipitationHours: daily.precipitation_hours?.[index],
|
precipitationHours: daily.precipitation_hours?.[index],
|
||||||
precipitationProbability: daily.precipitation_probability_max?.[index],
|
precipitationProbability: daily.precipitation_probability_max?.[index],
|
||||||
precipitationSum: daily.precipitation_sum?.[index],
|
precipitationSum: daily.precipitation_sum?.[index],
|
||||||
sunrise: daily.sunrise[index],
|
sunrise: new Date(daily.sunrise[0] || 0).toLocaleTimeString(),
|
||||||
sunset: daily.sunset[index],
|
sunset: new Date(daily.sunset[0] || 0).toLocaleTimeString(),
|
||||||
sunshineDuration: daily.sunshine_duration?.[index],
|
sunshineDuration: daily.sunshine_duration?.[index],
|
||||||
temperatureMax: daily.temperature_2m_max?.[index],
|
temperatureMax: daily.temperature_2m_max?.[index],
|
||||||
temperatureMin: daily.temperature_2m_min?.[index],
|
temperatureMin: daily.temperature_2m_min?.[index],
|
||||||
@@ -108,6 +72,7 @@ export default function ExtendedForecastCard({ daily }: { daily: Daily | undefin
|
|||||||
style={{
|
style={{
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
}}
|
}}
|
||||||
|
onClick={() => setSelectedDay(item)}
|
||||||
>
|
>
|
||||||
<Group
|
<Group
|
||||||
justify={
|
justify={
|
||||||
|
|||||||
244
src/components/WeatherModal/ExtendedForecastDetails.tsx
Normal file
244
src/components/WeatherModal/ExtendedForecastDetails.tsx
Normal file
@@ -0,0 +1,244 @@
|
|||||||
|
import { Box, Card, Group, Stack, Text } from '@mantine/core';
|
||||||
|
import { FaArrowDown, FaArrowUp, FaLocationArrow, FaSun, FaWind } from 'react-icons/fa';
|
||||||
|
import { WiRain, WiSunrise, WiSunset } from 'react-icons/wi';
|
||||||
|
import { WeatherCodes } from 'types';
|
||||||
|
import WeatherFeaturePill from './WeatherFeaturePill';
|
||||||
|
import WeatherIcon from './WeatherIcon';
|
||||||
|
|
||||||
|
export default function ExtendedForecastDetails({ selectedDay }: { selectedDay: any }) {
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
h={'100%'}
|
||||||
|
w={'100%'}
|
||||||
|
style={{
|
||||||
|
color: 'var(--mantine-color-primary-0)',
|
||||||
|
backgroundColor: 'var(--mantine-color-background-0)',
|
||||||
|
padding: '1rem',
|
||||||
|
borderRadius: '8px',
|
||||||
|
}}
|
||||||
|
onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
shadow='xl'
|
||||||
|
p={0}
|
||||||
|
>
|
||||||
|
<Group
|
||||||
|
w={'100%'}
|
||||||
|
justify='center'
|
||||||
|
bg={'var(--mantine-color-search-0)'}
|
||||||
|
p={0}
|
||||||
|
mt={0}
|
||||||
|
>
|
||||||
|
<Text fz={'1.5rem'}>
|
||||||
|
{selectedDay.time.toLocaleDateString('en-US', { weekday: 'long' })}
|
||||||
|
</Text>
|
||||||
|
<Text fz={'1.5rem'}>{selectedDay.time.toLocaleDateString()}</Text>
|
||||||
|
</Group>
|
||||||
|
<Stack align='center' p={16}>
|
||||||
|
<WeatherIcon size={'xl'} code={selectedDay.weatherCode} />
|
||||||
|
<Text fz={'1rem'} fw={600} mt={'-32px'}>
|
||||||
|
{WeatherCodes[Number(selectedDay.weatherCode)]}
|
||||||
|
</Text>
|
||||||
|
<Group>
|
||||||
|
<Group justify='space-between'>
|
||||||
|
<Stack gap={4}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<FaWind size={16} />
|
||||||
|
<Text>Wind</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={<Text>{selectedDay.windSpeed?.toFixed(0)}mph</Text>}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<FaWind size={16} />
|
||||||
|
<Text>Gusts</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={<Text>{selectedDay.windGusts?.toFixed(0)}mph</Text>}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
<Stack align='center' gap={0}>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
border: '2px solid var(--mantine-color-primary-0)',
|
||||||
|
borderRadius: '100%',
|
||||||
|
aspectRatio: 1,
|
||||||
|
width: 'fit-content',
|
||||||
|
padding: '.75rem',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'var(--mantine-color-background-0)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FaLocationArrow
|
||||||
|
style={{
|
||||||
|
color: 'var(--mantine-color-accent-0)',
|
||||||
|
transform: `rotate(${-48 + (selectedDay.windDirection || 0)}deg)`,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Text fz={12}>{selectedDay.windDirection?.toFixed(0)}°</Text>
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
<Group justify='space-between'>
|
||||||
|
<Stack align='center' justify='center' gap={0}>
|
||||||
|
<Box
|
||||||
|
style={{
|
||||||
|
border: '2px solid var(--mantine-color-primary-0)',
|
||||||
|
borderRadius: '100%',
|
||||||
|
aspectRatio: 1,
|
||||||
|
width: 'fit-content',
|
||||||
|
padding: '.75rem',
|
||||||
|
display: 'flex',
|
||||||
|
backgroundColor: 'var(--mantine-color-background-0)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<FaSun
|
||||||
|
style={{
|
||||||
|
color: 'var(--mantine-color-accent-0)',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Text fz={12}>UV {selectedDay.uvIndexMax?.toFixed(0)}</Text>
|
||||||
|
</Stack>
|
||||||
|
<Stack gap={4}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={0}>
|
||||||
|
<WiSunrise
|
||||||
|
size={18}
|
||||||
|
style={{
|
||||||
|
marginTop: '2px',
|
||||||
|
marginBottom: '2px',
|
||||||
|
marginLeft: -6,
|
||||||
|
marginRight: -6,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={<Text>{selectedDay.sunrise}</Text>}
|
||||||
|
highlight='left'
|
||||||
|
/>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={0}>
|
||||||
|
<WiSunset
|
||||||
|
size={18}
|
||||||
|
style={{
|
||||||
|
marginTop: '2px',
|
||||||
|
marginBottom: '2px',
|
||||||
|
marginLeft: -6,
|
||||||
|
marginRight: -6,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={<Text>{selectedDay.sunset}</Text>}
|
||||||
|
highlight='left'
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<Group w={'100%'} gap={4} justify='space-between'>
|
||||||
|
<Box w={'48%'}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<FaArrowUp size={16} />
|
||||||
|
<Text>High Temp</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={
|
||||||
|
<Text>
|
||||||
|
{selectedDay.temperatureMax.toFixed(0)}°<sup>F</sup>
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box w={'48%'}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<FaArrowDown size={16} />
|
||||||
|
<Text>Low Temp</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={
|
||||||
|
<Text>
|
||||||
|
{selectedDay.temperatureMin.toFixed(0)}°<sup>F</sup>
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
<Group w={'100%'} gap={4} justify='space-between'>
|
||||||
|
<Box w={'48%'}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<FaArrowUp size={16} />
|
||||||
|
<Text>Feels Like High</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={
|
||||||
|
<Text>
|
||||||
|
{selectedDay.apparentTemperatureMax.toFixed(0)}°<sup>F</sup>
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box w={'48%'}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<FaArrowDown size={16} />
|
||||||
|
<Text>Feels Like Temp</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={
|
||||||
|
<Text>
|
||||||
|
{selectedDay.apparentTemperatureMin.toFixed(0)}°<sup>F</sup>
|
||||||
|
</Text>
|
||||||
|
}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
<Group w={'100%'} gap={4} justify='space-between'>
|
||||||
|
<Box w={'48%'}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<WiRain size={16} />
|
||||||
|
<Text>Precipitation %</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={<Text>{selectedDay.precipitationProbability}%</Text>}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
<Box w={'48%'}>
|
||||||
|
<WeatherFeaturePill
|
||||||
|
leftSide={
|
||||||
|
<Group gap={2}>
|
||||||
|
<WiRain size={16} />
|
||||||
|
<Text>Precipitation In.</Text>
|
||||||
|
</Group>
|
||||||
|
}
|
||||||
|
rightSide={<Text>{selectedDay.precipitationSum.toFixed(2)} in.</Text>}
|
||||||
|
highlight='right'
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Group>
|
||||||
|
</Stack>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Stack } from '@mantine/core';
|
import { Group, Select, Stack } from '@mantine/core';
|
||||||
|
import { useState } from 'react';
|
||||||
import {
|
import {
|
||||||
Area,
|
Area,
|
||||||
AreaChart,
|
AreaChart,
|
||||||
@@ -11,16 +12,18 @@ import {
|
|||||||
XAxis,
|
XAxis,
|
||||||
YAxis,
|
YAxis,
|
||||||
} from 'recharts';
|
} from 'recharts';
|
||||||
|
import { selectClasses } from 'styles';
|
||||||
import type { Hourly } from 'types';
|
import type { Hourly } from 'types';
|
||||||
import WeatherTooltip from './WeatherTooltip';
|
import WeatherTooltip from './WeatherTooltip';
|
||||||
|
|
||||||
export default function WeatherGraphs({ hourly }: { hourly: Hourly | undefined }) {
|
export default function WeatherGraphs({ hourly }: { hourly: Hourly | undefined }) {
|
||||||
const colorPrecipitation = 'colorPrecipitation';
|
const colorPrecipitation = 'colorPrecipitation';
|
||||||
const colorHumidity = 'colorHumidity';
|
const colorHumidity = 'colorHumidity';
|
||||||
|
const [timeFrame, setTimeFrame] = useState(24);
|
||||||
const later = new Date();
|
const later = new Date();
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
later.setDate(now.getDate() + 1);
|
|
||||||
|
later.setTime(now.getTime() + timeFrame * 60 * 60 * 1000);
|
||||||
const hourlyForecast = hourly?.time
|
const hourlyForecast = hourly?.time
|
||||||
?.map((_: any, index: number) => {
|
?.map((_: any, index: number) => {
|
||||||
return {
|
return {
|
||||||
@@ -31,6 +34,7 @@ export default function WeatherGraphs({ hourly }: { hourly: Hourly | undefined }
|
|||||||
endTime: hourly.time[index + 1],
|
endTime: hourly.time[index + 1],
|
||||||
probabilityOfPrecipitation: hourly.precipitation_probability?.[index],
|
probabilityOfPrecipitation: hourly.precipitation_probability?.[index],
|
||||||
temperature: hourly.temperature_2m?.[index].toFixed(0),
|
temperature: hourly.temperature_2m?.[index].toFixed(0),
|
||||||
|
apparentTemperature: hourly.apparent_temperature?.[index].toFixed(0),
|
||||||
relativeHumidity: hourly.relative_humidity_2m?.[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)',
|
background: 'var(--mantine-color-search-0)',
|
||||||
padding: '.5rem',
|
padding: '.5rem',
|
||||||
borderRadius: '8px',
|
borderRadius: '8px',
|
||||||
|
position: 'relative',
|
||||||
|
marginTop: '.5rem',
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Group m={0} p={0} mt={'-1.5rem'}>
|
||||||
|
<Select
|
||||||
|
classNames={{
|
||||||
|
input: selectClasses.menuSelectInput,
|
||||||
|
label: selectClasses.menuSelectLabel,
|
||||||
|
options: selectClasses.menuSelectOptions,
|
||||||
|
option: selectClasses.menuSelectOption,
|
||||||
|
dropdown: selectClasses.dropdown,
|
||||||
|
}}
|
||||||
|
className={selectClasses.menuSelect}
|
||||||
|
defaultValue={24}
|
||||||
|
value={timeFrame}
|
||||||
|
data={[
|
||||||
|
{ value: 12, label: '12 hours' },
|
||||||
|
{ value: 24, label: '24 hours' },
|
||||||
|
{ value: 28, label: '2 days' },
|
||||||
|
{ value: 48, label: '3 days' },
|
||||||
|
{ value: 168, label: '7 days' },
|
||||||
|
]}
|
||||||
|
onChange={(value: any) => setTimeFrame(value)}
|
||||||
|
/>
|
||||||
|
</Group>
|
||||||
<ResponsiveContainer width={'100%'} height={150}>
|
<ResponsiveContainer width={'100%'} height={150}>
|
||||||
<ComposedChart data={hourlyForecast}>
|
<ComposedChart data={hourlyForecast}>
|
||||||
<XAxis
|
<XAxis
|
||||||
@@ -81,8 +109,8 @@ export default function WeatherGraphs({ hourly }: { hourly: Hourly | undefined }
|
|||||||
<Line
|
<Line
|
||||||
unit={'°F'}
|
unit={'°F'}
|
||||||
type='monotone'
|
type='monotone'
|
||||||
name='Dew Point'
|
name='Feels Like'
|
||||||
dataKey='dewpoint'
|
dataKey='apparentTemperature'
|
||||||
stroke={'var(--mantine-color-accent-0)'}
|
stroke={'var(--mantine-color-accent-0)'}
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
dot={{
|
dot={{
|
||||||
|
|||||||
@@ -1,9 +1,11 @@
|
|||||||
import { Center, Group, Modal, Stack, Text } from '@mantine/core';
|
import { Group, Modal, Overlay, Stack, Text } from '@mantine/core';
|
||||||
import { useCommonHooks } from 'hooks';
|
import { useCommonHooks } from 'hooks';
|
||||||
|
import { useState } from 'react';
|
||||||
import { modalClasses } from 'styles';
|
import { modalClasses } from 'styles';
|
||||||
import type { MeteoWeather } from 'types';
|
import type { MeteoWeather } from 'types';
|
||||||
import CurrentWeather from './CurrentWeather';
|
import CurrentWeather from './CurrentWeather';
|
||||||
import ExtendedForecastCard from './ExtendedForecastCard';
|
import ExtendedForecastCard from './ExtendedForecastCard';
|
||||||
|
import ExtendedForecastDetails from './ExtendedForecastDetails';
|
||||||
import WeatherGraphs from './WeatherGraphs';
|
import WeatherGraphs from './WeatherGraphs';
|
||||||
|
|
||||||
export function WeatherModal({
|
export function WeatherModal({
|
||||||
@@ -18,7 +20,7 @@ export function WeatherModal({
|
|||||||
closeWeatherModal: () => void;
|
closeWeatherModal: () => void;
|
||||||
}) {
|
}) {
|
||||||
const { isMobile, currentUser } = useCommonHooks();
|
const { isMobile, currentUser } = useCommonHooks();
|
||||||
|
const [selectedDay, setSelectedDay] = useState<any>(undefined);
|
||||||
return (
|
return (
|
||||||
<Modal.Root
|
<Modal.Root
|
||||||
fullScreen={isMobile}
|
fullScreen={isMobile}
|
||||||
@@ -30,6 +32,7 @@ export function WeatherModal({
|
|||||||
onClose={() => {
|
onClose={() => {
|
||||||
handleResetSearch();
|
handleResetSearch();
|
||||||
closeWeatherModal();
|
closeWeatherModal();
|
||||||
|
setSelectedDay(undefined);
|
||||||
}}
|
}}
|
||||||
closeOnEscape
|
closeOnEscape
|
||||||
closeOnClickOutside
|
closeOnClickOutside
|
||||||
@@ -54,13 +57,32 @@ export function WeatherModal({
|
|||||||
<Modal.CloseButton />
|
<Modal.CloseButton />
|
||||||
</Modal.Header>
|
</Modal.Header>
|
||||||
<Modal.Body m={0}>
|
<Modal.Body m={0}>
|
||||||
<Center w={'100%'}>
|
<Stack w={'100%'} h={'100%'} pos={'relative'}>
|
||||||
<Stack w={'100%'}>
|
{selectedDay && (
|
||||||
<CurrentWeather current={current} />
|
<Overlay
|
||||||
<WeatherGraphs hourly={current?.hourly} />
|
h={'100%'}
|
||||||
<ExtendedForecastCard daily={current?.daily} />
|
opacity={1}
|
||||||
</Stack>
|
blur={10}
|
||||||
</Center>
|
onClick={() => setSelectedDay(undefined)}
|
||||||
|
style={{
|
||||||
|
display: 'flex',
|
||||||
|
justifyContent: 'center',
|
||||||
|
alignItems: 'center',
|
||||||
|
backgroundColor: 'color-mix(in srgb, black, transparent 50%)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Stack w={'65%'} align={'center'} justify={'center'}>
|
||||||
|
<ExtendedForecastDetails selectedDay={selectedDay} />
|
||||||
|
</Stack>
|
||||||
|
</Overlay>
|
||||||
|
)}
|
||||||
|
<CurrentWeather current={current} />
|
||||||
|
<WeatherGraphs hourly={current?.hourly} />
|
||||||
|
<ExtendedForecastCard
|
||||||
|
daily={current?.daily}
|
||||||
|
setSelectedDay={setSelectedDay}
|
||||||
|
/>
|
||||||
|
</Stack>
|
||||||
</Modal.Body>
|
</Modal.Body>
|
||||||
</Modal.Content>
|
</Modal.Content>
|
||||||
</Modal.Root>
|
</Modal.Root>
|
||||||
|
|||||||
@@ -16,4 +16,5 @@ export type {
|
|||||||
MeteoWeather,
|
MeteoWeather,
|
||||||
SunState,
|
SunState,
|
||||||
} from './weather';
|
} from './weather';
|
||||||
|
export { WeatherCodes } from './weatherIcon';
|
||||||
export type { WolClient } from './wolClient';
|
export type { WolClient } from './wolClient';
|
||||||
|
|||||||
41
src/types/weatherIcon.ts
Normal file
41
src/types/weatherIcon.ts
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
export 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;
|
||||||
Reference in New Issue
Block a user