Fullscreen test

This commit is contained in:
2025-03-12 17:30:41 -05:00
parent bf82a3920d
commit 0ba63f57c4
5 changed files with 369 additions and 204 deletions

View File

@@ -6,7 +6,7 @@ import { FaLongArrowAltDown, FaLongArrowAltUp, FaWind } from 'react-icons/fa';
import { WiBarometer, WiHumidity, WiSunrise, WiSunset } from 'react-icons/wi';
import WeatherIcon from './WeatherIcon';
export default function CurrentWeather({ weather }: any) {
export default function CurrentWeather({ current }: any) {
const { currentLocation } = useCommonHooks();
const { data: sunStateData } = useSunStateAPI({
lat: currentLocation.lat,
@@ -28,184 +28,192 @@ export default function CurrentWeather({ weather }: any) {
);
}
}, [sunStateData]);
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%'} justify='space-between'>
<Text
c={'var(--color-text-pri)'}
<>
{current ? (
<Stack
gap={0}
w={'100%'}
justify='space-between'
style={{
fontSize: '1.375rem',
textAlign: 'right',
backgroundColor: 'var(--color-search-background)',
padding: '1rem',
borderRadius: '8px',
paddingBottom: '.5rem',
}}
c={'var(--color-text-pri)'}
>
Current Weather
</Text>
</Group>
<Group gap={8} w={'100%'} justify='space-between'>
<Stack gap={0} w={'45%'}>
<Group gap={0} justify='flex-end'>
<WeatherIcon
textDescription={`${
weather.textDescription.includes('and')
? weather.textDescription.substring(
0,
weather.textDescription.indexOf('and'),
)
: weather.textDescription.includes('then')
? weather.textDescription.substring(
0,
weather.textDescription.indexOf('then'),
)
: weather.textDescription
}`}
/>
<Text fz={'7rem'} fw={200}>
{weather.temperature}°<sup style={{ fontSize: '3rem' }}>F</sup>
<Group gap={0} px={16} w={'100%'} justify='space-between'>
<Text
c={'var(--color-text-pri)'}
style={{
fontSize: '1.375rem',
textAlign: 'right',
}}
>
Current Weather
</Text>
</Group>
<Text
c={'var(--color-text-pri)'}
style={{
fontSize: '1.375rem',
textAlign: 'right',
marginTop: -32,
marginLeft: 16,
}}
>
{weather.textDescription}
</Text>
</Stack>
<Stack gap={4} w={'45%'}>
<Text>
Feels like {weather.heatIndex ?? weather.windChill ?? weather.temperature}°
<sup>F</sup>
</Text>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
<Group gap={8} w={'100%'} justify='space-between'>
<Stack gap={0} w={'45%'}>
<Group gap={0} justify='flex-end'>
<WeatherIcon
textDescription={`${
current.textDescription.includes('and')
? current.textDescription.substring(
0,
current.textDescription.indexOf('and'),
)
: current.textDescription.includes('then')
? current.textDescription.substring(
0,
current.textDescription.indexOf('then'),
)
: current.textDescription
}`}
/>
<Text fz={'7rem'} fw={200}>
{current.temperature}°<sup style={{ fontSize: '3rem' }}>F</sup>
</Text>
</Group>
<Text
c={'var(--color-text-pri)'}
style={{
fontSize: '1.375rem',
textAlign: 'right',
marginTop: -32,
marginLeft: 16,
}}
>
<FaLongArrowAltUp size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>
{weather.highTemp}°<sup>F</sup>
{current.textDescription}
</Text>
</Grid.Col>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<FaLongArrowAltDown size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={1}>
</Stack>
<Stack gap={4} w={'45%'}>
<Text>
{weather.lowTemp}°<sup>F</sup>
Feels like {current.heatIndex ?? current.windChill ?? current.temperature}
°<sup>F</sup>
</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiSunrise size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>{sunStates[0]?.sunrise}</Text>
</Grid.Col>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiSunset size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>{sunStates[0]?.sunset}</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiHumidity size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>Humidity</Text>
</Grid.Col>
<Grid.Col span={2}>
<Text>{weather.humidity}%</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<FaWind size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>Wind</Text>
</Grid.Col>
<Grid.Col span={2}>
<Text>{weather.windSpeed}mph</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiBarometer size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>Pressure</Text>
</Grid.Col>
<Grid.Col span={2}>
<Text>{weather.pressure} in</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<FaLongArrowAltUp size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>
{current.highTemp}°<sup>F</sup>
</Text>
</Grid.Col>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<FaLongArrowAltDown size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={1}>
<Text>
{current.lowTemp}°<sup>F</sup>
</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiSunrise size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>{sunStates[0]?.sunrise}</Text>
</Grid.Col>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiSunset size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>{sunStates[0]?.sunset}</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiHumidity size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>Humidity</Text>
</Grid.Col>
<Grid.Col span={2}>
<Text>{current.humidity}%</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<FaWind size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>Wind</Text>
</Grid.Col>
<Grid.Col span={2}>
<Text>{current.windSpeed}mph</Text>
</Grid.Col>
</Grid>
<Grid align='center'>
<Grid.Col span={1}>
<ThemeIcon
h={'auto'}
w={'auto'}
variant='subtle'
c={'var(--color-text-pri)'}
>
<WiBarometer size={32} />
</ThemeIcon>
</Grid.Col>
<Grid.Col span={3}>
<Text>Pressure</Text>
</Grid.Col>
<Grid.Col span={2}>
<Text>{current.pressure} in</Text>
</Grid.Col>
</Grid>
</Stack>
</Group>
</Stack>
</Group>
</Stack>
) : (
<></>
)}
</>
);
}

