infoscreen/src/components/WeatherAndTime.tsx
2022-07-11 20:38:18 +02:00

131 lines
5.2 KiB
TypeScript

import * as React from "react"
import { dowToString, monthToString } from "../lib/utils";
import type { SecretsWeather, WeatherInfo } from "../lib/interfaces";
import * as styles from "../styles/containers/WeatherAndTime.module.css";
const WEATHER_REFRESH_INTERVAL = 15 * 60 * 1000;
function getWeatherIcon(icon: string) {
let weatherIcon: string;
switch (icon) {
case "clear-day":
weatherIcon = "day-sunny"
break
case "clear-night":
weatherIcon = "night-clear"
break
case "wind":
weatherIcon = "windy"
break
case "partly-cloudy-day":
weatherIcon = "day-cloudy"
break
case "partly-cloudy-night":
weatherIcon = "night-cloudy"
break;
default: weatherIcon = icon
}
try {
const ImportedIcon = require(`../images/weather-icons/svg/wi-${weatherIcon}.svg`);
return <ImportedIcon />
} catch {
const ImportedIcon = require("../images/weather-icons/svg/wi-alien.svg");
return <ImportedIcon />
}
}
const WeatherAndTime = ({ secrets }: { secrets: SecretsWeather }) => {
const [date, setDate] = React.useState(new Date());
const [weather, setWeather] = React.useState<WeatherInfo>({
currently: {
icon: "clear-day",
temperature: 0,
summary: "No data loaded"
},
daily: {
data: [
{ icon: "clear-day", time: 0, temperatureHigh: 0, temperatureLow: 0 },
{ icon: "clear-day", time: 0, temperatureHigh: 0, temperatureLow: 0 },
{ icon: "clear-day", time: 0, temperatureHigh: 0, temperatureLow: 0 },
{ icon: "clear-day", time: 0, temperatureHigh: 0, temperatureLow: 0 },
]
}
});
const pullWeather = () => {
fetch(`https://api.pirateweather.net/forecast/${secrets.apiKey}/${secrets.coords}?exclude=minutely,hourly&lang=de&units=ca`)
.then(resp => resp.json())
.then(setWeather);
}
React.useEffect(() => {
const dateInterval = setInterval(() => {
const date = new Date()
if (date.getHours() < 7) document.documentElement.setAttribute("data-theme", "night");
else document.documentElement.setAttribute("data-theme", "day");
setDate(date);
}, 1000);
pullWeather()
const weatherInterval = setInterval(pullWeather, WEATHER_REFRESH_INTERVAL);
return () => {
clearInterval(dateInterval);
clearInterval(weatherInterval);
}
}, [])
const time = `${date.getHours()}:${date.getMinutes().toString().padStart(2, "0")}`;
const dateString = `${dowToString(date.getDay())}, der ${date.getDate()}. ${monthToString(date.getMonth())} ${date.getFullYear()}`;
if (weather.currently.summary === "No data loaded") return (<div className={`container ${styles.container}`}>
<span id={styles.clock}>{time}</span>
<span id={styles.date}>{dateString}</span>
</div>);
return (<div className={`container ${styles.container}`}>
<span id={styles.clock}>{time}</span>
<span id={styles.date}>{dateString}</span>
<div id={styles.weatherIcon}>{getWeatherIcon(weather.currently.icon)}</div>
<span id={styles.temperature}>{weather.currently.temperature.toFixed(1)}°C</span>
<span id={styles.currentWeatherInfos}>{weather.currently.summary}</span>
<table id={styles.futureWeatherInfos}>
<thead>
<tr>
{(() => {
const rslt: JSX.Element[] = []
for (let i = 0; i < 4; i++) {
const day = new Date((weather.daily.data[i].time * 1000));
rslt.push(<th colSpan={2} key={i}>{dowToString(day.getDay())}, {day.getDate()}. {day.getMonth() + 1}.</th>);
}
return rslt
})()}
</tr>
</thead>
<tbody>
<tr>
{(() => {
const rslt: JSX.Element[] = []
for (let i = 0; i < 4; i++) {
const style = i > 0 ? { borderLeft: "1px solid var(--iconColor)" } : {}
rslt.push(<td key={`00${i}`} rowSpan={2} style={style}>{getWeatherIcon(weather.daily.data[i].icon)}</td>);
rslt.push(<td key={`10${i}`} className={styles.futureWeatherHighTemp}>{weather.daily.data[i].temperatureHigh.toFixed(1)}°C</td>);
}
return rslt
})()}
</tr>
<tr>
{(() => {
const rslt: JSX.Element[] = []
for (let i = 0; i < 4; i++) {
rslt.push(<td key={i} className={styles.futureWeatherLowTemp}>{weather.daily.data[i].temperatureLow.toFixed(1)}°C</td>);
}
return rslt
})()}
</tr>
</tbody>
</table>
</div>)
}
export default WeatherAndTime;