59 lines
1.8 KiB
TypeScript
59 lines
1.8 KiB
TypeScript
import { useEffect, useMemo, useState } from 'react';
|
|
// import { HiSolidArrowDown, HiSolidArrowUp } from 'solid-icons/hi';
|
|
// import { WiHumidity, WiSunrise, WiSunset } from 'solid-icons/wi';
|
|
import { useWeather } from '~/api/open-weather';
|
|
import { getTime } from '~/lib/date';
|
|
import {
|
|
IconChevronDown,
|
|
IconChevronUp,
|
|
IconDroplet,
|
|
IconSunrise,
|
|
IconSunset,
|
|
} from '@tabler/icons-react';
|
|
|
|
import style from './weather-widget.module.css';
|
|
import { Box } from '@mantine/core';
|
|
|
|
export function WeatherWidget() {
|
|
const weather = useWeather();
|
|
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
if (weather && isLoading === true) {
|
|
setTimeout(() => setIsLoading(false), 200);
|
|
}
|
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
}, [weather]);
|
|
|
|
const sunrise = useMemo(() => getTime((weather?.sunrise ?? 0) * 1000), [weather]);
|
|
const sunset = useMemo(() => getTime((weather?.sunset ?? 0) * 1000), [weather]);
|
|
|
|
if (!weather || isLoading) {
|
|
return <div className={`${style.Weather} ${style.Loading}`}>Loading...</div>;
|
|
}
|
|
|
|
return (
|
|
<div className={style.Weather}>
|
|
<div className={`${style.WeatherLine} ${style.Delimiter}`}>
|
|
<i className={`wi wi-owm-${weather.id} ${style.WeatherIcon}`}></i>
|
|
<div className={style.FeelsLike}>
|
|
<span>{weather.feels_like}°</span>
|
|
<span>{weather.main}</span>
|
|
</div>
|
|
</div>
|
|
<div className={style.WeatherLine}>
|
|
<IconChevronUp size={16} color="lightcoral" />
|
|
{weather.temp_min}° <IconChevronDown size={16} color="lightgreen" /> {weather.temp_max}
|
|
°
|
|
<IconDroplet size={14} />
|
|
{weather.humidity}%<br />
|
|
</div>
|
|
<Box className={style.WeatherLine} mt="xs">
|
|
<IconSunrise size={16} /> {sunrise}
|
|
<IconSunset size={16} /> {sunset}
|
|
</Box>
|
|
</div>
|
|
);
|
|
}
|