Skip to content

Instantly share code, notes, and snippets.

@ac205
Last active November 24, 2019 16:43
Show Gist options
  • Save ac205/1f560ade4becca692587ed7dd94b77ab to your computer and use it in GitHub Desktop.
Save ac205/1f560ade4becca692587ed7dd94b77ab to your computer and use it in GitHub Desktop.
Weather App
#weatherContainer {
text-align: center;
}
#weatherCard {
text-align: center;
margin: 50px auto;
width: 100%;
}
#desc {
text-transform: capitalize;
}
import React, { useState } from 'react';
import './App.css';
import SearchBox from './components/SearchBox'
import TitleBar from './components/TitleBar';
import WeatherCard from './components/WeatherCard';
function App() {
const [ weatherData, setWeatherData ] = useState();
const [ currentCity, setCurrentCity ] = useState();
const [ weatherLoaded, setWeatherLoaded ] = useState(false);
const [ unit, setUnit ] = useState('metric');
const [ error, setError ] = useState();
const Fetch = async () => {
const url =
'https://api.openweathermap.org/data/2.5/weather?q=' +
currentCity +
',ca&appid=5fe2845ad0de56c34e739ea3cfda57b2&units=metric';
const response = await fetch(url);
const data = await response.json();
setWeatherData(data);
document.getElementById('city').value = '';
if (data.message) {
console.log(data.message);
setError(data.message);
} else {
setError();
return setWeatherLoaded(true);
}
};
const handleChange = () => {
let city = document.getElementById('city').value;
setCurrentCity(city);
};
const handleFetch = () => {
setWeatherLoaded(false);
Fetch();
};
return (
<div id="weatherContainer">
<TitleBar unit={unit} setUnit={setUnit} />
<SearchBox handleFetch={handleFetch} handleChange={handleChange} error={error} />
<WeatherCard weatherData={weatherData} unit={unit} weatherLoaded={weatherLoaded} />
</div>
);
}
export default App;
import React from 'react';
import { makeStyles } from '@material-ui/core/styles';
import Button from '@material-ui/core/Button';
import TextField from '@material-ui/core/TextField';
const useStyles = makeStyles((theme) => ({
container: {
display: 'flex',
flexWrap: 'wrap'
},
textField: {
marginLeft: theme.spacing(1),
marginRight: theme.spacing(1),
width: 200
}
}));
const SearchBox = ({ handleChange, handleFetch, error }) => {
const classes = useStyles();
return (
<div>
<TextField
id="city"
label="Enter City"
margin="normal"
className={classes.textField}
onChange={handleChange}
/>
<br />
{error ? <h6> {error} </h6> : null}
<Button onClick={handleFetch} variant="contained" color="primary" style={{ margin: 20 }}>
Get Weather
</Button>
</div>
);
};
export default SearchBox;
import React from 'react';
import AppBar from '@material-ui/core/AppBar';
import Toolbar from '@material-ui/core/Toolbar';
import Switch from '@material-ui/core/Switch';
import Typography from '@material-ui/core/Typography';
const TitleBar = ({ setUnit, unit }) => {
const handleSwitch = () => {
unit === 'metric' ? setUnit('imperial') : setUnit('metric');
};
return (
<AppBar position="static">
<Toolbar>
<Typography style={{flexGrow : 1}} variant="h6">
Weather App
</Typography>
<Switch onChange={handleSwitch} color="default" />F
</Toolbar>
</AppBar>
);
};
export default TitleBar;
import React from 'react';
import Typography from '@material-ui/core/Typography';
import Card from '@material-ui/core/Card';
import CardActionArea from '@material-ui/core/CardActionArea';
import CardActions from '@material-ui/core/CardActions';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
const WeatherCard = ({ weatherData, weatherLoaded, unit }) => {
return (
<div>
{weatherLoaded ? (
<div>
<Card id="weatherCard" style={{ maxWidth: 345 }}>
<CardActionArea>
<CardContent>
<Typography gutterBottom variant="h5" component="h2">
<h2>{weatherData.name}</h2>
{new Date(weatherData.dt * 1000).toLocaleString('en-US', { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', hour12: true })}
</Typography>
</CardContent>
<CardMedia
image={'http://openweathermap.org/img/wn/' + weatherData.weather[0].icon + '.png'}
title="weatherIcon"
style={{
height: 75,
width: 75,
margin: 'auto',
backgroundColor: 'gray',
borderRadius: 15
}}
/>
<CardContent>
<Typography gutterBottom variant="h5" component="h2" id="desc">
{weatherData.weather[0].description}
</Typography>
<Typography variant="body2" color="textSecondary" component="h3">
{unit === 'metric' ? (
<h2>{weatherData.main.temp.toFixed(1)} &deg; C </h2>
) : (
<h2>{(weatherData.main.temp * 1.8 + 32).toFixed(1)} &deg; F</h2>
)}
</Typography>
</CardContent>
</CardActionArea>
<CardActions />
</Card>
</div>
) : null}
</div>
);
};
export default WeatherCard;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment