New Weather Modal
1
src/assets/weather/cloudy.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#BBDEFB" d="M29.5 12A8.5 8.5 0 1 0 29.5 29A8.5 8.5 0 1 0 29.5 12Z"/><path fill="#BBDEFB" d="M37 21.893A7 7 0 1 0 37 35.893 7 7 0 1 0 37 21.893zM11 22A7 7 0 1 0 11 36 7 7 0 1 0 11 22z"/><path fill="#BBDEFB" d="M17.5 15A6.5 6.5 0 1 0 17.5 28A6.5 6.5 0 1 0 17.5 15Z"/><path fill="#BBDEFB" d="M25 19.893A7 7 0 1 0 25 33.893A7 7 0 1 0 25 19.893Z"/><path fill="#BBDEFB" d="M7,32c0,2.209,1.791,4,4,4h25c2.209,0,4-1.791,4-4v-1c0-2.209-1.791-4-4-4H11c-2.209,0-4,1.791-4,4V32z"/></svg>
|
||||
|
After Width: | Height: | Size: 570 B |
1
src/assets/weather/haze.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#FF9800" d="M24,6L6,24l1,1h1c1.104,0,2,0.896,2,2c0,0.293-0.066,0.569-0.18,0.82L23,41h2l17-17L24,6z"/><path fill="#FF9800" d="M11 11H37V37H11z"/><path fill="#FFEB3B" d="M13,24c0,6.077,4.923,11,11,11c6.076,0,11-4.923,11-11s-4.924-11-11-11C17.923,13,13,17.923,13,24"/><path fill="#64B5F6" d="M40,37h-9c-1.104,0-2-0.896-2-2s0.896-2,2-2h3c1.104,0,2-0.896,2-2s-0.896-2-2-2h-6h-3h-6c-1.104,0-2-0.896-2-2c0-1.102,0.89-1.994,1.99-1.999H21c1.104,0,2-0.896,2-2V23l0,0c0-1.104-0.896-2-2-2H7v0.001c-1.104,0-2,0.896-2,2s0.896,2,2,2h1C9.1,25.006,9.99,25.898,9.99,27c0,1.104-0.896,2-2,2H8c-1.104,0-2,0.896-2,2s0.896,2,2,2h1c1.104,0,2,0.896,2,2s-0.896,2-2,2s-2,0.896-2,2s0.896,2,2,2h31c0.8,0,1.485-0.473,1.805-1.152h0.001l0.001-0.002c0.057-0.123,0.104-0.25,0.135-0.385c0.002-0.008,0.006-0.016,0.008-0.023C41.98,39.296,42,39.15,42,39C42,37.896,41.104,37,40,37z"/><path fill="#BBDEFB" d="M24,35c4.273,0,7.969-2.44,9.79-6H28h-3h-6c-1.104,0-2-0.896-2-2c0-1.102,0.89-1.994,1.99-1.999H21c1.104,0,2-0.896,2-2V23c0-1.104-0.896-2-2-2h-7.576C13.154,21.955,13,22.959,13,24C13,30.077,17.923,35,24,35z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
1
src/assets/weather/heavy-rain.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#BBDEFB" d="M29.5 5A8.5 8.5 0 1 0 29.5 22A8.5 8.5 0 1 0 29.5 5Z"/><path fill="#BBDEFB" d="M37 14.893A7 7 0 1 0 37 28.893 7 7 0 1 0 37 14.893zM11 15A7 7 0 1 0 11 29 7 7 0 1 0 11 15z"/><path fill="#BBDEFB" d="M17.5 8A6.5 6.5 0 1 0 17.5 21A6.5 6.5 0 1 0 17.5 8Z"/><path fill="#BBDEFB" d="M25 12.893A7 7 0 1 0 25 26.893A7 7 0 1 0 25 12.893Z"/><path fill="#BBDEFB" d="M7,25c0,2.209,1.791,4,4,4h25c2.209,0,4-1.791,4-4v-1c0-2.209-1.791-4-4-4H11c-2.209,0-4,1.791-4,4V25z"/><g><path fill="#2196F3" d="M20 29A1 1 0 1 0 20 31 1 1 0 1 0 20 29zM34 29A1 1 0 1 0 34 31 1 1 0 1 0 34 29zM19 32A1 1 0 1 0 19 34 1 1 0 1 0 19 32zM18 35A1 1 0 1 0 18 37 1 1 0 1 0 18 35zM17 38A1 1 0 1 0 17 40 1 1 0 1 0 17 38zM33 32A1 1 0 1 0 33 34 1 1 0 1 0 33 32zM32 35A1 1 0 1 0 32 37 1 1 0 1 0 32 35zM31 38A1 1 0 1 0 31 40 1 1 0 1 0 31 38zM16 41A1 1 0 1 0 16 43 1 1 0 1 0 16 41zM30 41A1 1 0 1 0 30 43 1 1 0 1 0 30 41zM12 32A1 1 0 1 0 12 34 1 1 0 1 0 12 32zM11 35A1 1 0 1 0 11 37 1 1 0 1 0 11 35zM26 32A1 1 0 1 0 26 34 1 1 0 1 0 26 32zM25 35A1 1 0 1 0 25 37 1 1 0 1 0 25 35zM10 38A1 1 0 1 0 10 40 1 1 0 1 0 10 38zM24 38A1 1 0 1 0 24 40 1 1 0 1 0 24 38zM27 29A1 1 0 1 0 27 31 1 1 0 1 0 27 29zM13 29A1 1 0 1 0 13 31 1 1 0 1 0 13 29z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/weather/partly-cloudy.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#FF9800" d="M8 10.001H25V27.000999999999998H8z"/><path fill="#FF9800" d="M7.661 9.661H25.339V27.339H7.661z" transform="rotate(-45.001 16.5 18.5)"/><path fill="#FFEB3B" d="M10,18.5c0,3.591,2.909,6.5,6.5,6.5s6.5-2.909,6.5-6.5S20.091,12,16.5,12S10,14.909,10,18.5"/><g><path fill="#BBDEFB" d="M29.5 17A8.5 8.5 0 1 0 29.5 34A8.5 8.5 0 1 0 29.5 17Z"/><path fill="#BBDEFB" d="M37 26.893A7 7 0 1 0 37 40.893 7 7 0 1 0 37 26.893zM11 27A7 7 0 1 0 11 41 7 7 0 1 0 11 27z"/><path fill="#BBDEFB" d="M17.5 20A6.5 6.5 0 1 0 17.5 33A6.5 6.5 0 1 0 17.5 20Z"/><path fill="#BBDEFB" d="M25 24.893A7 7 0 1 0 25 38.893A7 7 0 1 0 25 24.893Z"/><path fill="#BBDEFB" d="M7,37c0,2.209,1.791,4,4,4h25c2.209,0,4-1.791,4-4v-1c0-2.209-1.791-4-4-4H11c-2.209,0-4,1.791-4,4V37z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 851 B |
1
src/assets/weather/rain.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#BBDEFB" d="M29.5 5A8.5 8.5 0 1 0 29.5 22A8.5 8.5 0 1 0 29.5 5Z"/><path fill="#BBDEFB" d="M37 14.893A7 7 0 1 0 37 28.893 7 7 0 1 0 37 14.893zM11 15A7 7 0 1 0 11 29 7 7 0 1 0 11 15z"/><path fill="#BBDEFB" d="M17.5 8A6.5 6.5 0 1 0 17.5 21A6.5 6.5 0 1 0 17.5 8Z"/><path fill="#BBDEFB" d="M25 12.893A7 7 0 1 0 25 26.893A7 7 0 1 0 25 12.893Z"/><path fill="#BBDEFB" d="M7,25c0,2.209,1.791,4,4,4h25c2.209,0,4-1.791,4-4v-1c0-2.209-1.791-4-4-4H11c-2.209,0-4,1.791-4,4V25z"/><g><path fill="#2196F3" d="M34.95 37.15c-1.132 1.133-2.968 1.133-4.101 0-1.134-1.131-1.133-2.969 0-4.1C31.982 31.917 37 31 37 31S36.082 36.02 34.95 37.15zM23.95 41.15c-1.132 1.132-2.968 1.132-4.101 0-1.133-1.133-1.132-2.969 0-4.101 1.133-1.133 6.152-2.05 6.152-2.05S25.082 40.02 23.95 41.15zM13.95 37.15c-1.132 1.133-2.968 1.133-4.101 0-1.133-1.131-1.132-2.969 0-4.1 1.132-1.133 6.151-2.05 6.151-2.05S15.082 36.02 13.95 37.15z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 999 B |
1
src/assets/weather/sleet.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#BBDEFB" d="M29.5 5A8.5 8.5 0 1 0 29.5 22A8.5 8.5 0 1 0 29.5 5Z"/><path fill="#BBDEFB" d="M37 14.893A7 7 0 1 0 37 28.893 7 7 0 1 0 37 14.893zM11 15A7 7 0 1 0 11 29 7 7 0 1 0 11 15z"/><path fill="#BBDEFB" d="M17.5 8A6.5 6.5 0 1 0 17.5 21A6.5 6.5 0 1 0 17.5 8Z"/><path fill="#BBDEFB" d="M25 12.893A7 7 0 1 0 25 26.893A7 7 0 1 0 25 12.893Z"/><path fill="#BBDEFB" d="M7,25c0,2.209,1.791,4,4,4h25c2.209,0,4-1.791,4-4v-1c0-2.209-1.791-4-4-4H11c-2.209,0-4,1.791-4,4V25z"/><g><path fill="#2196F3" d="M35.95 37.15c-1.132 1.133-2.968 1.133-4.101 0-1.134-1.131-1.133-2.969 0-4.1C32.982 31.917 38 31 38 31S37.082 36.02 35.95 37.15zM14.95 37.15c-1.132 1.133-2.968 1.133-4.101 0-1.133-1.131-1.132-2.969 0-4.1 1.132-1.133 6.151-2.05 6.151-2.05S16.082 36.02 14.95 37.15zM23 34H25V43H23z"/><path fill="#2196F3" d="M23 33.999H25V42.999H23z" transform="rotate(120.471 24 38.499)"/><path fill="#2196F3" d="M23.001 34H24.999000000000002V43H23.001z" transform="rotate(60.679 24 38.5)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
1
src/assets/weather/snow.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#BBDEFB" d="M29.5 5A8.5 8.5 0 1 0 29.5 22A8.5 8.5 0 1 0 29.5 5Z"/><path fill="#BBDEFB" d="M37 14.893A7 7 0 1 0 37 28.893 7 7 0 1 0 37 14.893zM11 15A7 7 0 1 0 11 29 7 7 0 1 0 11 15z"/><path fill="#BBDEFB" d="M17.5 8A6.5 6.5 0 1 0 17.5 21A6.5 6.5 0 1 0 17.5 8Z"/><path fill="#BBDEFB" d="M25 12.893A7 7 0 1 0 25 26.893A7 7 0 1 0 25 12.893Z"/><path fill="#BBDEFB" d="M7,25c0,2.209,1.791,4,4,4h25c2.209,0,4-1.791,4-4v-1c0-2.209-1.791-4-4-4H11c-2.209,0-4,1.791-4,4V25z"/><g><path fill="#2196F3" d="M23 34H25V43H23z"/><path fill="#2196F3" d="M23 33.999H25V42.999H23z" transform="rotate(120.471 24 38.499)"/><path fill="#2196F3" d="M23.001 34H24.999000000000002V43H23.001z" transform="rotate(60.679 24 38.5)"/><path fill="#2196F3" d="M10 31H12V40H10z"/><path fill="#2196F3" d="M10 30.999H12V39.998999999999995H10z" transform="rotate(120.444 11 35.5)"/><path fill="#2196F3" d="M10.001 31H11.998999999999999V40H10.001z" transform="rotate(60.679 11 35.5)"/><path fill="#2196F3" d="M36 31H38V40H36z"/><path fill="#2196F3" d="M35.999 30.998H37.999V39.998000000000005H35.999z" transform="rotate(120.458 36.999 35.5)"/><path fill="#2196F3" d="M36 31H37.998V40.001H36z" transform="rotate(60.679 36.999 35.5)"/></g></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
1
src/assets/weather/sunny.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#FF9800" d="M38,38c0,0-9-3-14-3s-14,3-14,3s3-10,3-14s-3-14-3-14s9,3,14,3s14-3,14-3s-3,10-3,14S38,38,38,38z"/><path fill="#FF9800" d="M43,24c0,0-8.222,4.778-11.222,7.778S24,43,24,43s-4.278-7.722-7.778-11.222S5,24,5,24s8.221-4.777,11.222-7.777S24,5,24,5s4.779,8.223,7.778,11.223S43,24,43,24z"/><path fill="#FFEB3B" d="M14,24c0,5.524,4.477,10,10,10s10-4.476,10-10s-4.477-10-10-10S14,18.476,14,24"/></svg>
|
||||
|
After Width: | Height: | Size: 496 B |
1
src/assets/weather/thunderstorm.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 0 48 48"><path fill="#BBDEFB" d="M18.5 4A8.5 8.5 0 1 0 18.5 21A8.5 8.5 0 1 0 18.5 4Z"/><path fill="#BBDEFB" d="M19 20A7 7 0 1 0 19 34A7 7 0 1 0 19 20Z"/><path fill="#BBDEFB" d="M11 14A7 7 0 1 0 11 28 7 7 0 1 0 11 14zM38 14A6 6 0 1 0 38 26 6 6 0 1 0 38 14z"/><path fill="#BBDEFB" d="M30 19A6 6 0 1 0 30 31A6 6 0 1 0 30 19Z"/><path fill="#BBDEFB" d="M30.5 7A6.5 6.5 0 1 0 30.5 20A6.5 6.5 0 1 0 30.5 7Z"/><path fill="#BBDEFB" d="M23 12A7 7 0 1 0 23 26A7 7 0 1 0 23 12Z"/><g><path fill="#D500F9" d="M22 44l2-7h-3l4-8h4l-3.594 6H29L22 44zM32.594 39l2-7h-3l4-8h4L36 30h3.594L32.594 39z"/></g></svg>
|
||||
|
After Width: | Height: | Size: 666 B |
1
src/assets/weather/windy.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48"><path fill="#bbdefb" d="M38,15.5c0,4.7-3.8,8.5-8.5,8.5S21,20.2,21,15.5S24.8,7,29.5,7S38,10.8,38,15.5z"/><path fill="#bbdefb" d="M44 23.9c0 3.9-3.1 7-7 7s-7-3.1-7-7c0-3.9 3.1-7 7-7S44 20 44 23.9zM18 24c0 3.9-3.1 7-7 7s-7-3.1-7-7 3.1-7 7-7S18 20.1 18 24z"/><path fill="#bbdefb" d="M24,16.5c0,3.6-2.9,6.5-6.5,6.5S11,20.1,11,16.5s2.9-6.5,6.5-6.5S24,12.9,24,16.5z"/><path fill="#bbdefb" d="M32,21.9c0,3.9-3.1,7-7,7s-7-3.1-7-7c0-3.9,3.1-7,7-7S32,18,32,21.9z"/><path fill="#bbdefb" d="M7,27c0,2.2,1.8,4,4,4h25c2.2,0,4-1.8,4-4v-1c0-2.2-1.8-4-4-4H11c-2.2,0-4,1.8-4,4V27z"/><path fill="#2196f3" d="M31.9 41c-2.5 0-4.6-1.5-5.5-3.9-.2-.5.1-1.1.6-1.3.5-.2 1.1.1 1.3.6.6 1.7 2 2.7 3.7 2.6 2.3-.1 4-1.8 4-4 0-2.2-1.8-4-4-4H12c-.6 0-1-.4-1-1s.4-1 1-1h20c3.3 0 6 2.7 6 6 0 3.2-2.6 5.9-6 6C32 41 31.9 41 31.9 41zM25 27H14c-.6 0-1-.4-1-1s.4-1 1-1h11c1.6 0 3-1.4 3-3s-1.4-3-3-3c-1.2 0-2.3.8-2.8 1.9-.2.5-.8.8-1.3.6-.5-.2-.8-.8-.6-1.3.8-1.9 2.6-3.2 4.7-3.2 2.8 0 5 2.2 5 5S27.8 27 25 27z"/><path fill="#2196f3" d="M18,41c-1.5,0-2.9-0.8-3.5-2.2c-0.2-0.5,0-1.1,0.4-1.3c0.5-0.2,1.1,0,1.3,0.4c0.3,0.6,1,1,1.7,1 c1.1,0,2-0.9,2-2s-0.9-2-2-2h-8c-0.6,0-1-0.4-1-1s0.4-1,1-1h8c2.2,0,4,1.8,4,4S20.2,41,18,41z"/></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
145
src/components/WeatherModal/CurrentWeather.tsx
Normal file
@@ -0,0 +1,145 @@
|
||||
import { Grid, Group, Stack, Text, ThemeIcon } from '@mantine/core';
|
||||
import { FaLongArrowAltDown, FaLongArrowAltUp, FaWind } from 'react-icons/fa';
|
||||
import { WiBarometer, WiHumidity } from 'react-icons/wi';
|
||||
import WeatherIcon from './WeatherIcon';
|
||||
|
||||
export default function CurrentWeather({ weather }: any) {
|
||||
return (
|
||||
<Stack
|
||||
gap={0}
|
||||
w={'100%'}
|
||||
justify='space-between'
|
||||
style={{
|
||||
backgroundColor: 'var(--color-search-background)',
|
||||
padding: '1rem',
|
||||
borderRadius: '8px',
|
||||
paddingBottom: '.5rem',
|
||||
}}
|
||||
>
|
||||
<Group gap={0} px={16} w={'100%'}>
|
||||
<Text
|
||||
c={'var(--color-text-pri)'}
|
||||
style={{
|
||||
fontSize: '1.375rem',
|
||||
textAlign: 'left',
|
||||
}}
|
||||
>
|
||||
Current Weather
|
||||
</Text>
|
||||
</Group>
|
||||
<Group gap={0} w={'100%'}>
|
||||
<Stack gap={0} w={'50%'}>
|
||||
<Group gap={0}>
|
||||
<WeatherIcon textDescription={`${weather.textDescription}`} />
|
||||
<Text fz={'7rem'} fw={200}>
|
||||
{weather.temperature}°<sup style={{ fontSize: '3rem' }}>F</sup>
|
||||
</Text>
|
||||
</Group>
|
||||
<Text
|
||||
c={'var(--color-text-pri)'}
|
||||
style={{
|
||||
fontSize: '1.375rem',
|
||||
textAlign: 'left',
|
||||
marginTop: -32,
|
||||
marginLeft: 16,
|
||||
}}
|
||||
>
|
||||
{weather.textDescription}
|
||||
</Text>
|
||||
</Stack>
|
||||
<Stack gap={4} w={'50%'}>
|
||||
<Text>
|
||||
Feels like {weather.heatIndex ?? weather.windChill ?? weather.temperature}°
|
||||
<sup>F</sup>
|
||||
</Text>
|
||||
<Grid align='center' w={'100%'}>
|
||||
<Grid.Col span={2}>
|
||||
<ThemeIcon
|
||||
h={'auto'}
|
||||
w={'auto'}
|
||||
variant='subtle'
|
||||
c={'var(--color-text-pri)'}
|
||||
>
|
||||
<FaLongArrowAltUp size={32} />
|
||||
</ThemeIcon>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>
|
||||
<Text>
|
||||
{weather.highTemp}°<sup>F</sup>
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<ThemeIcon
|
||||
h={'auto'}
|
||||
w={'auto'}
|
||||
variant='subtle'
|
||||
c={'var(--color-text-pri)'}
|
||||
>
|
||||
<FaLongArrowAltDown size={32} />
|
||||
</ThemeIcon>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={1}>
|
||||
<Text>
|
||||
{weather.lowTemp}°<sup>F</sup>
|
||||
</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid align='center'>
|
||||
<Grid.Col span={2}>
|
||||
<ThemeIcon
|
||||
h={'auto'}
|
||||
w={'auto'}
|
||||
variant='subtle'
|
||||
c={'var(--color-text-pri)'}
|
||||
>
|
||||
<WiHumidity size={32} />
|
||||
</ThemeIcon>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Text>Humidity</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Text>{weather.humidity}%</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid align='center'>
|
||||
<Grid.Col span={2}>
|
||||
<ThemeIcon
|
||||
h={'auto'}
|
||||
w={'auto'}
|
||||
variant='subtle'
|
||||
c={'var(--color-text-pri)'}
|
||||
>
|
||||
<FaWind size={32} />
|
||||
</ThemeIcon>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Text>Wind</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Text>{weather.windSpeed}mph</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
<Grid align='center'>
|
||||
<Grid.Col span={2}>
|
||||
<ThemeIcon
|
||||
h={'auto'}
|
||||
w={'auto'}
|
||||
variant='subtle'
|
||||
c={'var(--color-text-pri)'}
|
||||
>
|
||||
<WiBarometer size={32} />
|
||||
</ThemeIcon>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Text>Pressure</Text>
|
||||
</Grid.Col>
|
||||
<Grid.Col span={2}>
|
||||
<Text>{weather.pressure} in</Text>
|
||||
</Grid.Col>
|
||||
</Grid>
|
||||
</Stack>
|
||||
</Group>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
52
src/components/WeatherModal/ExtendedForecast.tsx
Normal file
@@ -0,0 +1,52 @@
|
||||
import { Group, Stack, Text } from '@mantine/core';
|
||||
import WeatherIcon from './WeatherIcon';
|
||||
|
||||
export default function ExtendedForecast({ forecast }: any) {
|
||||
const day = forecast.slice(2, 14).filter((item: any) => item.isDaytime);
|
||||
const night = forecast.slice(2, 14).filter((item: any) => !item.isDaytime);
|
||||
return (
|
||||
<Stack
|
||||
gap={0}
|
||||
w={'100%'}
|
||||
justify='space-between'
|
||||
style={{
|
||||
backgroundColor: 'var(--color-search-background)',
|
||||
padding: '1rem',
|
||||
borderRadius: '8px',
|
||||
paddingBottom: '.5rem',
|
||||
}}
|
||||
>
|
||||
<Group gap={0} px={16} w={'100%'}>
|
||||
<Text
|
||||
c={'var(--color-text-pri)'}
|
||||
style={{
|
||||
fontSize: '1.375rem',
|
||||
textAlign: 'left',
|
||||
}}
|
||||
>
|
||||
Extended Forecast
|
||||
</Text>
|
||||
</Group>
|
||||
<Group w={'100%'} align='center' justify='space-between'>
|
||||
{day.map((item: any, index: number) => {
|
||||
const short = item.shortForecast.includes('And')
|
||||
? item.shortForecast.substring(0, item.shortForecast.indexOf('And'))
|
||||
: item.shortForecast.includes('then')
|
||||
? item.shortForecast.substring(0, item.shortForecast.indexOf('then'))
|
||||
: item.shortForecast;
|
||||
return (
|
||||
<Stack key={item.name} gap={0} align='center'>
|
||||
<Text>{item.name}</Text>
|
||||
<WeatherIcon textDescription={short} />
|
||||
<Text>{short}</Text>
|
||||
<Text>
|
||||
{item.temperature}°{item.temperatureUnit}/{night[index].temperature}°
|
||||
{item.temperatureUnit}
|
||||
</Text>
|
||||
</Stack>
|
||||
);
|
||||
})}
|
||||
</Group>
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
@@ -94,7 +94,7 @@ export default function HourlyCard({ weather }: any) {
|
||||
color: 'white',
|
||||
}}
|
||||
>
|
||||
{weather.temperature}°{weather.temperatureUnit}/{weather.relativeHumidity.value}%
|
||||
{weather.temperature}°{weather.temperatureUnit}/{weather.relativeHumidity?.value}%
|
||||
</Text>
|
||||
<Box
|
||||
mt={4}
|
||||
@@ -114,7 +114,7 @@ export default function HourlyCard({ weather }: any) {
|
||||
transform: `rotate(${WindDirection[weather.windDirection]}deg)`,
|
||||
}}
|
||||
/>
|
||||
{`${weather.probabilityOfPrecipitation.value}`}%
|
||||
{`${weather.probabilityOfPrecipitation?.value}`}%
|
||||
</Group>
|
||||
</Box>
|
||||
</Stack>
|
||||
|
||||
251
src/components/WeatherModal/WeatherIcon.tsx
Normal file
@@ -0,0 +1,251 @@
|
||||
import { Image } from '@mantine/core';
|
||||
import CloudyIcon from '../../assets/weather/cloudy.svg';
|
||||
import HazeIcon from '../../assets/weather/haze.svg';
|
||||
import HeavyRainIcon from '../../assets/weather/heavy-rain.svg';
|
||||
import PartlyCloudyIcon from '../../assets/weather/partly-cloudy.svg';
|
||||
import RainIcon from '../../assets/weather/rain.svg';
|
||||
import SleetIcon from '../../assets/weather/sleet.svg';
|
||||
import SnowIcon from '../../assets/weather/snow.svg';
|
||||
import SunnyIcon from '../../assets/weather/sunny.svg';
|
||||
import ThunderstormIcon from '../../assets/weather/thunderstorm.svg';
|
||||
|
||||
export default function WeatherIcon({ textDescription }: { textDescription: string }) {
|
||||
const Icon = () => {
|
||||
switch (textDescription.trim()) {
|
||||
case 'Clear':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={SunnyIcon}
|
||||
alt='SunnyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Cloudy':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={CloudyIcon}
|
||||
alt='CloudyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Mostly Cloudy':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={CloudyIcon}
|
||||
alt='CloudyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Rain':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={RainIcon}
|
||||
alt='RainIcon'
|
||||
/>
|
||||
);
|
||||
case 'Showers':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={RainIcon}
|
||||
alt='RainIcon'
|
||||
/>
|
||||
);
|
||||
case 'Drizzle':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={RainIcon}
|
||||
alt='RainIcon'
|
||||
/>
|
||||
);
|
||||
case 'Snow':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={SnowIcon}
|
||||
alt='SnowIcon'
|
||||
/>
|
||||
);
|
||||
case 'Thunderstorm':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={ThunderstormIcon}
|
||||
alt='ThunderstormIcon'
|
||||
/>
|
||||
);
|
||||
case 'Mist':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Haze':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Dust':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Fog':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Smoke':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Sand':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Ash':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Squall':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Tornado':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Freezing Rain':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Shower Rain':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HazeIcon}
|
||||
alt='HazeIcon'
|
||||
/>
|
||||
);
|
||||
case 'Heavy Rain':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={HeavyRainIcon}
|
||||
alt='HeavyRainIcon'
|
||||
/>
|
||||
);
|
||||
case 'Scattered Clouds':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={PartlyCloudyIcon}
|
||||
alt='PartlyCloudyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Broken Clouds':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={PartlyCloudyIcon}
|
||||
alt='PartlyCloudyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Overcast Clouds':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={PartlyCloudyIcon}
|
||||
alt='PartlyCloudyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Moderate Rain':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={PartlyCloudyIcon}
|
||||
alt='PartlyCloudyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Light Rain':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={PartlyCloudyIcon}
|
||||
alt='PartlyCloudyIcon'
|
||||
/>
|
||||
);
|
||||
case 'Heavy Snow':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={SnowIcon}
|
||||
alt='SnowIcon'
|
||||
/>
|
||||
);
|
||||
case 'Sleet':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={SleetIcon}
|
||||
alt='SleetIcon'
|
||||
/>
|
||||
);
|
||||
case 'Partly Sunny':
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={PartlyCloudyIcon}
|
||||
alt='PartlyCloudyIcon'
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return (
|
||||
<Image
|
||||
style={{ width: '100px', height: '100px' }}
|
||||
src={SunnyIcon}
|
||||
alt='SunnyIcon'
|
||||
/>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
return <Icon />;
|
||||
}
|
||||
@@ -1,15 +1,26 @@
|
||||
import { Box, Center, Divider, Group, Modal, Stack, Text } from '@mantine/core';
|
||||
import { Center, Group, Modal, Stack, Text } from '@mantine/core';
|
||||
import { modalClasses } from 'styles';
|
||||
import SmallOutlookCard from './SmallOutlookCard';
|
||||
import SmallWeatherCard from './SmallWeatherCard';
|
||||
|
||||
import { useCommonHooks, useWeatherAPI } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import HourlyCard from './HourlyCard';
|
||||
import {
|
||||
Area,
|
||||
CartesianGrid,
|
||||
ComposedChart,
|
||||
Legend,
|
||||
Line,
|
||||
ResponsiveContainer,
|
||||
Tooltip,
|
||||
XAxis,
|
||||
YAxis,
|
||||
} from 'recharts';
|
||||
import CurrentWeather from './CurrentWeather';
|
||||
import ExtendedForecast from './ExtendedForecast';
|
||||
|
||||
export function WeatherModal({
|
||||
current,
|
||||
outlook,
|
||||
extendedForecast,
|
||||
closeWeatherModal,
|
||||
weatherModalOpened,
|
||||
}: any) {
|
||||
@@ -31,9 +42,32 @@ export function WeatherModal({
|
||||
const [hourlyForecast, setHourlyForecast] = useState<any>([]);
|
||||
const [sunset, setSunset] = useState(100);
|
||||
|
||||
function CustomTooltip({ payload, active, unit }: any) {
|
||||
if (active) {
|
||||
return (
|
||||
<Stack
|
||||
style={{
|
||||
backgroundColor: 'var(--color-background)',
|
||||
padding: '1rem',
|
||||
borderRadius: '8px',
|
||||
}}
|
||||
>
|
||||
{payload.map((item: any) => (
|
||||
<Text
|
||||
key={item.name}
|
||||
size='sm'
|
||||
>{`${item.name} - ${item.value}${item.unit}`}</Text>
|
||||
))}
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (hourly) {
|
||||
setHourlyForecast(hourly.properties.periods.slice(1, 13));
|
||||
setHourlyForecast(hourly.properties.periods.slice(1, 25));
|
||||
}
|
||||
}, [hourly]);
|
||||
|
||||
@@ -49,7 +83,6 @@ export function WeatherModal({
|
||||
);
|
||||
}
|
||||
}, [hourlyForecast]);
|
||||
|
||||
return (
|
||||
<Modal.Root
|
||||
fullScreen={isMobile}
|
||||
@@ -89,58 +122,99 @@ export function WeatherModal({
|
||||
</Modal.Title>
|
||||
<Modal.CloseButton />
|
||||
</Modal.Header>
|
||||
<Modal.Body pb={'2rem'}>
|
||||
<Modal.Body m={0}>
|
||||
<Center w={'100%'}>
|
||||
<Stack w={'100%'}>
|
||||
<Group gap={0} w={'100%'} align='center' justify='center'>
|
||||
<Stack gap={0} align='center'>
|
||||
<h3 style={{ padding: 0, margin: 0, color: 'white' }}>Currently</h3>
|
||||
<Stack>
|
||||
<SmallWeatherCard weather={current} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
<Divider
|
||||
orientation={isMobile ? 'horizontal' : 'vertical'}
|
||||
mx={16}
|
||||
color={theme.accentColor}
|
||||
/>
|
||||
<Group gap={8}>
|
||||
{outlook.map((o: any) => (
|
||||
<Stack key={o.name} gap={0} align='center'>
|
||||
<h3 style={{ padding: 0, margin: 0, color: 'white' }}>{o.name}</h3>
|
||||
<Stack>
|
||||
<SmallOutlookCard weather={o} />
|
||||
</Stack>
|
||||
</Stack>
|
||||
))}
|
||||
</Group>
|
||||
</Group>
|
||||
<Divider orientation='horizontal' mx={8} color={theme.accentColor} />
|
||||
<Group
|
||||
<CurrentWeather weather={current} />
|
||||
<Stack
|
||||
style={{
|
||||
background:
|
||||
hourlyForecast.length > 0 && hourlyForecast[0].isDaytime
|
||||
? `linear-gradient(90deg, rgba(245, 225, 171, 0.85) ${sunset - 5}%, rgba(35, 28, 42, 0.85) ${sunset + 5}%)`
|
||||
: `linear-gradient(90deg, rgba(35, 28, 42, 0.85)${sunset - 5}%, rgba(245, 225, 171, 0.85)${sunset + 5}%)`,
|
||||
background: 'var(--color-search-background)',
|
||||
padding: '.5rem',
|
||||
borderRadius: '.5rem',
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
style={{
|
||||
display: 'flex',
|
||||
overflow: 'auto',
|
||||
whiteSpace: 'nowrap',
|
||||
justifyContent: 'space-between',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
{hourlyForecast.length > 0 &&
|
||||
hourlyForecast.map((h: any) => {
|
||||
return <HourlyCard key={h.number} weather={h} />;
|
||||
})}
|
||||
</Box>
|
||||
</Group>
|
||||
<ResponsiveContainer width={'100%'} height={150}>
|
||||
<ComposedChart data={hourlyForecast}>
|
||||
<XAxis
|
||||
type='category'
|
||||
stroke={theme.primaryColor}
|
||||
dataKey={(data: any) => {
|
||||
return new Date(data.startTime).toLocaleTimeString('en-US', {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<YAxis
|
||||
stroke={theme.primaryColor}
|
||||
unit={'°F'}
|
||||
dataKey={'temperature'}
|
||||
/>
|
||||
<CartesianGrid stroke='#f5f5f522' />
|
||||
<Tooltip content={<CustomTooltip />} />
|
||||
<Line
|
||||
unit={'°F'}
|
||||
type='monotone'
|
||||
name='Temperature'
|
||||
dataKey='temperature'
|
||||
stroke={theme.primaryColor}
|
||||
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
|
||||
/>
|
||||
<Line
|
||||
unit={'°F'}
|
||||
type='monotone'
|
||||
name='Dew Point'
|
||||
dataKey={(data: any) => {
|
||||
return (data.dewpoint.value * 9) / 5 + 32;
|
||||
}}
|
||||
stroke={theme.accentColor}
|
||||
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
|
||||
/>
|
||||
<Legend style={{ background: 'var(--color-search-background)' }} />
|
||||
</ComposedChart>
|
||||
</ResponsiveContainer>
|
||||
<ResponsiveContainer width={'100%'} height={150}>
|
||||
<ComposedChart data={hourlyForecast}>
|
||||
<XAxis
|
||||
type='category'
|
||||
stroke={theme.primaryColor}
|
||||
dataKey={(data: any) => {
|
||||
return new Date(data.startTime).toLocaleTimeString('en-US', {
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<YAxis stroke={theme.primaryColor} unit={'%'} domain={[0, 100]} />
|
||||
<CartesianGrid stroke='#f5f5f522' />
|
||||
<Tooltip content={<CustomTooltip />} />
|
||||
<Area
|
||||
unit={'%'}
|
||||
type='monotone'
|
||||
name='Precipitation'
|
||||
dataKey={(data: any) => {
|
||||
return data.probabilityOfPrecipitation.value;
|
||||
}}
|
||||
stroke={theme.primaryColor}
|
||||
fill={theme.accentColor}
|
||||
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
|
||||
/>
|
||||
<Area
|
||||
unit={'%'}
|
||||
type='monotone'
|
||||
name='Humidity'
|
||||
dataKey={(data: any) => {
|
||||
return data.relativeHumidity.value;
|
||||
}}
|
||||
stroke={theme.accentColor}
|
||||
fill={theme.accentColor}
|
||||
dot={{ stroke: theme.primaryColor, strokeWidth: 1 }}
|
||||
/>
|
||||
<Legend style={{ background: 'var(--color-search-background)' }} />
|
||||
</ComposedChart>
|
||||
</ResponsiveContainer>
|
||||
</Stack>
|
||||
<ExtendedForecast forecast={extendedForecast} />
|
||||
</Stack>
|
||||
</Center>
|
||||
</Modal.Body>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { useCommonHooks, useOSMAPI, useQueryAPI, useWeatherAPI } from 'hooks';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { stackClasses } from 'styles';
|
||||
import type { CurrentWeather, OutlookWeather } from 'types';
|
||||
import type { ExtendedForecast } from 'types/weather';
|
||||
import Applications from './components/Applications/Applications';
|
||||
import Bookmarks from './components/Bookmarks/Bookmarks';
|
||||
import Header from './components/Header/Header';
|
||||
@@ -106,14 +107,17 @@ export function Homepage() {
|
||||
});
|
||||
const [current, setCurrent] = useState<CurrentWeather>({
|
||||
icon: '',
|
||||
textDescription: '',
|
||||
temperature: 0,
|
||||
highTemp: 0,
|
||||
lowTemp: 0,
|
||||
precipitation: 'N/A',
|
||||
humidity: 0,
|
||||
heatIndex: 0,
|
||||
heatIndex: null,
|
||||
windChill: null,
|
||||
windSpeed: 0,
|
||||
windDirection: 0,
|
||||
pressure: 0,
|
||||
});
|
||||
const [outlook, setOutlook] = useState<OutlookWeather[]>([
|
||||
{
|
||||
@@ -126,11 +130,22 @@ export function Homepage() {
|
||||
windDirection: 'N',
|
||||
},
|
||||
]);
|
||||
const [extendedForecast, setExtendedForecast] = useState<ExtendedForecast[]>([
|
||||
{
|
||||
detailedForecast: '',
|
||||
isDaytime: true,
|
||||
name: '',
|
||||
shortForecast: '',
|
||||
temperature: 0,
|
||||
temperatureUnit: 'F',
|
||||
},
|
||||
]);
|
||||
|
||||
useEffect(() => {
|
||||
if (weather !== undefined && basicWeather !== undefined) {
|
||||
setCurrent({
|
||||
icon: weather.features[0]?.properties.icon?.replace('medium', 'large') || '',
|
||||
textDescription: weather.features[0]?.properties.textDescription,
|
||||
temperature: Math.round(
|
||||
(weather.features[0]?.properties.temperature.value * 9) / 5 + 32,
|
||||
),
|
||||
@@ -143,13 +158,23 @@ export function Homepage() {
|
||||
precipitation:
|
||||
weather.features[0]?.properties.precipitationLastHour.value || 'N/A',
|
||||
humidity: Math.round(weather.features[0]?.properties.relativeHumidity.value),
|
||||
heatIndex: Math.round(
|
||||
weather.features[0]?.properties.heatIndex.value !== null
|
||||
? (weather.features[0]?.properties.heatIndex.value * 9) / 5 + 32
|
||||
: (weather.features[0]?.properties.temperature.value * 9) / 5 + 32,
|
||||
),
|
||||
heatIndex:
|
||||
basicWeather.properties.heatIndex?.values[0].value === null
|
||||
? null
|
||||
: Math.round(
|
||||
(basicWeather.properties.heatIndex.values[0].value * 9) / 5 + 32,
|
||||
),
|
||||
windChill:
|
||||
basicWeather.properties.windChill?.values[0].value === null
|
||||
? null
|
||||
: Math.round(
|
||||
(basicWeather.properties.windChill.values[0].value * 9) / 5 + 32,
|
||||
),
|
||||
windSpeed: Math.round(weather.features[0]?.properties.windSpeed.value / 1.60934),
|
||||
windDirection: weather.features[0]?.properties.windDirection.value,
|
||||
pressure: Math.round(
|
||||
weather.features[0]?.properties.barometricPressure.value / 3386.38,
|
||||
),
|
||||
});
|
||||
}
|
||||
}, [weather, basicWeather]);
|
||||
@@ -179,6 +204,16 @@ export function Homepage() {
|
||||
windDirection: forecast.properties.periods[1].windDirection,
|
||||
},
|
||||
]);
|
||||
setExtendedForecast(
|
||||
forecast.properties.periods.map((item: any) => ({
|
||||
detailedForecast: item.detailedForecast,
|
||||
isDaytime: item.isDaytime,
|
||||
name: item.name,
|
||||
shortForecast: item.shortForecast,
|
||||
temperature: item.temperature,
|
||||
temperatureUnit: item.temperatureUnit,
|
||||
})),
|
||||
);
|
||||
setCurrentLocation({
|
||||
office: points?.properties.gridId,
|
||||
station: stations?.features[0].properties.stationIdentifier,
|
||||
@@ -189,11 +224,13 @@ export function Homepage() {
|
||||
});
|
||||
}
|
||||
}, [forecast]);
|
||||
|
||||
return (
|
||||
<Stack gap={0} className={stackClasses.containerStack} justify='center'>
|
||||
<Search
|
||||
current={current}
|
||||
outlook={outlook}
|
||||
extendedForecast={extendedForecast}
|
||||
weather={weather}
|
||||
basicWeather={basicWeather}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
@@ -206,6 +243,7 @@ export function Homepage() {
|
||||
current={current}
|
||||
setCurrent={setCurrent}
|
||||
outlook={outlook}
|
||||
extendedForecast={extendedForecast}
|
||||
weather={weather}
|
||||
basicWeather={basicWeather}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
|
||||
@@ -10,6 +10,7 @@ function Header({
|
||||
current,
|
||||
setCurrent,
|
||||
outlook,
|
||||
extendedForecast,
|
||||
weather,
|
||||
basicWeather,
|
||||
weatherModalOpened,
|
||||
@@ -154,6 +155,7 @@ function Header({
|
||||
<WeatherModal
|
||||
current={current}
|
||||
outlook={outlook}
|
||||
extendedForecast={extendedForecast}
|
||||
closeWeatherModal={closeWeatherModal}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
/>
|
||||
|
||||
@@ -8,6 +8,7 @@ import { textInputClasses } from 'styles';
|
||||
export default function Search({
|
||||
current,
|
||||
outlook,
|
||||
extendedForecast,
|
||||
weatherModalOpened,
|
||||
closeWeatherModal,
|
||||
openWeatherModal,
|
||||
@@ -161,6 +162,7 @@ export default function Search({
|
||||
<WeatherModal
|
||||
current={current}
|
||||
outlook={outlook}
|
||||
extendedForecast={extendedForecast}
|
||||
closeWeatherModal={closeWeatherModal}
|
||||
weatherModalOpened={weatherModalOpened}
|
||||
/>
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
export interface CurrentWeather {
|
||||
icon: string;
|
||||
textDescription: string;
|
||||
temperature: number;
|
||||
highTemp: number;
|
||||
lowTemp: number;
|
||||
precipitation: string;
|
||||
humidity: number;
|
||||
heatIndex: number;
|
||||
heatIndex: number | null;
|
||||
windChill: number | null;
|
||||
windSpeed: number;
|
||||
windDirection: number;
|
||||
pressure: number;
|
||||
}
|
||||
|
||||
export interface OutlookWeather {
|
||||
@@ -19,3 +22,12 @@ export interface OutlookWeather {
|
||||
windSpeed: string;
|
||||
windDirection: string;
|
||||
}
|
||||
|
||||
export interface ExtendedForecast {
|
||||
detailedForecast: string;
|
||||
isDaytime: boolean;
|
||||
name: string;
|
||||
shortForecast: string;
|
||||
temperature: number;
|
||||
temperatureUnit: string;
|
||||
}
|
||||
|
||||