From aec2c734a4b47fa7f173c51fd9b9383c6d28c62b Mon Sep 17 00:00:00 2001 From: Krupa Panchal Date: Wed, 28 Dec 2022 12:59:13 +0530 Subject: [PATCH] Use latest functional components and hooks --- src/components/ErrorNotice/ErrorNotice.js | 23 --- src/components/ErrorNotice/ErrorNotice.jsx | 27 +++ src/components/Footer/Footer.js | 15 -- src/components/Footer/Footer.jsx | 14 ++ src/components/Header/Header.js | 14 -- src/components/Header/Header.jsx | 13 ++ src/components/Preview/Preview.js | 14 -- src/components/Preview/Preview.jsx | 14 ++ src/components/SearchBar/SearchBar.js | 27 --- src/components/SearchBar/SearchBar.jsx | 30 +++ src/components/WeatherDetails/Date/Date.js | 16 -- src/components/WeatherDetails/Date/Date.jsx | 14 ++ .../WeatherDetails/Description/Description.js | 13 -- .../Description/Description.jsx | 8 + .../WeatherDetails/Temperature/Temperature.js | 13 -- .../Temperature/Temperature.jsx | 13 ++ .../WeatherDetails/WeatherDetails.js | 24 --- .../WeatherDetails/WeatherDetails.jsx | 23 +++ src/containers/App/App.js | 173 ++++++++---------- src/elements/Button/Button.js | 20 -- src/elements/Button/Button.jsx | 18 ++ src/elements/Card/Card.js | 13 -- src/elements/Card/Card.jsx | 8 + src/elements/Icon/Icon.js | 14 -- src/elements/Icon/Icon.jsx | 14 ++ src/elements/InputField/InputField.js | 23 --- src/elements/InputField/InputField.jsx | 31 ++++ src/elements/Logo/Logo.js | 17 -- src/elements/Logo/Logo.jsx | 17 ++ src/utils/constants.js | 2 + 30 files changed, 319 insertions(+), 346 deletions(-) delete mode 100644 src/components/ErrorNotice/ErrorNotice.js create mode 100644 src/components/ErrorNotice/ErrorNotice.jsx delete mode 100644 src/components/Footer/Footer.js create mode 100644 src/components/Footer/Footer.jsx delete mode 100644 src/components/Header/Header.js create mode 100644 src/components/Header/Header.jsx delete mode 100644 src/components/Preview/Preview.js create mode 100644 src/components/Preview/Preview.jsx delete mode 100644 src/components/SearchBar/SearchBar.js create mode 100644 src/components/SearchBar/SearchBar.jsx delete mode 100644 src/components/WeatherDetails/Date/Date.js create mode 100644 src/components/WeatherDetails/Date/Date.jsx delete mode 100644 src/components/WeatherDetails/Description/Description.js create mode 100644 src/components/WeatherDetails/Description/Description.jsx delete mode 100644 src/components/WeatherDetails/Temperature/Temperature.js create mode 100644 src/components/WeatherDetails/Temperature/Temperature.jsx delete mode 100644 src/components/WeatherDetails/WeatherDetails.js create mode 100644 src/components/WeatherDetails/WeatherDetails.jsx delete mode 100644 src/elements/Button/Button.js create mode 100644 src/elements/Button/Button.jsx delete mode 100644 src/elements/Card/Card.js create mode 100644 src/elements/Card/Card.jsx delete mode 100644 src/elements/Icon/Icon.js create mode 100644 src/elements/Icon/Icon.jsx delete mode 100644 src/elements/InputField/InputField.js create mode 100644 src/elements/InputField/InputField.jsx delete mode 100644 src/elements/Logo/Logo.js create mode 100644 src/elements/Logo/Logo.jsx create mode 100644 src/utils/constants.js diff --git a/src/components/ErrorNotice/ErrorNotice.js b/src/components/ErrorNotice/ErrorNotice.js deleted file mode 100644 index 574ea78..0000000 --- a/src/components/ErrorNotice/ErrorNotice.js +++ /dev/null @@ -1,23 +0,0 @@ -import React from 'react'; - -import classes from './ErrorNotice.module.css'; -import Button from '../../elements/Button/Button'; - -const errorNotice = (props) => { - return( -
-

404

-
-

Oops!

-

We can't find the city you are looking for.

- -
-
- ); -} - -export default errorNotice; diff --git a/src/components/ErrorNotice/ErrorNotice.jsx b/src/components/ErrorNotice/ErrorNotice.jsx new file mode 100644 index 0000000..ed98894 --- /dev/null +++ b/src/components/ErrorNotice/ErrorNotice.jsx @@ -0,0 +1,27 @@ +import React from "react"; +import classes from "./ErrorNotice.module.css"; +import Button from "../../elements/Button/Button"; + +const ErrorNotice = ({ onClickHandler }) => { + return ( +
+

404

+
+

Oops!

+

+ We can't find the city you are looking for. +

+ +
+
+ ); +}; + +export default ErrorNotice; diff --git a/src/components/Footer/Footer.js b/src/components/Footer/Footer.js deleted file mode 100644 index a81d71c..0000000 --- a/src/components/Footer/Footer.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; - -import classes from './Footer.module.css'; -import Logo from '../../elements/Logo/Logo'; - -const footer = (props) => { - return( - - ); -} - -export default footer; \ No newline at end of file diff --git a/src/components/Footer/Footer.jsx b/src/components/Footer/Footer.jsx new file mode 100644 index 0000000..50f7216 --- /dev/null +++ b/src/components/Footer/Footer.jsx @@ -0,0 +1,14 @@ +import React from "react"; +import classes from "./Footer.module.css"; +import Logo from "../../elements/Logo/Logo"; + +const Footer = ({ onClickHandler }) => { + return ( + + ); +}; + +export default Footer; diff --git a/src/components/Header/Header.js b/src/components/Header/Header.js deleted file mode 100644 index d86e256..0000000 --- a/src/components/Header/Header.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; - -import classes from './Header.module.css'; -import Logo from '../../elements/Logo/Logo'; - -const header = (props) => { - return( -
- -
- ); -} - -export default header; \ No newline at end of file diff --git a/src/components/Header/Header.jsx b/src/components/Header/Header.jsx new file mode 100644 index 0000000..e14a16e --- /dev/null +++ b/src/components/Header/Header.jsx @@ -0,0 +1,13 @@ +import React from "react"; +import classes from "./Header.module.css"; +import Logo from "../../elements/Logo/Logo"; + +const Header = ({ onClickHandler, color }) => { + return ( +
+ +
+ ); +}; + +export default Header; diff --git a/src/components/Preview/Preview.js b/src/components/Preview/Preview.js deleted file mode 100644 index 1d35803..0000000 --- a/src/components/Preview/Preview.js +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react'; - -import classes from './Preview.module.css'; - -const preview = (props) => { - return( - Weather App Icon - ); -} - -export default preview; diff --git a/src/components/Preview/Preview.jsx b/src/components/Preview/Preview.jsx new file mode 100644 index 0000000..8a5854d --- /dev/null +++ b/src/components/Preview/Preview.jsx @@ -0,0 +1,14 @@ +import React from "react"; +import classes from "./Preview.module.css"; + +const Preview = () => { + return ( + Weather App Icon + ); +}; + +export default Preview; diff --git a/src/components/SearchBar/SearchBar.js b/src/components/SearchBar/SearchBar.js deleted file mode 100644 index e8359c0..0000000 --- a/src/components/SearchBar/SearchBar.js +++ /dev/null @@ -1,27 +0,0 @@ -import React from 'react' - -import classes from './SearchBar.module.css'; -import InputField from '../../elements/InputField/InputField'; -import Button from '../../elements/Button/Button'; - -const searchBar = (props) => { - return( -
- - -
- ); -} - -export default searchBar; \ No newline at end of file diff --git a/src/components/SearchBar/SearchBar.jsx b/src/components/SearchBar/SearchBar.jsx new file mode 100644 index 0000000..fa9e3b4 --- /dev/null +++ b/src/components/SearchBar/SearchBar.jsx @@ -0,0 +1,30 @@ +import React from "react"; +import classes from "./SearchBar.module.css"; +import InputField from "../../elements/InputField/InputField"; +import Button from "../../elements/Button/Button"; + +const SearchBar = ({ value, error, onChangeHandler, onClickHandler }) => { + return ( +
+ + +
+ ); +}; + +export default SearchBar; diff --git a/src/components/WeatherDetails/Date/Date.js b/src/components/WeatherDetails/Date/Date.js deleted file mode 100644 index 815b414..0000000 --- a/src/components/WeatherDetails/Date/Date.js +++ /dev/null @@ -1,16 +0,0 @@ -import React from 'react'; - -import dateformat from 'dateformat'; - -import classes from './Date.module.css'; - -const date = (props) => { - const today = new Date(); - return( -
- {dateformat(today, "dddd, mmmm dd")} -
- ); -} - -export default date; \ No newline at end of file diff --git a/src/components/WeatherDetails/Date/Date.jsx b/src/components/WeatherDetails/Date/Date.jsx new file mode 100644 index 0000000..dd5e700 --- /dev/null +++ b/src/components/WeatherDetails/Date/Date.jsx @@ -0,0 +1,14 @@ +import React from "react"; +import dateformat from "dateformat"; + +import classes from "./Date.module.css"; + +const TodayDate = () => { + return ( +
+ {dateformat(new Date(), "dddd, mmmm dd")} +
+ ); +}; + +export default TodayDate; diff --git a/src/components/WeatherDetails/Description/Description.js b/src/components/WeatherDetails/Description/Description.js deleted file mode 100644 index b6eeab4..0000000 --- a/src/components/WeatherDetails/Description/Description.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; - -import classes from './Description.module.css'; - -const description = (props) => { - return( -
- {props.type} -
- ); -} - -export default description; \ No newline at end of file diff --git a/src/components/WeatherDetails/Description/Description.jsx b/src/components/WeatherDetails/Description/Description.jsx new file mode 100644 index 0000000..91a2fa4 --- /dev/null +++ b/src/components/WeatherDetails/Description/Description.jsx @@ -0,0 +1,8 @@ +import React from "react"; +import classes from "./Description.module.css"; + +const Description = ({ type }) => { + return
{type}
; +}; + +export default Description; diff --git a/src/components/WeatherDetails/Temperature/Temperature.js b/src/components/WeatherDetails/Temperature/Temperature.js deleted file mode 100644 index e9bf3a8..0000000 --- a/src/components/WeatherDetails/Temperature/Temperature.js +++ /dev/null @@ -1,13 +0,0 @@ -import React from 'react'; - -import classes from './Temperature.module.css'; - -const temperature = (props) => { - return( -
- {Math.round(props.degrees)}° -
- ); -} - -export default temperature; \ No newline at end of file diff --git a/src/components/WeatherDetails/Temperature/Temperature.jsx b/src/components/WeatherDetails/Temperature/Temperature.jsx new file mode 100644 index 0000000..9588076 --- /dev/null +++ b/src/components/WeatherDetails/Temperature/Temperature.jsx @@ -0,0 +1,13 @@ +import React from "react"; +import classes from "./Temperature.module.css"; + +const Temperature = ({ degrees }) => { + return ( +
+ {Math.round(degrees)} + ° +
+ ); +}; + +export default Temperature; diff --git a/src/components/WeatherDetails/WeatherDetails.js b/src/components/WeatherDetails/WeatherDetails.js deleted file mode 100644 index b011080..0000000 --- a/src/components/WeatherDetails/WeatherDetails.js +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; - -import classes from './WeatherDetails.module.css'; -import Icon from '../../elements/Icon/Icon'; -import Temperature from './Temperature/Temperature'; -import Description from './Description/Description'; -import Date from './Date/Date'; - -const weatherDetails = (props) => { - return( -
-
- -
-
- - - -
-
- ); -} - -export default weatherDetails; \ No newline at end of file diff --git a/src/components/WeatherDetails/WeatherDetails.jsx b/src/components/WeatherDetails/WeatherDetails.jsx new file mode 100644 index 0000000..1ef78c1 --- /dev/null +++ b/src/components/WeatherDetails/WeatherDetails.jsx @@ -0,0 +1,23 @@ +import React from "react"; +import classes from "./WeatherDetails.module.css"; +import Icon from "../../elements/Icon/Icon"; +import Temperature from "./Temperature/Temperature"; +import Description from "./Description/Description"; +import TodayDate from "./Date/Date"; + +const WeatherDetails = ({ data }) => { + return ( +
+
+ +
+
+ + + +
+
+ ); +}; + +export default WeatherDetails; diff --git a/src/containers/App/App.js b/src/containers/App/App.js index 7286c6b..7134436 100644 --- a/src/containers/App/App.js +++ b/src/containers/App/App.js @@ -1,7 +1,4 @@ -import React, { Component } from 'react'; - -import { MoonLoader } from 'react-spinners'; - +import React from 'react'; import classes from './App.module.css'; import assetMapping from '../../assets/assetMapping.json'; import Card from '../../elements/Card/Card'; @@ -11,109 +8,85 @@ import SearchBar from '../../components/SearchBar/SearchBar'; import WeatherDetails from '../../components/WeatherDetails/WeatherDetails'; import Preview from '../../components/Preview/Preview'; import ErrorNotice from '../../components/ErrorNotice/ErrorNotice'; +import { MoonLoader } from 'react-spinners'; +import { API_URL, API_KEY } from '../../utils/constants'; -class App extends Component { - - state = { - searchBarInput: '', - weatherDetails: { - temperature: null, - description: '' - }, - loading: false, - error: false - } - - // Update state with current search bar input - searchBarHandler = (e) => { - this.setState({ - searchBarInput: e.target.value - }) - } +const App = () => { + const [error, setError] = React.useState(false); + const [isLoading, setIsLoading] = React.useState(false); + const [searchBarInput, setSearchBarInput] = React.useState(''); + const [weatherDetails, setWeatherDetails] = React.useState({ + temperature: null, + description: '' + }); - // Reset state after clicking on Logo or Try Again button - tryAgainHandler = () => { - this.setState({ - searchBarInput: '', - weatherDetails: {}, - error: false - }) - } + const tryAgainHandler = () => { + setSearchBarInput(''); + setWeatherDetails({}); + setError(false); + }; - // Fetch weather information and update state - setWeather = () => { - const city = this.state.searchBarInput; - const API_KEY = process.env.REACT_APP_WEATHER_API_KEY; - const API_URL = 'https://api.openweathermap.org/data/2.5/weather'; + const setWeather = () => { + const city = searchBarInput; const URL = API_URL + `?q=${city}&appid=${API_KEY}&units=metric`; - this.setState({ - weatherDetails: {}, - loading: true, - error: false - }, () => { - // Executed as callback function - fetch(URL) - .then(res => res.json()) - .then(data => { - // If city exists, update weather details - if(data.cod === 200) { - this.setState({ - weatherDetails: { - temperature: data.main.temp, - description: data.weather[0].main - }, - loading: false - }); - } else { - // If city doesn't exist, throw error - throw data.cod - } - }) - .catch(err => { - console.log(err); - this.setState({ - loading: false, - error: true - }); - }); - }); - } - render() { + setIsLoading(true); + setError(false); + setWeatherDetails({}); - // Conditionally render card content - let cardContent = ; - if (this.state.loading) { - cardContent = ; - } else if (this.state.error) { - cardContent = ; - } else if (this.state.weatherDetails.temperature && this.state.weatherDetails.description !== '') { - // Display weather information if temperature and description exists - cardContent = ; - } + fetch(URL) + .then((res) => res.json()) + .then((data) => { + // If city exists, update weather details + if (data.cod === 200) { + setWeatherDetails({ + temperature: data.main.temp, + description: data.weather[0].main + }); + } else { + // If city doesn't exist, throw error + throw data.cod; + } + }) + .catch(() => { + setError(true); + }) + .finally(() => setIsLoading(false)); + }; - return ( -
-
+
-
- - - {cardContent} - -
-
-
- ); - } -} + error ? 'error' : weatherDetails.description + ] + } + onClickHandler={tryAgainHandler} + /> +
+ setSearchBarInput(e.target.value)} + onClickHandler={setWeather} + error={error} + /> + + {isLoading ? ( + + ) : error ? ( + + ) : weatherDetails.temperature && weatherDetails.description !== '' ? ( + + ) : ( + + )} + +
+