Skip to content

Commit 6f15e0b

Browse files
author
Arghyadeep
committed
feat: enhance Weather component with badge display for forecast conditions and improve code formatting
1 parent 639ca1d commit 6f15e0b

1 file changed

Lines changed: 79 additions & 34 deletions

File tree

src/pages/Weather.jsx

Lines changed: 79 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,40 @@
1919
* - [ ] Animate background transitions
2020
* - [ ] Add geolocation: auto-detect user city (with permission)
2121
*/
22-
import { useEffect, useState } from 'react';
23-
import Loading from '../components/Loading.jsx';
24-
import ErrorMessage from '../components/ErrorMessage.jsx';
25-
import Card from '../components/Card.jsx';
26-
import { getWeatherData, clearWeatherCache, getCacheStats } from '../services/weather.js';
22+
import { useEffect, useState } from "react";
23+
import Loading from "../components/Loading.jsx";
24+
import ErrorMessage from "../components/ErrorMessage.jsx";
25+
import Card from "../components/Card.jsx";
26+
import {
27+
getWeatherData,
28+
clearWeatherCache,
29+
getCacheStats,
30+
} from "../services/weather.js";
2731

2832
export default function Weather() {
2933
const [city, setCity] = useState(() => {
30-
return localStorage.getItem('lastCity') || 'London';
34+
return localStorage.getItem("lastCity") || "London";
3135
});
3236
const [data, setData] = useState(null);
3337
const [loading, setLoading] = useState(false);
3438
const [error, setError] = useState(null);
35-
const [unit, setUnit] = useState('C'); // °C by default
39+
const [unit, setUnit] = useState("C"); // °C by default
3640

3741
useEffect(() => {
3842
fetchWeather(city);
3943
// eslint-disable-next-line react-hooks/exhaustive-deps
40-
}, []);
44+
}, []);
4145

4246
async function fetchWeather(c) {
4347
try {
4448
setLoading(true);
4549
setError(null);
4650

47-
const json = await getWeatherData(c);// Using the service instead of direct fetch
51+
const json = await getWeatherData(c); // Using the service instead of direct fetch
4852
setData(json);
4953

5054
// Save the searched city to localStorage
51-
localStorage.setItem('lastCity', c);
55+
localStorage.setItem("lastCity", c);
5256
} catch (e) {
5357
setError(e);
5458
} finally {
@@ -71,15 +75,28 @@ export default function Weather() {
7175
// Helper function to show cache stats (for development)
7276
const handleShowCacheStats = () => {
7377
const stats = getCacheStats();
74-
console.log('Cache Statistics:', stats);
78+
console.log("Cache Statistics:", stats);
7579
alert(`Cache has ${stats.size} entries. Check console for details.`);
7680
};
7781

7882
const current = data?.current_condition?.[0];
7983
const forecast = data?.weather?.slice(0, 3) || [];
8084

8185
// Helper to convert °C to °F
82-
const displayTemp = (c) => (unit === 'C' ? c : Math.round((c * 9) / 5 + 32));
86+
const displayTemp = (c) => (unit === "C" ? c : Math.round((c * 9) / 5 + 32));
87+
88+
const getBadgeStyle = (condition) => {
89+
if (!condition) return { color: "#E0E0E0", label: "Clear 🌤️" };
90+
91+
const desc = condition.toLowerCase();
92+
if (desc.includes("sun")) return { color: "#FFD54F", label: "Sunny ☀️" };
93+
if (desc.includes("rain")) return { color: "#4FC3F7", label: "Rainy 🌧️" };
94+
if (desc.includes("snow")) return { color: "#81D4FA", label: "Snowy ❄️" };
95+
if (desc.includes("cloud")) return { color: "#B0BEC5", label: "Cloudy ☁️" };
96+
if (desc.includes("storm") || desc.includes("thunder"))
97+
return { color: "#9575CD", label: "Storm ⛈️" };
98+
return { color: "#E0E0E0", label: "Clear 🌤️" };
99+
};
83100

84101
return (
85102
<div className="dashboard-page">
@@ -96,32 +113,38 @@ export default function Weather() {
96113
</form>
97114

98115
{/* Development tools - you can remove these later */}
99-
<div style={{ marginTop: '10px', display: 'flex', gap: '10px' }}>
100-
<button onClick={handleClearCache} style={{ fontSize: '12px' }}>
116+
<div style={{ marginTop: "10px", display: "flex", gap: "10px" }}>
117+
<button onClick={handleClearCache} style={{ fontSize: "12px" }}>
101118
Clear Cache
102119
</button>
103-
<button onClick={handleShowCacheStats} style={{ fontSize: '12px' }}>
120+
<button onClick={handleShowCacheStats} style={{ fontSize: "12px" }}>
104121
Cache Stats
105122
</button>
106123
<button
107-
onClick={() => setUnit(unit === 'C' ? 'F' : 'C')}
108-
style={{ fontSize: '12px' }}
124+
onClick={() => setUnit(unit === "C" ? "F" : "C")}
125+
style={{ fontSize: "12px" }}
109126
>
110-
Switch to °{unit === 'C' ? 'F' : 'C'}
127+
Switch to °{unit === "C" ? "F" : "C"}
111128
</button>
112129
</div>
113130
</div>
114131

115132
{loading && <Loading />}
116-
{error && <ErrorMessage message={error.message} onRetry={() => fetchWeather(city)} />}
133+
{error && (
134+
<ErrorMessage
135+
message={error.message}
136+
onRetry={() => fetchWeather(city)}
137+
/>
138+
)}
117139

118140
{data && !loading && (
119141
<div className="dashboard-grid">
120142
{/* Current Weather */}
121143
<Card title="Current Weather" size="large">
122144
<h2>{data.nearest_area?.[0]?.areaName?.[0]?.value || city}</h2>
123145
<p>
124-
<strong>Temperature:</strong> {displayTemp(Number(current.temp_C))}°{unit}
146+
<strong>Temperature:</strong>{" "}
147+
{displayTemp(Number(current.temp_C))}°{unit}
125148
</p>
126149
<p>
127150
<strong>Humidity:</strong> {current.humidity}%
@@ -132,22 +155,44 @@ export default function Weather() {
132155
</Card>
133156

134157
{/* 3-Day Forecast */}
135-
{forecast.map((day, i) => (
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>
146-
</Card>
147-
))}
158+
{forecast.map((day, i) => {
159+
const condition =
160+
day.hourly?.[0]?.weatherDesc?.[0]?.value || "Clear";
161+
const badge = getBadgeStyle(condition);
162+
163+
return (
164+
<Card key={i} title={i === 0 ? "Today" : `Day ${i + 1}`}>
165+
{/* Badge Section */}
166+
<div
167+
style={{
168+
backgroundColor: badge.color,
169+
borderRadius: "8px",
170+
padding: "4px 8px",
171+
display: "inline-block",
172+
fontSize: "12px",
173+
fontWeight: "bold",
174+
marginBottom: "8px",
175+
color: "#333",
176+
}}
177+
>
178+
{badge.label}
179+
</div>
180+
181+
<p>
182+
<strong>Avg Temp:</strong> {displayTemp(Number(day.avgtempC))}
183+
°{unit}
184+
</p>
185+
<p>
186+
<strong>Sunrise:</strong> {day.astronomy?.[0]?.sunrise}
187+
</p>
188+
<p>
189+
<strong>Sunset:</strong> {day.astronomy?.[0]?.sunset}
190+
</p>
191+
</Card>
192+
);
193+
})}
148194
</div>
149195
)}
150196
</div>
151197
);
152198
}
153-

0 commit comments

Comments
 (0)