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

View File

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

View File

@@ -16,6 +16,22 @@ export default function WeatherIcon({
size: string;
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) => {
switch (code) {
case 0:
@@ -180,11 +196,7 @@ export default function WeatherIcon({
return (
<Image
style={
size === 'lg'
? { width: '150px', height: '150px' }
: { width: '75px', height: '75px' }
}
style={dimensions(size)}
src={lookupSource(code).src}
alt={lookupSource(code).alt}
/>