import { createSignal, onMount, onCleanup, Show } from "solid-js"; import type { WidgetSettings, WidgetSchema } from "../types/widget"; import { getRefreshInterval } from "../utils/timeUtils"; interface WeatherProps { settings: WidgetSettings; } interface WeatherData { temp: number; description: string; humidity: number; windSpeed: number; } export function Weather(props: WeatherProps) { const [weather, setWeather] = createSignal(null); const [error, setError] = createSignal(""); const fetchWeather = async () => { try { const city = (props.settings.city as string) || "London"; const lat = (props.settings.lat as string) || ""; const lon = (props.settings.lon as string) || ""; const apiKey = (props.settings.apiKey as string) || ""; const units = (props.settings.units as string) || "metric"; if (!apiKey) { setError("API key required"); return; } // Build URL based on whether lat/lon or city is provided let url = `/api/weather?apiKey=${encodeURIComponent(apiKey)}&units=${units}`; if (lat && lon) { url += `&lat=${encodeURIComponent(lat)}&lon=${encodeURIComponent(lon)}`; } else { url += `&city=${encodeURIComponent(city)}`; } // Use our server endpoint instead of calling OpenWeatherMap directly const response = await fetch(url); if (!response.ok) { throw new Error("Failed to fetch weather"); } const data = await response.json(); setWeather({ temp: Math.round(data.main.temp), description: data.weather[0].description, humidity: data.main.humidity, windSpeed: data.wind.speed, }); setError(""); } catch (err) { setError("Error fetching weather"); console.error(err); } }; onMount(() => { fetchWeather(); const refreshInterval = getRefreshInterval(props.settings, 10, "minutes"); const interval = setInterval(fetchWeather, refreshInterval); onCleanup(() => clearInterval(interval)); }); return (
{error()}
{props.settings.lat && props.settings.lon ? `${props.settings.lat}, ${props.settings.lon}` : props.settings.city || "London"}
{weather()?.temp}° {(props.settings.units as string) === "metric" ? "C" : "F"}
{weather()?.description}
💧 {weather()?.humidity}%
💨 {weather()?.windSpeed} m/s
); } export const weatherSchema: WidgetSchema = { name: "Weather", description: "Display current weather from OpenWeatherMap API", settingsSchema: { city: { type: "string", label: "City Name", default: "London", required: false, }, lat: { type: "string", label: "Latitude (optional, overrides city)", default: "", required: false, }, lon: { type: "string", label: "Longitude (optional, overrides city)", default: "", required: false, }, apiKey: { type: "string", label: "OpenWeatherMap API Key", default: "", required: true, }, units: { type: "select", label: "Temperature Units", default: "metric", options: ["metric", "imperial"], }, showDetails: { type: "boolean", label: "Show Humidity & Wind", default: true, }, refreshIntervalValue: { type: "number", label: "Refresh Interval", default: 10, required: true, }, refreshIntervalUnit: { type: "select", label: "Unit", options: ["seconds", "minutes", "hours", "days"], default: "minutes", required: true, }, }, };