Skip to content

Commit 0e687af

Browse files
committed
feat: add weather-dashboard.jsx solution
1 parent 33df2b6 commit 0e687af

File tree

1 file changed

+121
-0
lines changed

1 file changed

+121
-0
lines changed

solutions/weather-dashboard.jsx

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import React, { useState } from "react"
2+
import { createRoot } from "react-dom/client"
3+
4+
const style = {
5+
marginTop: {
6+
marginTop: "10px",
7+
},
8+
marginRight: {
9+
marginRight: "10px",
10+
},
11+
}
12+
13+
const WeatherDashboard = () => {
14+
// instead of requesting data from an API, use this mock data
15+
const mockWeatherData = {
16+
"New York": {
17+
temperature: "22°C",
18+
humidity: "56%",
19+
windSpeed: "15 km/h",
20+
},
21+
"Los Angeles": {
22+
temperature: "27°C",
23+
humidity: "45%",
24+
windSpeed: "10 km/h",
25+
},
26+
London: {
27+
temperature: "15°C",
28+
humidity: "70%",
29+
windSpeed: "20 km/h",
30+
},
31+
}
32+
33+
const defaultWeather = {
34+
temperature: "",
35+
humidity: "",
36+
windSpeed: "",
37+
}
38+
39+
const [city, setCity] = useState("")
40+
const [cache, setCache] = useState({})
41+
const [notFound, setNotFound] = useState(false)
42+
const [previousSearches, setPreviousSearches] = useState([])
43+
const [weather, setWeather] = useState(defaultWeather)
44+
45+
const mockFetchWeatherData = city => {
46+
return new Promise((resolve, reject) => {
47+
setTimeout(() => {
48+
if (mockWeatherData[city]) {
49+
resolve(mockWeatherData[city])
50+
} else {
51+
reject(new Error("City not found."))
52+
setNotFound(true)
53+
setWeather(defaultWeather)
54+
}
55+
}, 500)
56+
})
57+
}
58+
59+
const search = async city => {
60+
setNotFound(false)
61+
62+
if (!city || city === "") {
63+
setWeather(defaultWeather)
64+
setNotFound(true)
65+
return
66+
}
67+
68+
if (cache[city]) {
69+
setWeather(cache[city])
70+
return
71+
}
72+
73+
try {
74+
const data = await mockFetchWeatherData(city)
75+
setCache({ ...cache, [city]: data })
76+
setWeather(data)
77+
setPreviousSearches([...previousSearches, city])
78+
} catch {
79+
throw new Error("Could not fetch weather data.")
80+
}
81+
}
82+
83+
return (
84+
<div>
85+
<input
86+
type="text"
87+
id="citySearch"
88+
placeholder="Search for a city..."
89+
value={city}
90+
onChange={e => setCity(e.target.value)}
91+
/>
92+
<button id="searchButton" onClick={() => search(city)}>
93+
Search
94+
</button>
95+
<div id="weatherData" style={style.marginTop}>
96+
<div>Temperature: {weather.temperature}</div>
97+
<div>Humidity: {weather.humidity}</div>
98+
<div>Wind Speed: {weather.windSpeed}</div>
99+
{notFound && <div style={style.marginTop}>City not found.</div>}
100+
</div>
101+
<div id="previousSearches" style={style.marginTop}>
102+
{previousSearches.length > 0 &&
103+
previousSearches.map((previousSearch, index) => (
104+
<button
105+
key={index}
106+
onClick={() => {
107+
setCity(previousSearch)
108+
search(previousSearch)
109+
}}
110+
style={style.marginRight}
111+
>
112+
{previousSearch}
113+
</button>
114+
))}
115+
</div>
116+
</div>
117+
)
118+
}
119+
120+
const root = createRoot(document.getElementById("root"))
121+
root.render(<WeatherDashboard />)

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy