Skip to content
This repository has been archived by the owner on Nov 11, 2022. It is now read-only.

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurenceHo committed Sep 6, 2017
0 parents commit 81f88a9
Show file tree
Hide file tree
Showing 14 changed files with 7,352 additions and 0 deletions.
18 changes: 18 additions & 0 deletions app/api/openWeatherMap.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import axios from 'axios';

const OPEN_WEATHER_MAP_URL = 'http://api.openweathermap.org/data/2.5/weather?appid=c4e735ea8bd7e7b6dc8368c752517b2d&units=imperial';

export const getTemp = (location) => {
const encodedLocation = encodeURIComponent (location);
const requestUrl = `${OPEN_WEATHER_MAP_URL}&q=${encodedLocation}`;

return axios.get (requestUrl).then ((res) => {
if ( res.data.cod && res.data.message ) {
throw new Error (res.data.message);
} else {
return res.data.main.temp;
}
}, (res) => {
throw new Error (res.data.message);
});
};
27 changes: 27 additions & 0 deletions app/components/About.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import React from 'react';

export const About = () => {
return (
<div>
<h1 className="text-center">About</h1>
<p>
This is a weather application build on React. I have built this
for The Complete React Web App Developer Course.
</p>
<p>
Here are some of the tools I used:
</p>
<ul>
<li>
<a href="https://facebook.github.io/react">React</a> - This was the
JavaScript framework used.
</li>
<li>
<a href="http://openweathermap.org">Open Weather Map</a> - I used
Open Weather Map to search for weather data by city name.
</li>
</ul>
</div>

)
};
26 changes: 26 additions & 0 deletions app/components/App.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import { Nav } from './Nav';
import { Main } from './Main';
import { About } from './About';
import { Examples } from './Examples';

export class App extends React.Component {
render () {
return (
<Router>
<div>
<Nav/>
<Switch>
<Route exact path='/' component={Main}/>
<Route path='/about' component={About}/>
<Route path='/examples' component={Examples}/>
<Route render={() => {
return <p> Not found!!</p>
}}/>
</Switch>
</div>
</Router>
);
}
}
20 changes: 20 additions & 0 deletions app/components/Examples.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { NavLink } from 'react-router-dom';

export const Examples = () => {
return (
<div>
<h1 className="text-center">Examples</h1>
<p>Here are a few example locations to try out:</p>
<ol>
<li>
<NavLink to='/?location=Philadelphia'>Philadelphia, PA</NavLink>
</li>
<li>
<NavLink to='/?location=Rio'>Rio, Brazil</NavLink>
</li>
</ol>
</div>

)
};
14 changes: 14 additions & 0 deletions app/components/Main.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import React from 'react';
import { Weather } from './Weather';

export const Main = () => {
return (
<div>
<div className="row">
<div className="columns medium-6 large-4 small-centered">
<Weather/>
</div>
</div>
</div>
);
};
58 changes: 58 additions & 0 deletions app/components/Nav.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import React from 'react';
import { NavLink } from 'react-router-dom';

export class Nav extends React.Component {
constructor (props) {
super (props);

this.state = {
location: ''
};

this.handleSubmit = this.handleSubmit.bind (this);
}

handleSubmit (event) {
event.preventDefault ();
// TODO
};

render () {
return (
<div className="top-bar">
<div className="top-bar-left">
<ul className="menu">
<li className="menu-text">React Weather App</li>
<li>
<NavLink exact activeClassName='active' to='/'>
Get Weather
</NavLink>
</li>
<li>
<NavLink activeClassName='active' to='/about'>
About
</NavLink>
</li>
<li>
<NavLink activeClassName='active' to='/examples'>
Examples
</NavLink>
</li>
<div className="top-bar-right">
<form onSubmit={this.handleSubmit}>
<ul className="menu">
<li>
<input type="search" placeholder="Search weather"/>
</li>
<li>
<input type="submit" className="button" value="Get Weather"/>
</li>
</ul>
</form>
</div>
</ul>
</div>
</div>
);
}
}
48 changes: 48 additions & 0 deletions app/components/Weather.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { WeatherMessage } from './WeatherMessage';
import { WeatherForm } from './WeatherForm';
import { getTemp } from '../api/openWeatherMap';

export class Weather extends React.Component {
constructor (props) {
super (props);
this.state = {
isLoading: false
};

this.handleSearch = this.handleSearch.bind (this);
}

handleSearch (location) {
this.setState ({ isLoading: true });

getTemp (location).then ((temp) => {
this.setState ({
location: location,
temp: temp,
isLoading: false
});
}, (errorMessage) => {
this.setState ({ isLoading: false });
alert (errorMessage);
});
}

render () {
const renderMessage = () => {
if ( this.state.isLoading ) {
return <h3 className="text-center">Fetching weather...</h3>;
} else if ( this.state.temp && this.state.location ) {
return <WeatherMessage temp={this.state.temp} location={this.state.location}/>;
}
};

return (
<div>
<h1 className="text-center">Get Weather</h1>
<WeatherForm onSearch={this.handleSearch}/>
{renderMessage ()}
</div>
)
}
}
53 changes: 53 additions & 0 deletions app/components/WeatherForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import React from 'react';
import PropTypes from 'prop-types';

export class WeatherForm extends React.Component {
constructor (props) {
super (props);

this.state = {
location: ''
};

this.handleChange = this.handleChange.bind (this);
this.handleSubmit = this.handleSubmit.bind (this);
}

handleChange (event) {
const value = event.target.value;

this.setState (() => {
return {
location: value
}
})
}

handleSubmit (event) {
event.preventDefault ();

this.props.onSearch (
this.state.location
)
};

render () {
return (
<div>
<form onSubmit={this.handleSubmit}>
<input
type='text'
value={this.state.location}
onChange={this.handleChange}
placeholder="Search weather"
/>
<button className="button expanded hollow">Get Weather</button>
</form>
</div>
);
}
}

WeatherForm.PropTypes = {
onSearch: PropTypes.func.isRequired
};
15 changes: 15 additions & 0 deletions app/components/WeatherMessage.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';

export const WeatherMessage = (props) => {
const temperature = Math.round (((props.temp - 32) * 5 / 9) * 10) / 10;

return (
<h3 className="text-center">It's {temperature} ℃ in {props.location}.</h3>
)
};

WeatherMessage.PropTypes = {
temp: PropTypes.string.isRequired,
location: PropTypes.string.isRequired
};
10 changes: 10 additions & 0 deletions app/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
</head>

<body>
<div id="app"></div>
</body>
</html>
11 changes: 11 additions & 0 deletions app/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React from 'react';
import ReactDOM from 'react-dom';
import { App } from "./components/app";
import 'jquery/dist/jquery';
import 'foundation-sites/dist/css/foundation.css';
import 'foundation-sites/dist/js/foundation.min';

ReactDOM.render (
<App/>,
document.getElementById ('app')
);
Loading

0 comments on commit 81f88a9

Please sign in to comment.