SHARE
TWEET

Untitled

a guest Feb 27th, 2020 78 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React, { Fragment } from 'react';
  2. import WeatherAppContainer from './WeatherAppContainer';
  3. import Typography from '@material-ui/core/Typography';
  4. import Grid from '@material-ui/core/Grid';
  5. import Box from '@material-ui/core/Box';
  6.  
  7. const App = () => {
  8.   return (
  9.     <Fragment>
  10.       <Box pb={5} pt={3} color='primary.main'>
  11.         <Grid container justify='center'>
  12.           <Typography variant='h4'>React Weather</Typography>
  13.         </Grid>
  14.       </Box>
  15.       <Box color='text.secondary'>
  16.         <WeatherAppContainer />
  17.       </Box>
  18.     </Fragment>
  19.   );
  20. };
  21.  
  22. export default App;
  23.  
  24. /////////////////////////////
  25.  
  26. import React, { useState } from 'react';
  27. import Button from '@material-ui/core/Button';
  28. import TextField from '@material-ui/core/TextField';
  29. import SearchIcon from '@material-ui/icons/Search';
  30. import Grid from '@material-ui/core/Grid';
  31. import Box from '@material-ui/core/Box';
  32.  
  33. const Search = ({ onSubmit }) => {
  34.   const [userQuery, setUserQuery] = useState('');
  35.  
  36.   const handleChange = event => {
  37.     setUserQuery(event.target.value);
  38.   };
  39.  
  40.   const handleSubmit = event => {
  41.     event.preventDefault();
  42.     onSubmit(userQuery);
  43.   };
  44.  
  45.   return (
  46.     <Box pb={5}>
  47.       <Grid container justify='center'>
  48.         <form onSubmit={handleSubmit}>
  49.           <TextField
  50.             type='text'
  51.             onChange={handleChange}
  52.             value={userQuery}
  53.             label='Enter a City'
  54.           />
  55.  
  56.           <Button
  57.             type='submit'
  58.             variant='contained'
  59.             color='primary'
  60.             startIcon={<SearchIcon />}
  61.           >
  62.             Search
  63.           </Button>
  64.         </form>
  65.       </Grid>
  66.     </Box>
  67.   );
  68. };
  69.  
  70. export default Search;
  71.  
  72. /////
  73.  
  74. import React from 'react';
  75. import CircularProgress from '@material-ui/core/CircularProgress';
  76. import Grid from '@material-ui/core/Grid';
  77. import Typography from '@material-ui/core/Typography';
  78. import Box from '@material-ui/core/Box';
  79.  
  80. const Form = ({ weatherData, fetchState }) => {
  81.   const showText = () => {
  82.     if (fetchState === 'ERROR') {
  83.       return 'City not found!';
  84.     } else if (fetchState === 'LOADING') {
  85.       return <CircularProgress />;
  86.     } else {
  87.       return null;
  88.     }
  89.   };
  90.  
  91.   const showIcon = () => {
  92.     return (
  93.       weatherData.icon && (
  94.         <img
  95.           src={`http://openweathermap.org/img/wn/${weatherData.icon}@2x.png`}
  96.           alt='Weather Icon'
  97.         />
  98.       )
  99.     );
  100.   };
  101.  
  102.   return (
  103.     <Grid
  104.       textAlign='center'
  105.       container
  106.       direction='column'
  107.       justify='center'
  108.       alignItems='center'
  109.     >
  110.       <Box bgcolor='secondary.main'>
  111.         <Grid>
  112.           <Typography variant='h6'>{showText()}</Typography>
  113.         </Grid>
  114.       </Box>
  115.  
  116.       <Grid>
  117.         <Typography variant='h1'>
  118.           {weatherData.temperature &&
  119.             `${Math.floor(weatherData.temperature)}°C`}
  120.         </Typography>
  121.       </Grid>
  122.  
  123.       <Grid>
  124.         <Typography variant='h6'>
  125.           {weatherData.city && `${weatherData.city}, ${weatherData.country}`}
  126.         </Typography>
  127.       </Grid>
  128.  
  129.       <Grid>{showIcon()}</Grid>
  130.  
  131.       <Grid>
  132.         <Typography variant='h5'>
  133.           {weatherData.description.charAt(0).toUpperCase() +
  134.             weatherData.description.slice(1)}
  135.         </Typography>
  136.       </Grid>
  137.     </Grid>
  138.   );
  139. };
  140.  
  141. export default Form;
  142.  
  143. ////
  144.  
  145. import React, { useState, Fragment } from 'react';
  146. import SearchResults from './SearchResults';
  147. import SearchForm from './SearchForm';
  148.  
  149. const WeatherAppContainer = () => {
  150.   const [fetchState, setFetchState] = useState(null);
  151.   const [weatherData, setWeatherData] = useState({
  152.     country: '',
  153.     city: '',
  154.     temperature: '',
  155.     description: '',
  156.     icon: ''
  157.   });
  158.  
  159.   const fetchWeatherData = userQuery => {
  160.     const API_KEY = process.env.REACT_APP_API_KEY;
  161.     setFetchState('LOADING');
  162.     fetch(
  163.       `https://api.openweathermap.org/data/2.5/weather?q=${userQuery}&units=metric&appid=${API_KEY}`
  164.     )
  165.       .then(response => response.json())
  166.       .then(data => {
  167.         setWeatherData({
  168.           country: data.sys.country,
  169.           city: data.name,
  170.           temperature: data.main.temp,
  171.           description: data.weather[0].description,
  172.           icon: data.weather[0].icon
  173.         });
  174.         setFetchState(null);
  175.       })
  176.       .catch(() => {
  177.         setFetchState('ERROR');
  178.       });
  179.   };
  180.  
  181.   return (
  182.     <Fragment>
  183.       <SearchForm onSubmit={fetchWeatherData} />
  184.       <SearchResults weatherData={weatherData} fetchState={fetchState} />
  185.     </Fragment>
  186.   );
  187. };
  188.  
  189. export default WeatherAppContainer;
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Top