halfPage/src/components/navbar/index.tsx
2025-04-09 22:32:54 -04:00

65 lines
No EOL
2.7 KiB
TypeScript

import { useState } from 'preact/hooks';
import { ChevronLeft, ChevronRight } from 'lucide-preact';
import desc from "./desc.json";
const favicon = document.getElementById("favicon") as HTMLLinkElement;
const fetchWeather = async (lat: number, long: number) => {
const req = await fetch(`https://api.open-meteo.com/v1/forecast?latitude=${lat}&longitude=${long}&current=temperature_2m,is_day,weather_code&timezone=${Intl.DateTimeFormat().resolvedOptions().timeZone}`)
const res = await req.json();
return res as {
current: {
temperature_2m: number,
is_day: number;
weather_code: number;
}
}
}
export default () => {
const [weather, setWeather] = useState<string>("Loading...");
const [imgSrc, setSrc] = useState<string>("favicon.svg");
const [wttrDesc, setWttrDesc] = useState<string>("Loading...");
const getWeather = async (coords: GeolocationCoordinates) => {
const weather = await fetchWeather(coords.latitude, coords.longitude);
const weatherCode = weather.current.weather_code;
const isDay = weather.current.is_day === 1;
const dayOrNight = isDay ? "Day" : "Night";
const weatherDesc = desc[weatherCode.toString() as keyof typeof desc][dayOrNight.toLowerCase() as "day" | "night"];
setWeather(`${weather.current.temperature_2m}°C`);
setSrc(weatherDesc.image);
favicon.href = weatherDesc.image;
setWttrDesc(`${weatherDesc.description} & ${dayOrNight}`);
}
(async () => {
const req = await fetch("https://cf.ipv4-army.workers.dev/")
const res = await req.json();
return await getWeather(res);
})()
return (
<>
<nav class="navbar shadow fixed-top" style="background-color: var(--bs-content-bg); border-bottom: var(--bs-border-width) solid var(--bs-content-border-color);">
<div class="container-fluid">
<div class="navbar-brand">
{wttrDesc}
<img src={imgSrc} alt="Logo" width="24" height="24" class="d-inline-block align-text-top" />
</div>
<span class="navbar-text">
{weather}
</span>
<div class="d-flex hstack gap-2" role="search">
<button type="button" class="btn btn-outline-light btn-sm" onClick={history.back}><ChevronLeft size={20} /></button>
<button type="button" class="btn btn-outline-light btn-sm" onClick={history.forward}><ChevronRight size={20} /></button>
</div>
</div>
</nav>
</>
)
}