From c89ea483c92c8f0818d4c4e026f313a8fcfa34ff Mon Sep 17 00:00:00 2001 From: Aly Raffauf Date: Thu, 29 Jan 2026 18:39:05 +0000 Subject: [PATCH] add weather component --- src/App.tsx | 8 ++++++++ src/index.ts | 18 ++++++++++++++++-- src/components/Weather.tsx | 42 ++++++++++++++++++++++++++++++++++++++++++ 3 file(s) changed, 66 insertion(s)(+), 2 deletion(s)(-) diff --git a/src/App.tsx b/src/App.tsx --- a/src/App.tsx +++ b/src/App.tsx @@ -1,5 +1,6 @@ import Layout from "./Layout"; import ServiceGrid from "./components/ServiceGrid"; +import { Weather } from "./components/Weather"; import { apps } from "./data/apps"; import { privateApps } from "./data/privateApps"; import { websites } from "./data/websites"; @@ -7,6 +8,13 @@ export function App() { return ( +
+
+ {" "} +

Weather

+ +
+

Websites

diff --git a/src/index.ts b/src/index.ts --- a/src/index.ts +++ b/src/index.ts @@ -26,6 +26,8 @@ } const server = serve({ + hostname: "0.0.0.0", + port: 3000, routes: { // Serve index.html for all unmatched routes. "/*": index, @@ -37,9 +39,21 @@ }, }, - "/api/websites": { + "/api/weather": { async GET(req) { - return Response.json(await checkStatuses(websites)); + const url = new URL(req.url); + const lat = url.searchParams.get("lat"); + const lon = url.searchParams.get("lon"); + + const pointsResponse = await fetch( + `https://api.weather.gov/points/${lat},${lon}`, + ); + + const pointsData = await pointsResponse.json(); + const forecastUrl = pointsData.properties.forecast; + const forecastResponse = await fetch(forecastUrl); + const forecastData = await forecastResponse.json(); + return Response.json(forecastData.properties.periods[0]); }, }, diff --git a/src/components/Weather.tsx b/src/components/Weather.tsx new file mode 100644 --- /dev/null +++ b/src/components/Weather.tsx @@ -0,0 +1,42 @@ +import { useState, useEffect } from "react"; + +export function Weather() { + const [weather, setWeather] = useState<{ + temperature: number; + temperatureUnit: string; + shortForecast: string; + } | null>(null); + + const [error, setError] = useState(null); + + useEffect(() => { + const fetchWeather = (lat: number, lon: number) => { + fetch(`/api/weather?lat=${lat}&lon=${lon}`) + .then((response) => response.json()) + .then((data) => setWeather(data)); + }; + + navigator.geolocation.getCurrentPosition( + (position) => { + fetchWeather(position.coords.latitude, position.coords.longitude); + }, + () => { + // Fallback to Atlanta + fetchWeather(33.749, -84.388); + }, + ); + }, []); + + if (!weather) { + return
Loading weather...
; + } + + return ( +
+
+ {weather.temperature}°{weather.temperatureUnit} +
+
{weather.shortForecast}
+
+ ); +} -- tangled.sh