From 2c293bd5ed1b7cab04f9fec07258ee7b849df3b4 Mon Sep 17 00:00:00 2001 From: Andrew Lemons Date: Sun, 6 Apr 2025 15:32:50 -0400 Subject: [PATCH] add weather alerts --- src/Dashboard.jsx | 2 ++ src/components/WeatherAlerts.jsx | 47 ++++++++++++++++++++++++++++++++ src/hooks/useWeatherAlerts.jsx | 36 ++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 src/components/WeatherAlerts.jsx create mode 100644 src/hooks/useWeatherAlerts.jsx diff --git a/src/Dashboard.jsx b/src/Dashboard.jsx index 6781291..42c3387 100644 --- a/src/Dashboard.jsx +++ b/src/Dashboard.jsx @@ -4,6 +4,7 @@ import Config from "./components/Config"; import Music from "./components/Music"; import Notices from "./components/Notices"; import SpaceInfo from "./components/SpaceInfo"; +import WeatherAlerts from "./components/WeatherAlerts"; import useSpotify from "./hooks/useSpotify"; import useTime from "./hooks/useTime"; @@ -40,6 +41,7 @@ export default function Dashboard({}) { height="100%" maxHeight="100%" > */} + diff --git a/src/components/WeatherAlerts.jsx b/src/components/WeatherAlerts.jsx new file mode 100644 index 0000000..58ab974 --- /dev/null +++ b/src/components/WeatherAlerts.jsx @@ -0,0 +1,47 @@ +import React from 'react'; +import useWeatherAlerts from '../hooks/useWeatherAlerts'; +import { Box } from "@radix-ui/themes"; +import { useState, useEffect } from 'react'; +import { AnimatePresence, motion } from "motion/react"; + +const WeatherAlerts = () => { + const { alerts } = useWeatherAlerts(); + + const [currentAlertIndex, setCurrentAlertIndex] = useState(0); + + useEffect(() => { + const interval = setInterval(() => { + setCurrentAlertIndex((prevIndex) => (prevIndex + 1) % alerts.length); + }, 10000); + + return () => clearInterval(interval); + }, [alerts.length]); + + if (!alerts || alerts.length === 0) { + return null; + } + + return ( + + + + + {alerts[currentAlertIndex].properties.event} until {new Date(alerts[currentAlertIndex].properties.expires).toLocaleTimeString([], { hour: 'numeric', minute: '2-digit' })} + + + + + ); +}; + +export default WeatherAlerts; \ No newline at end of file diff --git a/src/hooks/useWeatherAlerts.jsx b/src/hooks/useWeatherAlerts.jsx new file mode 100644 index 0000000..118a68b --- /dev/null +++ b/src/hooks/useWeatherAlerts.jsx @@ -0,0 +1,36 @@ +import { useState, useEffect } from 'react'; + +export default function useWeatherAlerts() { + const [alerts, setAlerts] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + const fetchWeatherAlerts = async () => { + try { + setLoading(true); + const response = await fetch( + `https://api.weather.gov/alerts/active/zone/GAC121` + ); + + if (!response.ok) { + throw new Error('Failed to fetch weather alerts'); + } + + const data = await response.json(); + setAlerts(data.features || []); + } catch (err) { + setError(err.message); + } finally { + setLoading(false); + } + }; + + fetchWeatherAlerts(); + + const interval = setInterval(fetchWeatherAlerts, 60000); // Refresh every 60 seconds + return () => clearInterval(interval); + }, []); + + return { alerts, loading, error }; +};