import { Stack } from '@mantine/core'; import { useDisclosure } from '@mantine/hooks'; import { useCommonHooks, useOSMAPI, useQueryAPI, useWeatherAPI } from 'hooks'; import { useEffect, useState } from 'react'; import { stackClasses } from 'styles'; import type { CurrentWeather, OutlookWeather } from 'types'; import Applications from './components/Applications/Applications'; import Bookmarks from './components/Bookmarks/Bookmarks'; import Header from './components/Header/Header'; import Search from './components/Search/Search'; import SettingsButton from './components/SettingsButton'; export function Homepage() { const { data: personal, isFetched: personalIsFetched } = useQueryAPI({ endpoint: 'api/personalData', }); const { data: messageData, isFetching: isMessagesFetching, isFetched: isMessagesFetched, } = useQueryAPI({ endpoint: 'api/messages', }); const [personalData, setPersonalData] = useState([]); const [messages, setMessages] = useState([]); const [displayedGreeting, setDisplayedGreeting] = useState(''); const [weatherModalOpened, { open: openWeatherModal, close: closeWeatherModal }] = useDisclosure(false); const { appFilter, bookmarkFilter, isMobile } = useCommonHooks(); const dateOptions: Intl.DateTimeFormatOptions = !isMobile ? { weekday: 'long', year: 'numeric', month: 'long', day: 'numeric', } : {}; const date = new Date().toLocaleDateString('en-US', dateOptions); useEffect(() => { if (messageData && isMessagesFetched) { setMessages(messageData); } }, [messageData, isMessagesFetched]); useEffect(() => { if (personal && personalIsFetched) { setPersonalData(personal); } }, [personal, personalIsFetched]); useEffect(() => { if (messages && personalData) { setDisplayedGreeting(() => { if (Math.floor(Math.random() * 100) > 10 || messages.length === 0) { switch (Math.floor(new Date().getHours() / 6)) { case 0: return `Good night, ${personalData?.[0]?.firstName}!`; case 1: return `Good morning, ${personalData?.[0]?.firstName}!`; case 2: return `Good afternoon, ${personalData?.[0]?.firstName}!`; case 3: return `Good evening, ${personalData?.[0]?.firstName}!`; } } return messages[Math.floor(Math.random() * messages.length)].message; }); } }, [messages, personalData, isMessagesFetching]); const { data: weatherMetadata } = useOSMAPI({ address: personal?.[0].physicalAddress }); const { data: points } = useWeatherAPI({ endpoint: 'points', lat: weatherMetadata?.[0].lat || 0, lon: weatherMetadata?.[0].lon || 0, }); const { data: basicWeather } = useWeatherAPI({ endpoint: 'baseline', office: points?.properties.gridId, x: points?.properties.gridX, y: points?.properties.gridY, }); const { data: stations } = useWeatherAPI({ endpoint: 'stations', office: points?.properties.gridId, x: points?.properties.gridX, y: points?.properties.gridY, }); const { data: weather } = useWeatherAPI({ endpoint: 'current', station: stations?.features[0].properties.stationIdentifier, }); const { data: forecast } = useWeatherAPI({ endpoint: 'forecast', office: points?.properties.gridId, x: points?.properties.gridX, y: points?.properties.gridY, }); const [current, setCurrent] = useState({ icon: '', temperature: 0, highTemp: 0, lowTemp: 0, precipitation: 'N/A', humidity: 0, heatIndex: 0, windSpeed: 0, windDirection: 0, }); const [outlook, setOutlook] = useState([ { name: '', icon: '', isDayTime: true, temperature: 0, precipitation: 0, windSpeed: '0 mph', windDirection: 'N', }, ]); useEffect(() => { if (weather !== undefined && basicWeather !== undefined) { setCurrent({ icon: weather.features[0]?.properties.icon?.replace('medium', 'large') || '', 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: Math.round( weather.features[0]?.properties.heatIndex.value !== null ? (weather.features[0]?.properties.heatIndex.value * 9) / 5 + 32 : (weather.features[0]?.properties.temperature.value * 9) / 5 + 32, ), windSpeed: Math.round(weather.features[0]?.properties.windSpeed.value / 1.60934), windDirection: weather.features[0]?.properties.windDirection.value, }); } }, [weather, basicWeather]); useEffect(() => { if (forecast) { setOutlook([ { name: forecast.properties.periods[0].name, icon: forecast.properties.periods[0].icon.replace('medium', 'large'), isDayTime: forecast.properties.periods[0].isDaytime, temperature: forecast.properties.periods[0].temperature, precipitation: Math.round( forecast.properties.periods[0].probabilityOfPrecipitation.value, ), windSpeed: forecast.properties.periods[0].windSpeed, windDirection: forecast.properties.periods[0].windDirection, }, { name: forecast.properties.periods[1].name, icon: forecast.properties.periods[1].icon.replace('medium', 'large'), isDayTime: forecast.properties.periods[1].isDaytime, temperature: forecast.properties.periods[1].temperature, precipitation: Math.round( forecast.properties.periods[1].probabilityOfPrecipitation.value, ), windSpeed: forecast.properties.periods[1].windSpeed, windDirection: forecast.properties.periods[1].windDirection, }, ]); } }, [forecast]); return (
); }