# Weather UI — Implementation Guide
## Weather card component
Render the weather data inside a Card component:
```tsx
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { useWeather } from "@/hooks/useWeather";
interface WeatherCardProps {
lat?: number;
lng?: number;
}
export default function WeatherCard({ lat, lng }: WeatherCardProps) {
const { data: weather, loading, error } = useWeather(lat, lng);
return (
Weather
{new Date().toLocaleDateString("en-US", {
weekday: "short",
month: "short",
day: "numeric",
year: "numeric",
})}
{loading && Loading weather…
}
{error && (
{error}
)}
{!loading && !error && weather && (
<>
{/* Current conditions */}
{weather.current.description}
{weather.current.tempF}°F
{weather.current.windSpeedMph} mph Wind
{weather.current.humidity}% Humidity
{/* Tab indicator */}
Today
{/* Hourly forecast */}
{weather.hourly.length > 0 && (
{weather.hourly.map((h) => (
))}
)}
>
)}
);
}
```
---
## Layout placement
### Dashboard sidebar
Place the weather card in a two-column grid alongside other dashboard content:
```tsx
{/* Primary dashboard content */}
```
### Full-width widget
For a standalone weather section:
```tsx
```
---
## Loading state
Show a text indicator while data is fetching:
```tsx
{loading && Loading weather…
}
```
For a richer skeleton:
```tsx
{loading && (
)}
```
---
## Error state
Show error messages with proper ARIA:
```tsx
{error && (
{error}
)}
```
---
## Extending to daily forecast
To show a multi-day forecast, update the `fetchWeather` function to request daily data:
```ts
url.searchParams.set("daily", "weather_code,temperature_2m_max,temperature_2m_min");
url.searchParams.set("forecast_days", "7");
```
Then render each day:
```tsx
{weather.daily.map((day) => (
{day.dayName}
{day.highF}° / {day.lowF}°
{day.description}
))}
```
---
## Using browser geolocation
To auto-detect the user's location:
```ts
import { useState, useEffect } from "react";
export function useUserLocation(): { lat: number | null; lng: number | null; error: string | null } {
const [lat, setLat] = useState(null);
const [lng, setLng] = useState(null);
const [error, setError] = useState(null);
useEffect(() => {
if (!navigator.geolocation) {
setError("Geolocation not supported");
return;
}
navigator.geolocation.getCurrentPosition(
(pos) => {
setLat(pos.coords.latitude);
setLng(pos.coords.longitude);
},
(err) => {
setError(err.message);
}
);
}, []);
return { lat, lng, error };
}
```
Combine with the weather hook:
```tsx
const { lat, lng } = useUserLocation();
const { data: weather } = useWeather(lat, lng);
```
Falls back to the default location if geolocation is denied or unavailable.
---
## Accessibility
- Error messages use `role="alert"` for screen reader announcement.
- Temperature values include the unit symbol (`°F` or `°C`) in the text.
- Hourly forecast items are visually distinct with background color and spacing.
- Loading state provides text feedback, not just spinners.