133 lines
3.8 KiB
TypeScript
133 lines
3.8 KiB
TypeScript
import { Box, Center, Divider, Group, Modal, Stack } from '@mantine/core';
|
|
import { useAtom } from 'jotai';
|
|
import { modalClasses } from 'styles';
|
|
import SmallOutlookCard from './SmallOutlookCard';
|
|
import SmallWeatherCard from './SmallWeatherCard';
|
|
|
|
import { useEffect, useState } from 'react';
|
|
import { appTheme } from '../../contexts/theme';
|
|
import HourlyCard from './HourlyCard';
|
|
|
|
export function WeatherModal({
|
|
current,
|
|
outlook,
|
|
hourly,
|
|
closeWeatherModal,
|
|
weatherModalOpened,
|
|
setProviderLabel,
|
|
setProviderURL,
|
|
isMobile,
|
|
}: any) {
|
|
const [theme, _] = useAtom(appTheme);
|
|
const [hourlyForecast, setHourlyForecast] = useState<any>([]);
|
|
const [sunset, setSunset] = useState(100);
|
|
|
|
useEffect(() => {
|
|
if (hourly) {
|
|
setHourlyForecast(hourly.properties.periods.slice(1, 13));
|
|
}
|
|
}, [hourly]);
|
|
|
|
useEffect(() => {
|
|
if (hourlyForecast) {
|
|
hourlyForecast[0]?.isDaytime
|
|
? setSunset(
|
|
(hourlyForecast.findIndex((item: any) => item.isDaytime === false) / 12) *
|
|
100,
|
|
)
|
|
: setSunset(
|
|
(hourlyForecast.findIndex((item: any) => item.isDaytime === true) / 12) * 100,
|
|
);
|
|
}
|
|
}, [hourlyForecast]);
|
|
return (
|
|
<Modal.Root
|
|
fullScreen={isMobile}
|
|
size={'60%'}
|
|
className={modalClasses.helpModal}
|
|
classNames={modalClasses}
|
|
opened={weatherModalOpened}
|
|
onClose={() => {
|
|
closeWeatherModal();
|
|
setProviderLabel('Google Search');
|
|
setProviderURL('https://www.google.com/search?q=');
|
|
}}
|
|
style={{
|
|
'--color-text-pri': theme.primaryColor,
|
|
'--color-text-acc': theme.accentColor,
|
|
'--color-background': theme.backgroundColor,
|
|
'--color-border': theme.borderColor,
|
|
'--color-search-background': theme.searchColor,
|
|
'--image-background': `url(${theme.backgroundImage})`,
|
|
}}
|
|
closeOnEscape
|
|
closeOnClickOutside
|
|
>
|
|
<Modal.Overlay />
|
|
<Modal.Content>
|
|
<Modal.Header>
|
|
<Modal.Title>Weather Forecast</Modal.Title>
|
|
<Modal.CloseButton />
|
|
</Modal.Header>
|
|
<Modal.Body pb={'2rem'}>
|
|
<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
|
|
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}%)`,
|
|
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} isMobile={isMobile} />
|
|
);
|
|
})}
|
|
</Box>
|
|
</Group>
|
|
</Stack>
|
|
</Center>
|
|
</Modal.Body>
|
|
</Modal.Content>
|
|
</Modal.Root>
|
|
);
|
|
}
|