React Weather Practice
by YangHax
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.0.5/redux.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-redux/7.2.0/react-redux.min.js"></script>
<div id="app"></div>
<!--
• Build form control with the following. Label : “Enter City”, Input form field, Submit Button. Button should be custom built and re-usable.
• Build weather details component. It should show the current Date, City Name, Current time & temperature details. “Begin with Static Data and later bind with JSON dynamic data”
• Retrieve weather data from JSON service (API). Use Redux Store for the Data management. Parse the content to respective UI components.
• Weather Details should be updated based on the City name entered in the form control.
• Build “5 Day Weather” Button by re-using the button component which was created earlier.
• Implement new page which shows 5 day weather Details. Create an event to “5 Day Weather” button to take to 5 Day weather details page.
• Enhance Weather details UI component. Component should be divided into 3 small re-usable components. Date Display, City & current time, Temperature. Show the Visual screen to the candidate
• 5 Day Weather details page should contain a data grid which shows the 5 day weather info. Temperature component should be reused and rendered in each cell. Show the visual design to the candidate.
-->
<script type="text/javascript">
const data = {
"States": {
"IL": {
"currentdate": "04/05/2019",
"time": "02:59 PM",
"cities": [{
"name": "Chicago",
"forecast": [{
"Date": "04/05/2019",
"Time": "2.59pm",
"temprature": 47,
"feels": 40
},
{
"Date": "04/06/2019",
"Time": "2.59pm",
"temprature": 57,
"feels": 55
},
{
"Date": "04/07/2019",
"Time": "2.59pm",
"temprature": 45,
"feels": 44
},
{
"Date": "04/08/2019",
"Time": "2.59pm",
"temprature":...
CSS
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
.done {
color: rgba(0, 0, 0, 0.3);
text-decoration: line-through;
}
input {
margin-right: 5px;
}
.date-card {
display: inline-block;
background: #4caf50;
margin: 5px;
padding: 5px;
box-shadow: gray 1px 2px 4px;
}
React
class WeatherApp extends React.Component {
constructor(props) {
super(props)
this.state = {
city: undefined,
hasSearched: false
}
}
render() {
return (
<div>
<h2>Weather App</h2>
<input
ref="cityInput"
placeholder="Enter City"
onKeyDown={e => e.key === 'Enter' && this.onSubmit()}
/>
<WeatherButton onSubmit={_ => this.onSubmit()} />
{this.state.hasSearched && !this.state.city ? <div>City not found</div> : null}
{this.state.city ? <WeatherDetails city={this.state.city} /> : null}
</div>
)
}
onSubmit() {
this.setState({ hasSearched: true });
const cityName = this.refs.cityInput.value;
if (cityName) this.setState({ city: this.findCity(cityName) });
}
findCity(name) {
const mathcRegExp = new RegExp(`^${name}$`,'i');
let foundCity = null;
for (let iState in data.States ) {
data.States[iState].cities.forEach(city => {
if (city.name.match(mathcRegExp)) {
foundCity = city;
return false;
}
});
}
return foundCity;
}
}
const WeatherButton = props => (
<input type="submit"
onClick={_ => props.onSubmit()}
/>);
class WeatherDetails extends React.Component {
render() {
return (
<div>
Weather data for <b>{this.props.city.name}</b>:
{this.props.city.forecast.map((forecast,i) =>
<WeatherDayCard
key={i}
Date={forecast.Date}
Time={forecast.Time}
temprature={forecast.temprature}
feels={forecast.feels}
/>)}
</div>
);
}
}
const WeatherDayCard = props => (
<div className="date-card">
<div>Date: {props.Date}</div>
<div>Current Time: {props.Time}</div>
<div>Currently {props.temprature} F / Feels {props.feels} F </div>
</div>
);
ReactDOM.render(<WeatherApp />, document.querySelector("#app"))