Files
TriggerFrontend/src/components/WeatherModal/ExtendedForecastDetails.tsx
Sean Edmunds 001843dcd2
All checks were successful
Deploy to production / build (push) Successful in 18s
Updates to details
2026-07-16 11:26:16 -05:00

320 lines
8.2 KiB
TypeScript

import { ActionIcon, Box, Card, Group, Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { FaLocationArrow, FaSun, FaWind } from 'react-icons/fa';
import { FaDroplet, FaX } from 'react-icons/fa6';
import { WiRain, WiSunrise, WiSunset } from 'react-icons/wi';
import { textClasses } from 'styles';
import { WeatherCodes } from 'types';
import WeatherFeaturePill from './WeatherFeaturePill';
import WeatherGraphs from './WeatherGraphs';
import WeatherIcon from './WeatherIcon';
export default function ExtendedForecastDetails({
selectedDay,
setSelectedDay,
selectedHourly,
setSelectedHourly,
}: {
selectedDay: any;
setSelectedDay: (day: any) => void;
selectedHourly: any;
setSelectedHourly: (hourly: any) => void;
}) {
const { isMobile } = useCommonHooks();
return (
<Card
h={'100%'}
w={'100%'}
style={{
color: 'var(--mantine-color-primary-0)',
backgroundColor: 'var(--mantine-color-background-0)',
padding: '1rem',
borderRadius: '8px',
overflow: 'visible',
cursor: 'default',
boxShadow:
'15px 15px 2px color-mix(in srgb, var(--mantine-color-border-0), transparent 50%)',
}}
onClick={(e) => {
e.stopPropagation();
}}
p={0}
>
<ActionIcon
pos={'absolute'}
top={-12}
right={-12}
style={{
borderRadius: '100%',
boxShadow: '2px 2px var(--mantine-color-search-0)',
}}
onClick={() => {
setSelectedDay(undefined);
setSelectedHourly(undefined);
}}
>
<FaX />
</ActionIcon>
<Group
w={'100%'}
justify='center'
bg={'var(--mantine-color-search-0)'}
py={4}
mt={0}
style={{
borderTopLeftRadius: '8px',
borderTopRightRadius: '8px',
}}
>
<Text fw={600} fz={'1.5rem'}>
{selectedDay.time.toLocaleDateString('en-US', { weekday: 'long' })}
</Text>
<Text fw={600} fz={'1.5rem'}>
{selectedDay.time.toLocaleDateString()}
</Text>
</Group>
<Stack align='center' p={16}>
<Group>
<Stack
gap={0}
style={{
overflow: 'hidden',
backgroundColor: 'var(--mantine-color-background-0)',
border: 'thin solid var(--mantine-color-primary-0)',
zIndex: 1,
paddingLeft: '2.25rem',
paddingRight: '2.25rem',
borderRadius: '100%',
aspectRatio: 1,
}}
align='center'
justify='center'
>
<Box m={0} p={0}>
<WeatherFeaturePill
leftSide={<Text>Feels like</Text>}
rightSide={
<Text>
{selectedDay.apparentTemperatureMax?.toFixed(0) ??
selectedDay.temperatureMax?.toFixed(0)}
°<sup>F</sup>
</Text>
}
highlight='right'
/>
</Box>
<Group pos={'relative'}>
<Text fz={isMobile ? '5rem' : '7rem'} fw={400} style={{ lineHeight: 1 }}>
{selectedDay.temperatureMax?.toFixed(0)}
<sup style={{ fontSize: '3rem' }}>°F</sup>
</Text>
<Text style={{ lineHeight: 1 }} pos={'absolute'} bottom={20} right={0}>
/ {selectedDay.temperatureMin?.toFixed(0)}°<sup>F</sup>
</Text>
<Box
style={{
position: 'absolute',
backgroundColor:
'color-mix(in srgb, var(--mantine-color-accent-0), transparent 80%)',
height: '250%',
width: '80%',
bottom: -96,
right: -60,
transform: 'skewX(-25deg)',
zIndex: -1,
borderRadius: '2px',
backdropFilter: 'brightness(0.5)',
lineHeight: 1,
}}
/>
</Group>
<Group
justify={
WeatherCodes[Number(selectedDay.weatherCode)].length > 25
? 'flex-start'
: 'center'
}
style={{
width: '100%',
maxWidth: '180px',
whiteSpace: 'nowrap',
overflow: 'hidden',
boxSizing: 'border-box',
position: 'relative',
}}
>
<Text
className={
WeatherCodes[Number(selectedDay.weatherCode)].length > 25
? textClasses.autoScrollText
: undefined
}
classNames={textClasses}
style={{ lineHeight: 1 }}
>
{selectedDay.temperature_2m?.toFixed(0) === '69'
? 'Nice'
: WeatherCodes[Number(selectedDay.weatherCode)]}
</Text>
</Group>
</Stack>
<Stack>
<WeatherIcon size={'xl'} code={selectedDay.weatherCode} />
</Stack>
</Group>
<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 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)',
}}
>
<FaDroplet
style={{
color: 'var(--mantine-color-accent-0)',
}}
/>
</Box>
</Stack>
<Stack gap={4}>
<WeatherFeaturePill
leftSide={
<Group gap={2}>
<WiRain size={16} />
<Text>Precipitation %</Text>
</Group>
}
rightSide={<Text>{selectedDay.precipitationProbability}%</Text>}
highlight='right'
/>
<WeatherFeaturePill
leftSide={
<Group gap={2}>
<WiRain size={16} />
<Text>Precipitation In.</Text>
</Group>
}
rightSide={<Text>{selectedDay.precipitationSum.toFixed(2)} in.</Text>}
highlight='right'
/>
</Stack>
</Group>
<WeatherGraphs hourly={selectedHourly} formatted />
</Stack>
</Card>
);
}