/* WeatherMate — search / city manager */ function MiniWeather({ city, unit, active, onSelect, onRemove, removable }) { const [info, setInfo] = React.useState(null); React.useEffect(() => { let alive = true; WX.fetchWeather(city.lat, city.lon) .then(d => { if (alive) setInfo(d); }) .catch(() => { if (alive) setInfo(null); }); return () => { alive = false; }; }, [city.lat, city.lon]); const cond = info ? WX.conditionOf(info.current.code) : "cloudy"; const isDay = info ? info.current.isDay : true; const theme = WX.themeFor(cond, isDay); return ( ); } function SearchScreen({ saved, activeId, unit, onSelect, onAdd, onRemove, onClose }) { const [q, setQ] = React.useState(""); const [results, setResults] = React.useState([]); const [busy, setBusy] = React.useState(false); const tRef = React.useRef(null); React.useEffect(() => { if (tRef.current) clearTimeout(tRef.current); if (q.trim().length < 2) { setResults([]); setBusy(false); return; } setBusy(true); tRef.current = setTimeout(() => { WX.geocode(q.trim()) .then(r => setResults(r)) .catch(() => setResults([])) .finally(() => setBusy(false)); }, 350); return () => tRef.current && clearTimeout(tRef.current); }, [q]); return (

Weather

setQ(e.target.value)} /> {q && }
{q.trim().length >= 2 ? (
{busy &&
Searching…
} {!busy && results.length === 0 &&
No matches for “{q}”.
} {results.map(r => ( ))}
) : (
{saved.map(c => ( 1} /> ))}
Search to add more cities. Tap a city to view its full forecast.
)}
); } window.SearchScreen = SearchScreen;