Skip to content

Commit c855f98

Browse files
author
Arghyadeep
committed
feat: persist last searched city in localStorage and refactor form submission
1 parent e6af903 commit c855f98

File tree

1 file changed

+50
-23
lines changed

1 file changed

+50
-23
lines changed

src/pages/Weather.jsx

Lines changed: 50 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@
1919
* - [ ] Animate background transitions
2020
* - [ ] Add geolocation: auto-detect user city (with permission)
2121
*/
22-
2322
import { useEffect, useState } from 'react';
2423
import Loading from '../components/Loading.jsx';
2524
import ErrorMessage from '../components/ErrorMessage.jsx';
2625
import Card from '../components/Card.jsx';
2726
import { getWeatherData, clearWeatherCache, getCacheStats } from '../services/weather.js';
2827

2928
export default function Weather() {
30-
const [city, setCity] = useState('London');
29+
const [city, setCity] = useState(() => {
30+
return localStorage.getItem('lastCity') || 'London';
31+
});
3132
const [data, setData] = useState(null);
3233
const [loading, setLoading] = useState(false);
3334
const [error, setError] = useState(null);
@@ -36,21 +37,31 @@ export default function Weather() {
3637
useEffect(() => {
3738
fetchWeather(city);
3839
// eslint-disable-next-line react-hooks/exhaustive-deps
39-
}, []);
40+
}, []);
4041

4142
async function fetchWeather(c) {
4243
try {
4344
setLoading(true);
4445
setError(null);
45-
const json = await getWeatherData(c); // Using the service instead of direct fetch
46+
47+
const json = await getWeatherData(c);// Using the service instead of direct fetch
4648
setData(json);
49+
50+
// Save the searched city to localStorage
51+
localStorage.setItem('lastCity', c);
4752
} catch (e) {
4853
setError(e);
4954
} finally {
5055
setLoading(false);
5156
}
5257
}
5358

59+
const handleSubmit = (e) => {
60+
e.preventDefault();
61+
if (!city.trim()) return;
62+
fetchWeather(city);
63+
};
64+
5465
// Helper function to clear cache and refetch (for testing)
5566
const handleClearCache = () => {
5667
clearWeatherCache();
@@ -65,34 +76,37 @@ export default function Weather() {
6576
};
6677

6778
const current = data?.current_condition?.[0];
68-
const forecast = data?.weather?.slice(0,3) || [];
79+
const forecast = data?.weather?.slice(0, 3) || [];
6980

7081
// Helper to convert °C to °F
71-
const displayTemp = (c) => unit === 'C' ? c : Math.round((c * 9/5) + 32);
82+
const displayTemp = (c) => (unit === 'C' ? c : Math.round((c * 9) / 5 + 32));
7283

7384
return (
7485
<div className="dashboard-page">
7586
<div className="dashboard-header">
7687
<h1>🌤️ Weather Dashboard</h1>
77-
<form onSubmit={(e) => {e.preventDefault(); fetchWeather(city)}}>
78-
<input
79-
type="text"
80-
value={city}
88+
<form onSubmit={handleSubmit}>
89+
<input
90+
type="text"
91+
value={city}
8192
onChange={(e) => setCity(e.target.value)}
82-
placeholder="Enter city name..."
93+
placeholder="Enter city name..."
8394
/>
8495
<button type="submit">Get Weather</button>
8596
</form>
86-
97+
8798
{/* Development tools - you can remove these later */}
88-
<div style={{marginTop: '10px', display: 'flex', gap: '10px'}}>
89-
<button onClick={handleClearCache} style={{fontSize: '12px'}}>
99+
<div style={{ marginTop: '10px', display: 'flex', gap: '10px' }}>
100+
<button onClick={handleClearCache} style={{ fontSize: '12px' }}>
90101
Clear Cache
91102
</button>
92-
<button onClick={handleShowCacheStats} style={{fontSize: '12px'}}>
103+
<button onClick={handleShowCacheStats} style={{ fontSize: '12px' }}>
93104
Cache Stats
94105
</button>
95-
<button onClick={() => setUnit(unit === 'C' ? 'F' : 'C')} style={{fontSize: '12px'}}>
106+
<button
107+
onClick={() => setUnit(unit === 'C' ? 'F' : 'C')}
108+
style={{ fontSize: '12px' }}
109+
>
96110
Switch to °{unit === 'C' ? 'F' : 'C'}
97111
</button>
98112
</div>
@@ -106,21 +120,34 @@ export default function Weather() {
106120
{/* Current Weather */}
107121
<Card title="Current Weather" size="large">
108122
<h2>{data.nearest_area?.[0]?.areaName?.[0]?.value || city}</h2>
109-
<p><strong>Temperature:</strong> {displayTemp(Number(current.temp_C))}°{unit}</p>
110-
<p><strong>Humidity:</strong> {current.humidity}%</p>
111-
<p><strong>Desc:</strong> {current.weatherDesc?.[0]?.value}</p>
123+
<p>
124+
<strong>Temperature:</strong> {displayTemp(Number(current.temp_C))}°{unit}
125+
</p>
126+
<p>
127+
<strong>Humidity:</strong> {current.humidity}%
128+
</p>
129+
<p>
130+
<strong>Desc:</strong> {current.weatherDesc?.[0]?.value}
131+
</p>
112132
</Card>
113133

114134
{/* 3-Day Forecast */}
115135
{forecast.map((day, i) => (
116-
<Card key={i} title={i === 0 ? 'Today' : `Day ${i+1}`}>
117-
<p><strong>Avg Temp:</strong> {displayTemp(Number(day.avgtempC))}°{unit}</p>
118-
<p><strong>Sunrise:</strong> {day.astronomy?.[0]?.sunrise}</p>
119-
<p><strong>Sunset:</strong> {day.astronomy?.[0]?.sunset}</p>
136+
<Card key={i} title={i === 0 ? 'Today' : `Day ${i + 1}`}>
137+
<p>
138+
<strong>Avg Temp:</strong> {displayTemp(Number(day.avgtempC))}°{unit}
139+
</p>
140+
<p>
141+
<strong>Sunrise:</strong> {day.astronomy?.[0]?.sunrise}
142+
</p>
143+
<p>
144+
<strong>Sunset:</strong> {day.astronomy?.[0]?.sunset}
145+
</p>
120146
</Card>
121147
))}
122148
</div>
123149
)}
124150
</div>
125151
);
126152
}
153+

0 commit comments

Comments
 (0)