Updated current weather
All checks were successful
Deploy to production / build (push) Successful in 12s

This commit is contained in:
Sean Edmunds
2026-07-14 14:10:04 -05:00
parent 3d5a2dd88a
commit 8bc8680152
3 changed files with 219 additions and 154 deletions

View File

@@ -1,7 +1,7 @@
import { Box, Card, Group, Stack, Text } from '@mantine/core'; import { Box, Card, Group, Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks'; import { useCommonHooks } from 'hooks';
import { FaLongArrowAltDown, FaLongArrowAltUp, FaWind } from 'react-icons/fa'; import { FaCloud, FaLocationArrow, FaSun, FaWind } from 'react-icons/fa';
import { WiBarometer, WiHumidity, 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 } from 'types';
import WeatherFeaturePill from './WeatherFeaturePill'; import WeatherFeaturePill from './WeatherFeaturePill';
@@ -54,11 +54,9 @@ export default function CurrentWeather({
}: { }: {
current: MeteoWeather | undefined; current: MeteoWeather | undefined;
}) { }) {
const { isMobile, theme, textShadowStyle } = useCommonHooks(); const { isMobile, theme } = useCommonHooks();
const sunrise = new Date(current?.daily.sunrise[0] || 0).toLocaleTimeString(); const sunrise = new Date(current?.daily.sunrise[0] || 0).toLocaleTimeString();
const sunset = new Date(current?.daily.sunset[0] || 0).toLocaleTimeString(); const sunset = new Date(current?.daily.sunset[0] || 0).toLocaleTimeString();
return ( return (
<> <>
{current && ( {current && (
@@ -84,8 +82,115 @@ export default function CurrentWeather({
> >
Current Weather Current Weather
</Text> </Text>
<Group gap={32} w={'100%'} align='center' justify='center' pt={'.5rem'}> <Group gap={32} w={'100%'} justify='center' pt={'.5rem'}>
<Stack gap={4} align='center'> <Stack w={'30%'}>
<Group gap={4} justify='space-between'>
<Stack align='center' gap={4}>
<WeatherFeaturePill
leftSide={
<Group gap={2}>
<WiRain size={16} />
<Text>Precipitation</Text>
</Group>
}
rightSide={<Text>{current.current.precipitation} in.</Text>}
highlight='right'
/>
<WeatherFeaturePill
leftSide={
<Group gap={2}>
<WiHumidity size={16} />
<Text>Humidity</Text>
</Group>
}
rightSide={<Text>{current.current.relative_humidity_2m}%</Text>}
highlight='right'
/>
<WeatherFeaturePill
leftSide={
<Group gap={0}>
<WiBarometer size={16} />
<Text>Pressure</Text>
</Group>
}
rightSide={
<Text>{current.current.surface_pressure?.toFixed(0)} mbar</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)',
}}
>
<FaCloud
style={{
color: 'var(--mantine-color-accent-0)',
}}
/>
</Box>
<Text fz={12}>{current.current.cloud_cover?.toFixed(0)}%</Text>
</Stack>
</Group>
<Group justify='space-between'>
<Stack gap={4}>
<WeatherFeaturePill
leftSide={
<Group gap={2}>
<FaWind size={16} />
<Text>Wind</Text>
</Group>
}
rightSide={
<Text>{current.current.wind_speed_10m?.toFixed(0)}mph</Text>
}
highlight='right'
/>
<WeatherFeaturePill
leftSide={
<Group gap={2}>
<FaWind size={16} />
<Text>Gusts</Text>
</Group>
}
rightSide={
<Text>{current.current.wind_gusts_10m?.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(${-45 + (current.current.wind_direction_10m || 0)}deg)`,
}}
/>
</Box>
<Text fz={12}>{current.current.wind_direction_10m?.toFixed(0)}°</Text>
</Stack>
</Group>
</Stack>
<Stack align='center' w={'30%'}>
<Stack <Stack
gap={0} gap={0}
style={{ style={{
@@ -93,42 +198,58 @@ export default function CurrentWeather({
backgroundColor: 'var(--mantine-color-background-0)', backgroundColor: 'var(--mantine-color-background-0)',
border: 'thin solid var(--mantine-color-primary-0)', border: 'thin solid var(--mantine-color-primary-0)',
zIndex: 1, zIndex: 1,
padding: '1rem', padding: '2.25rem',
borderRadius: '8px', borderRadius: '100%',
aspectRatio: 1,
}} }}
align='center'
justify='center'
> >
<Group pos={'relative'}> <Box m={0} p={0} mb={'-.5rem'}>
<Box <WeatherFeaturePill
style={{ leftSide={<Text>Feels like </Text>}
position: 'absolute', rightSide={
right: '-1.25rem', <Text>
bottom: '-1.25rem', {current.current.apparent_temperature?.toFixed(0) ??
zIndex: -1, current.current.temperature_2m?.toFixed(0)}
opacity: 0.5, °<sup>F</sup>
}} </Text>
}
highlight='right'
/>
</Box>
<Group pos={'relative'} m={0}>
<Text
fz={isMobile ? '5rem' : '7rem'}
fw={400}
style={{ lineHeight: 1 }}
> >
<WeatherIcon size={'lg'} code={current.current.weather_code} /> {current.current.temperature_2m?.toFixed(0)}
</Box> <sup style={{ fontSize: '3rem' }}>°F</sup>
<Text fz={isMobile ? '5rem' : '7rem'} fw={400}>
{current.current.temperature_2m?.toFixed(0)}°
<sup style={{ fontSize: '3rem' }}>F</sup>
</Text> </Text>
<Box <Box
style={{ style={{
position: 'absolute', position: 'absolute',
backgroundColor: backgroundColor:
'color-mix(in srgb, var(--mantine-color-accent-0), transparent 80%)', 'color-mix(in srgb, var(--mantine-color-accent-0), transparent 80%)',
height: '200%', height: '250%',
width: '100%', width: '80%',
bottom: -40, bottom: -72,
right: -72, right: -60,
transform: 'skewX(-25deg)', transform: 'skewX(-25deg)',
zIndex: -1, zIndex: -1,
borderRadius: '2px', borderRadius: '2px',
backdropFilter: 'brightness(0.5)', backdropFilter: 'brightness(0.5)',
lineHeight: 1,
}} }}
/> />
</Group> </Group>
<Group mb={4}>
<Text style={{ lineHeight: 1 }}>
{current.daily.temperature_2m_max?.[0].toFixed(0)}°<sup>F</sup>/
{current.daily.temperature_2m_min?.[0].toFixed(0)}°<sup>F</sup>
</Text>
</Group>
<Group <Group
justify={ justify={
WeatherCodes[Number(current.current.weather_code)].length > 25 WeatherCodes[Number(current.current.weather_code)].length > 25
@@ -151,6 +272,7 @@ export default function CurrentWeather({
: undefined : undefined
} }
classNames={textClasses} classNames={textClasses}
style={{ lineHeight: 1 }}
> >
{current.current.temperature_2m?.toFixed(0) === '69' {current.current.temperature_2m?.toFixed(0) === '69'
? 'Nice' ? 'Nice'
@@ -158,124 +280,54 @@ export default function CurrentWeather({
</Text> </Text>
</Group> </Group>
</Stack> </Stack>
<WeatherFeaturePill
leftSide={<Text>Feels like </Text>}
rightSide={
<Text>
{current.current.apparent_temperature?.toFixed(0) ??
current.current.temperature_2m?.toFixed(0)}
°<sup>F</sup>
</Text>
}
highlight='right'
/>
</Stack> </Stack>
<Stack gap={10}> <Stack
<Stack gap={0} align='center'> gap={4}
<Text w={'30%'}
className={textClasses.sectionTitle} h={'100%'}
classNames={textClasses} align='center'
style={{ justify='center'
textAlign: 'center', pos={'relative'}
textShadow: theme.textShadowsEnabled ? textShadowStyle : undefined, >
}} <Box
w={'100%'} style={{
> position: 'absolute',
Temperatures bottom: -64,
</Text> zIndex: -1,
<Group justify='center'> opacity: 0.3,
<WeatherFeaturePill }}
leftSide={ >
<Group gap={0}> <WeatherIcon size={'xl'} code={current.current.weather_code} />
<FaLongArrowAltUp size={16} /> </Box>
High <Group
</Group> w={'100%'}
} justify='space-between'
rightSide={ pos={'absolute'}
<Text> right={0}
{current.daily.temperature_2m_max?.[0].toFixed(0)}°<sup>F</sup> top={24}
</Text> >
} <Stack align='center' justify='center' gap={0}>
highlight='right' <Box
/> style={{
<WeatherFeaturePill border: '2px solid var(--mantine-color-primary-0)',
leftSide={ borderRadius: '100%',
<Group gap={0}> aspectRatio: 1,
<FaLongArrowAltDown size={16} /> width: 'fit-content',
Low padding: '.75rem',
</Group> display: 'flex',
} backgroundColor: 'var(--mantine-color-background-0)',
rightSide={ }}
<Text> >
{current.daily.temperature_2m_min?.[0].toFixed(0)}°<sup>F</sup> <FaSun
</Text> style={{
} color: 'var(--mantine-color-accent-0)',
highlight='right' transform: `rotate(${-45 + (current.current.wind_direction_10m || 0)}deg)`,
/> }}
</Group> />
</Stack> </Box>
<Stack gap={0} align='center'> <Text fz={12}>UV {current.daily.uv_index_max?.[0].toFixed(0)}</Text>
<Text </Stack>
className={textClasses.sectionTitle} <Stack gap={4}>
classNames={textClasses}
style={{
textAlign: 'center',
textShadow: theme.textShadowsEnabled ? textShadowStyle : undefined,
}}
w={'100%'}
>
Conditions
</Text>
<Group justify='center'>
<WeatherFeaturePill
leftSide={
<Group gap={0}>
<WiHumidity size={16} />
Humidity
</Group>
}
rightSide={<Text>{current.current.relative_humidity_2m}%</Text>}
highlight='right'
/>
<WeatherFeaturePill
leftSide={
<Group gap={0}>
<FaWind size={16} />
Wind
</Group>
}
rightSide={
<Text>{current.current.wind_speed_10m?.toFixed(0)}mph</Text>
}
highlight='right'
/>
<WeatherFeaturePill
leftSide={
<Group gap={0}>
<WiBarometer size={16} />
Pressure
</Group>
}
rightSide={
<Text>{current.current.surface_pressure?.toFixed(0)} mbar</Text>
}
highlight='right'
/>
</Group>
</Stack>
<Stack gap={0} align='center'>
<Text
className={textClasses.sectionTitle}
classNames={textClasses}
style={{
textAlign: 'center',
textShadow: theme.textShadowsEnabled ? textShadowStyle : undefined,
}}
w={'100%'}
>
Sun Cycle
</Text>
<Group justify='center'>
<WeatherFeaturePill <WeatherFeaturePill
leftSide={ leftSide={
<Group gap={0}> <Group gap={0}>
@@ -310,8 +362,8 @@ export default function CurrentWeather({
rightSide={<Text>{sunset}</Text>} rightSide={<Text>{sunset}</Text>}
highlight='left' highlight='left'
/> />
</Group> </Stack>
</Stack> </Group>
</Stack> </Stack>
</Group> </Group>
</Card> </Card>

View File

@@ -11,11 +11,12 @@ function WeatherFeaturePill({
}) { }) {
return ( return (
<Group <Group
gap={2} gap={'auto'}
w={'fit-content'} w={'100%'}
justify='space-between'
style={{ style={{
color: 'var(--mantine-color-background-0)', color: 'var(--mantine-color-background-0)',
backgroundColor: 'var(--mantine-color-primary-0)', backgroundColor: 'var(--mantine-color-search-0)',
borderRadius: '16px', borderRadius: '16px',
padding: '2px', padding: '2px',
}} }}

View File

@@ -16,6 +16,22 @@ export default function WeatherIcon({
size: string; size: string;
code: number | undefined; code: number | undefined;
}) { }) {
const dimensions = (size: string) => {
switch (size) {
case 'xs':
return { width: 16, height: 16 };
case 'sm':
return { width: '32px', height: '32px' };
case 'md':
return { width: '75px', height: '75px' };
case 'lg':
return { width: '150px', height: '150px' };
case 'xl':
return { width: '225px', height: '225px' };
default:
return { width: 32, height: 32 };
}
};
const lookupSource = (code: any) => { const lookupSource = (code: any) => {
switch (code) { switch (code) {
case 0: case 0:
@@ -180,11 +196,7 @@ export default function WeatherIcon({
return ( return (
<Image <Image
style={ style={dimensions(size)}
size === 'lg'
? { width: '150px', height: '150px' }
: { width: '75px', height: '75px' }
}
src={lookupSource(code).src} src={lookupSource(code).src}
alt={lookupSource(code).alt} alt={lookupSource(code).alt}
/> />