parent
f0f470ba8b
commit
6a97d392c9
@ -0,0 +1,7 @@
|
|||||||
|
import mapIcon from "utils/owm-condition-map";
|
||||||
|
|
||||||
|
export default function Icon({ condition, timeOfDay }) {
|
||||||
|
const Icon = mapIcon(condition, timeOfDay);
|
||||||
|
|
||||||
|
return <Icon className="w-10 h-10 text-theme-800 dark:text-theme-200"></Icon>;
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
import useSWR from "swr";
|
||||||
|
import { BiError } from "react-icons/bi";
|
||||||
|
|
||||||
|
import Icon from "./icon";
|
||||||
|
|
||||||
|
export default function OpenWeatherMap({ options }) {
|
||||||
|
const { data, error } = useSWR(
|
||||||
|
`/api/widgets/openweathermap?lat=${options.latitude}&lon=${options.longitude}&apiKey=${options.apiKey}&duration=${options.cache}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (error) {
|
||||||
|
return (
|
||||||
|
<div className="order-last grow flex-none flex flex-row items-center justify-end">
|
||||||
|
<BiError className="w-8 h-8 text-theme-800 dark:text-theme-200" />
|
||||||
|
<div className="flex flex-col ml-3 text-left">
|
||||||
|
<span className="text-theme-800 dark:text-theme-200 text-sm">API</span>
|
||||||
|
<span className="text-theme-800 dark:text-theme-200 text-xs">Error</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!data) {
|
||||||
|
return <div className="order-last grow flex-none flex flex-row items-center justify-end"></div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data.error) {
|
||||||
|
return <div className="order-last grow flex-none flex flex-row items-center justify-end"></div>;
|
||||||
|
}
|
||||||
|
// OpenWeatherMap returns temperature in Kelvins
|
||||||
|
var temp_c = data.main.temp - 273.15;
|
||||||
|
var temp_f = temp_c * 9 / 5 + 32;
|
||||||
|
return (
|
||||||
|
<div className="order-last grow flex-none flex flex-row items-center justify-end">
|
||||||
|
<Icon condition={data.weather[0].id} timeOfDay={(data.dt > data.sys.sunrise) && (data.dt < data.sys.sundown) ? "day" : "night"} />
|
||||||
|
<div className="flex flex-col ml-3 text-left">
|
||||||
|
<span className="text-theme-800 dark:text-theme-200 text-sm">
|
||||||
|
{options.units === "metric" ? temp_c.toFixed(0) : temp_f.toFixed(0)}°
|
||||||
|
</span>
|
||||||
|
<span className="text-theme-800 dark:text-theme-200 text-xs">{data.weather[0].description}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
import cachedFetch from "utils/cached-fetch";
|
||||||
|
|
||||||
|
export default async function handler(req, res) {
|
||||||
|
const { lat, lon, apiKey, duration } = req.query;
|
||||||
|
|
||||||
|
const api_url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${apiKey}`;
|
||||||
|
|
||||||
|
res.send(await cachedFetch(api_url, duration));
|
||||||
|
}
|
@ -0,0 +1,413 @@
|
|||||||
|
import * as Icons from "react-icons/wi";
|
||||||
|
|
||||||
|
const conditions = [
|
||||||
|
{
|
||||||
|
code: 200,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayStormShowers,
|
||||||
|
night: Icons.WiNightAltStormShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 201,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 202,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 210,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayStormShowers,
|
||||||
|
night: Icons.WiNightAltStormShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 211,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 212,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 221,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 230,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayStormShowers,
|
||||||
|
night: Icons.WiNightAltStormShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 231,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayStormShowers,
|
||||||
|
night: Icons.WiNightAltStormShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 232,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayThunderstorm,
|
||||||
|
night: Icons.WiNightAltThunderstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
code: 300,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySprinkle,
|
||||||
|
night: Icons.WiNightAltSprinkle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 301,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySprinkle,
|
||||||
|
night: Icons.WiNightAltSprinkle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 302,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 310,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySprinkle,
|
||||||
|
night: Icons.WiNightAltSprinkle,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 311,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 312,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 313,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 314,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 321,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
code: 500,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 501,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 502,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 503,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 504,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRain,
|
||||||
|
night: Icons.WiNightAltRain,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 511,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 520,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 521,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 522,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 531,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayShowers,
|
||||||
|
night: Icons.WiNightAltShowers,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
code: 600,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 601,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 602,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 611,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 612,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 613,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySleet,
|
||||||
|
night: Icons.WiNightAltSleet,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 615,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRainMix,
|
||||||
|
night: Icons.WiNightAltRainMix,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 616,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayRainMix,
|
||||||
|
night: Icons.WiNightAltRainMix,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 620,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 621,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 622,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySnow,
|
||||||
|
night: Icons.WiNightAltSnow,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
code: 701,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayFog,
|
||||||
|
night: Icons.WiNightFog,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 711,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiSmoke,
|
||||||
|
night: Icons.WiSmoke,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 721,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayHaze,
|
||||||
|
night: Icons.WiWindy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 731,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDust,
|
||||||
|
night: Icons.WiDust,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 741,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayFog,
|
||||||
|
night: Icons.WiNightFog,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 751,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDust,
|
||||||
|
night: Icons.WiDust,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 761,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiSandstorm,
|
||||||
|
night: Icons.WiSandstorm,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 762,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDust,
|
||||||
|
night: Icons.WiDust,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 771,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiStrongWind,
|
||||||
|
night: Icons.WiStrongWind,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
code: 781,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiTornado,
|
||||||
|
night: Icons.WiTornado,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
code: 800,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDaySunny,
|
||||||
|
night: Icons.WiNightClear,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
{
|
||||||
|
code: 801,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayCloudy,
|
||||||
|
night: Icons.WiNightAltCloudy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 802,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayCloudy,
|
||||||
|
night: Icons.WiNightAltCloudy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 803,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiDayCloudy,
|
||||||
|
night: Icons.WiNightAltCloudy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
code: 804,
|
||||||
|
icon: {
|
||||||
|
day: Icons.WiCloudy,
|
||||||
|
night: Icons.WiCloudy,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
];
|
||||||
|
|
||||||
|
export default function mapIcon(weatherStatusCode, timeOfDay) {
|
||||||
|
const mapping = conditions.find(
|
||||||
|
(condition) => condition.code === weatherStatusCode
|
||||||
|
);
|
||||||
|
|
||||||
|
if (mapping) {
|
||||||
|
if (timeOfDay === "day") {
|
||||||
|
return mapping.icon.day;
|
||||||
|
} else if (timeOfDay === "night") {
|
||||||
|
return mapping.icon.night;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Icons.WiDaySunny;
|
||||||
|
}
|
Loading…
Reference in new issue