1919 * - [ ] Animate background transitions
2020 * - [ ] Add geolocation: auto-detect user city (with permission)
2121 */
22-
2322import { useEffect , useState } from 'react' ;
2423import Loading from '../components/Loading.jsx' ;
2524import ErrorMessage from '../components/ErrorMessage.jsx' ;
2625import Card from '../components/Card.jsx' ;
2726import { getWeatherData , clearWeatherCache , getCacheStats } from '../services/weather.js' ;
2827
2928export 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