View File

@@ -79,7 +79,7 @@ export function WeatherModal({
<Modal.Body m={0}>
<Center w={'100%'}>
<Stack w={'100%'}>
<CurrentWeather weather={current} />
<CurrentWeather current={current} />
<WeatherGraphs hourlyForecast={hourlyForecast} />
<ExtendedForecast forecast={extendedForecast} />
</Stack>

View File

@@ -1,13 +1,15 @@
import { Stack } from '@mantine/core';
import { Grid, Stack } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
import CurrentWeather from 'components/WeatherModal/CurrentWeather';
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 type { CurrentWeather as CW, OutlookWeather } from 'types';
import type { ExtendedForecast as EF } from 'types/weather';
import Applications from './components/Applications/Applications';
import Bookmarks from './components/Bookmarks/Bookmarks';
import Header from './components/Header/Header';
import LargeHeader from './components/Header/LargeHeader';
import Search from './components/Search/Search';
import SettingsButton from './components/SettingsButton';
@@ -105,7 +107,7 @@ export function Homepage() {
x: points?.properties.gridX || currentLocation.x,
y: points?.properties.gridY || currentLocation.y,
});
const [current, setCurrent] = useState<CurrentWeather>({
const [current, setCurrent] = useState<CW>({
icon: '',
textDescription: '',
temperature: 0,
@@ -130,7 +132,7 @@ export function Homepage() {
windDirection: 'N',
},
]);
const [extendedForecast, setExtendedForecast] = useState<ExtendedForecast[]>([
const [extendedForecast, setExtendedForecast] = useState<EF[]>([
{
detailedForecast: '',
isDaytime: true,
@@ -224,34 +226,73 @@ 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}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
/>
<Header
date={date}
greet={displayedGreeting}
current={current}
setCurrent={setCurrent}
outlook={outlook}
extendedForecast={extendedForecast}
weather={weather}
basicWeather={basicWeather}
weatherModalOpened={weatherModalOpened}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
/>
<Applications contentType={appFilter} />
<Bookmarks contentType={bookmarkFilter} />
<Stack
gap={0}
h={appFilter.length > 0 || bookmarkFilter.length > 0 ? undefined : '100%'}
className={stackClasses.containerStack}
justify='center'
>
{appFilter.length > 0 || bookmarkFilter.length > 0 ? (
<>
<Search
current={current}
outlook={outlook}
extendedForecast={extendedForecast}
weather={weather}
basicWeather={basicWeather}
weatherModalOpened={weatherModalOpened}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
/>
<Header
date={date}
greet={displayedGreeting}
current={current}
setCurrent={setCurrent}
outlook={outlook}
extendedForecast={extendedForecast}
weather={weather}
basicWeather={basicWeather}
weatherModalOpened={weatherModalOpened}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
/>
<Applications contentType={appFilter} />
<Bookmarks contentType={bookmarkFilter} />
</>
) : (
<>
<Stack align='center'>
<LargeHeader
date={date}
greet={displayedGreeting}
current={current}
setCurrent={setCurrent}
outlook={outlook}
extendedForecast={extendedForecast}
weather={weather}
basicWeather={basicWeather}
weatherModalOpened={weatherModalOpened}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
/>
<Grid grow columns={24} pos={'absolute'} bottom={'1rem'} w={'50%'}>
<CurrentWeather span={18} current={current} />
</Grid>
</Stack>
<Search
current={current}
outlook={outlook}
extendedForecast={extendedForecast}
weather={weather}
basicWeather={basicWeather}
weatherModalOpened={weatherModalOpened}
closeWeatherModal={closeWeatherModal}
openWeatherModal={openWeatherModal}
/>
</>
)}
<SettingsButton />
</Stack>
);

View File

@@ -38,6 +38,7 @@ function Header({
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,
),
@@ -50,11 +51,23 @@ function Header({
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 * 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]);

View File

@@ -0,0 +1,103 @@
import { Stack, Text } from '@mantine/core';
import { useCommonHooks } from 'hooks';
import { useEffect, useState } from 'react';
import { textClasses } from 'styles';
function LargeHeader({ greet, date, setCurrent, weather, basicWeather }: any) {
const [time, setTime] = useState(new Date());
const { isMobile, currentUser } = useCommonHooks();
function fixDigits(k: any) {
if (k < 10) {
return `0${k}`;
}
return k;
}
useEffect(() => {
setInterval(() => {
const newDate = new Date();
setTime(newDate);
}, 1000);
}, []);
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,
),
highTemp: Math.round(
(basicWeather.properties.maxTemperature.values[0].value * 9) / 5 + 32,
),
lowTemp: Math.round(
(basicWeather.properties.minTemperature.values[0].value * 9) / 5 + 32,
),
precipitation:
weather.features[0]?.properties.precipitationLastHour.value || 'N/A',
humidity: Math.round(weather.features[0]?.properties.relativeHumidity.value),
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]);
return (
<Stack gap={0} pos={'absolute'} align='center' justify='center' top={0}>
<Text
className={textClasses.greeting}
classNames={textClasses}
fz={isMobile ? 24 : 96}
>
{greet
.replace('$firstName', currentUser.firstName)
.replace('$lastName', currentUser.lastName)
.replace('$^firstName', currentUser.firstName.toUpperCase())
.replace('$^lastName', currentUser.lastName.toUpperCase())}
</Text>
<Text
fz={48}
className={textClasses.dateTime}
classNames={textClasses}
m={0}
style={{ width: 'max-content' }}
>
{date}
</Text>
<Text
fz={96}
fw={400}
m={0}
className={textClasses.dateTime}
classNames={textClasses}
>
{`${
time.getHours() === 0
? 12
: time.getHours() > 12
? time.getHours() - 12
: time.getHours()
}:${fixDigits(time.getMinutes())} ${time.getHours() >= 12 ? 'PM' : 'AM'}`}
</Text>
</Stack>
);
}
export default LargeHeader;