'use client' import { useEffect, useState, useCallback } from 'react' import { MapPin } from 'lucide-react' import { getCurrentWeather, setWeatherLocation, setLocationHint, getTempUnit, formatTemperature, type CurrentWeather, type TempUnit, } from '@/lib/weatherApi' interface WeatherWidgetProps { /** Compact mode for inline display (e.g., next to time) */ compact?: boolean /** Callback when location is successfully set */ onLocationSet?: () => void } export function WeatherWidget({ compact = false, onLocationSet }: WeatherWidgetProps) { const [weather, setWeather] = useState(null) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) const [needsLocation, setNeedsLocation] = useState(false) const [tempUnit, setTempUnitState] = useState('F') // Load temp unit from localStorage on mount useEffect(() => { setTempUnitState(getTempUnit()) }, []) // City input state const [cityInput, setCityInput] = useState('') const [saving, setSaving] = useState(false) const [saveError, setSaveError] = useState(null) const fetchWeather = useCallback(async () => { setLoading(true) setError(null) try { const data = await getCurrentWeather() if (data === null) { // No location set or API issue - prompt for location setNeedsLocation(true) setWeather(null) } else { setWeather(data) setNeedsLocation(false) setLocationHint(true) } } catch { // On any error, show location input instead of error message setNeedsLocation(true) setWeather(null) } finally { setLoading(false) } }, []) useEffect(() => { fetchWeather() }, [fetchWeather]) const handleSetLocation = async (e: React.FormEvent) => { e.preventDefault() if (!cityInput.trim()) return setSaving(true) setSaveError(null) try { await setWeatherLocation(cityInput.trim()) setLocationHint(true) setCityInput('') await fetchWeather() onLocationSet?.() } catch (err) { setSaveError(err instanceof Error ? err.message : 'Failed to set location') } finally { setSaving(false) } } // Loading state if (loading) { if (compact) { return (
) } return (
) } // Needs location input if (needsLocation) { if (compact) { return (
setCityInput(e.target.value)} placeholder="Enter city" disabled={saving} className="border border-border bg-input text-foreground text-xs px-2 py-1 w-24" /> {saveError && {saveError}} ) } return (
Set your weather location
setCityInput(e.target.value)} placeholder="Enter your city" disabled={saving} className="flex-1 border border-border bg-input text-foreground text-sm px-3 py-1.5" />
{saveError && (
{saveError}
)}
) } // Weather display if (weather) { if (compact) { // Two-line display: white text above (temp + city), grey text below (description) return (
{formatTemperature(weather.temperatureF, tempUnit)}
{weather.city} - {weather.description}
) } return (
{weather.city}
{formatTemperature(weather.temperatureF, tempUnit)}
{weather.description}
) } return null }