// WeatherDashboard.jsx
import { useState, useEffect } from 'react'
function useFetch(url) {
const [state, setState] = useState({ data: null, loading: !!url, error: null })
useEffect(() => {
if (!url) return
let cancelled = false
setState({ data: null, loading: true, error: null })
fetch(url)
.then(r => r.ok ? r.json() : Promise.reject(new Error(`HTTP ${r.status}`)))
.then(data => !cancelled && setState({ data, loading: false, error: null }))
.catch(err => !cancelled && setState({ data: null, loading: false, error: err }))
return () => { cancelled = true }
}, [url])
return state
}
function WeatherCard({ data }) {
const wmo = { 0: "☀️ Clear", 1: "🌤 Mostly Clear", 2: "⛅ Partly Cloudy",
3: "☁️ Overcast", 51: "🌦 Drizzle", 61: "🌧 Rain", 80: "🌧 Showers" }
const icon = wmo[data.current.weather_code] ?? "🌡"
return (
<div className="weather-card">
<h2>{icon}</h2>
<p className="temp">{data.current.temperature_2m}°C</p>
<p>Wind: {data.current.wind_speed_10m} km/h</p>
<p>Humidity: {data.current.relative_humidity_2m}%</p>
</div>
)
}
const CITIES = [
{ name: "London", lat: 51.5074, lon: -0.1278 },
{ name: "New York", lat: 40.7128, lon: -74.0060 },
{ name: "Tokyo", lat: 35.6762, lon: 139.6503 },
]
function WeatherDashboard() {
const [city, setCity] = useState(CITIES[0])
const url = `https://api.open-meteo.com/v1/forecast`
+ `?latitude=${city.lat}&longitude=${city.lon}`
+ `¤t=temperature_2m,wind_speed_10m,weather_code,relative_humidity_2m`
const { data, loading, error } = useFetch(url)
return (
<div>
<h1>Weather Dashboard</h1>
<div>
{CITIES.map(c => (
<button key={c.name} onClick={() => setCity(c)}
style={{ fontWeight: city.name === c.name ? "bold" : "normal" }}>
{c.name}
</button>
))}
</div>
<h2>{city.name}</h2>
{loading && <p>Loading...</p>}
{error && <p>Error: {error.message}</p>}
{data && <WeatherCard data={data} />}
</div>
)
}
export default WeatherDashboard