diff --git a/src/App.js b/src/App.js index c0ae1c7..0a78a16 100644 --- a/src/App.js +++ b/src/App.js @@ -7,6 +7,8 @@ import 'react-toastify/dist/ReactToastify.css'; class App extends React.Component { constructor() { super(); + + this.state = { city_name: "london", error: false, @@ -21,12 +23,88 @@ class App extends React.Component { visibility: [], displayLoader: "none", }; + + this.componentDidMount = this.componentDidMount.bind(this); this.city = this.city.bind(this); this.submit = this.submit.bind(this); + + this.clearInput = this.clearInput.bind(this); this.componentWillMount = this.componentWillMount.bind(this); + this.closeToasterMessage = this.closeToasterMessage.bind(this); } + async componentDidMount() { + try { + const position = await this.getCurrentPosition(); + const { latitude, longitude } = position.coords; + + const reverseGeocodeRes = await fetch( + `http://api.openweathermap.org/geo/1.0/reverse?lat=${latitude}&lon=${longitude}&limit=1&appid=${process.env.REACT_APP_OPEN_WEATHER_SECRET}` + ); + const reverseGeocodeData = await reverseGeocodeRes.json(); + const cityName = reverseGeocodeData[0]?.name || "london"; + + + + this.setState({ + city_name: cityName, + }); + + // Now fetch weather data based on the user's location + this.fetchWeatherData(cityName); + } catch (error) { + console.error("Error getting location or weather data:", error); + this.setState({ + error: true, + toast_message: "Error fetching location or weather data.", + }); + } + } + + getCurrentPosition() { + return new Promise((resolve, reject) => { + navigator.geolocation.getCurrentPosition(resolve, reject); + }); + } + + async fetchWeatherData(city) { + const url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${process.env.REACT_APP_OPEN_WEATHER_SECRET}`; + try { + const response = await fetch(url); + if (!response.ok) { + throw Error(response.status); + } + const responseData = await response.json(); + + this.setState({ + temp: responseData.main.temp, + city: responseData.name, + icon: responseData.weather[0].icon, + desc: responseData.weather[0].description, + humidity: responseData.main.humidity, + pressure: responseData.main.pressure, + wind: responseData.wind.speed, + visibility: responseData.visibility, + error: false, + toast_message: "", + }); + } catch (error) { + if (error.message === "404") { + this.setState({ + error: true, + toast_message: + "The location entered is invalid. Please enter a valid location.", + }); + toast("The location entered is invalid", { + position: toast.POSITION.TOP_CENTER, + autoClose: 1500, + className: 'toast-message' + }); + } + } + } + city(event) { this.setState({ city_name: event.target.value, @@ -48,6 +126,11 @@ class App extends React.Component { e.preventDefault(); this.componentWillMount(); } + clearInput() { + this.setState({ + city_name: "", + }); + } componentWillMount() { document.body.style.filter = "blur(0px)"; @@ -94,7 +177,7 @@ class App extends React.Component { position: toast.POSITION.TOP_CENTER, autoClose: 1500, className: 'toast-message' - }); + }); } }); } @@ -117,6 +200,9 @@ class App extends React.Component { SUBMIT + + Clear + {this.state.error && ( - + )} ); diff --git a/src/Footer.js b/src/Footer.js index 5f12f28..2656c35 100644 --- a/src/Footer.js +++ b/src/Footer.js @@ -1,5 +1,6 @@ -import React from "react" -import "./index.css" +import React from "react"; +import "./index.css"; + function Footer(){ return( @@ -14,6 +15,20 @@ function Footer(){ ) } +function Footer() { + const year = new Date().getFullYear(); -export default Footer + return ( + + ); +} +export default Footer; diff --git a/src/Header.js b/src/Header.js index e4bbb1c..5dd4c86 100644 --- a/src/Header.js +++ b/src/Header.js @@ -1,11 +1,14 @@ import React from "react"; import "./index.css"; +import {TiWeatherSunny} from 'react-icons/ti' function Header() { return ( - GET WEATHER 💨 + + GET WEATHER + ); diff --git a/src/index.css b/src/index.css index e5c1e99..2f2b10f 100644 --- a/src/index.css +++ b/src/index.css @@ -17,10 +17,16 @@ footer { color: white; background-image: linear-gradient(to right, #051937, #0d2750, #16376b, #214786, #2c57a3); padding: 1.5rem; + + text-align: center; } + + header { margin-bottom: 1rem; + margin-bottom: 2rem; + } footer { @@ -40,6 +46,7 @@ a:hover { width: 90%; max-width: 1110px; margin: 0 auto; + } /* TYPOGRAPHY */ @@ -49,6 +56,16 @@ a:hover { display: flex; justify-content: center; padding-left: 0.6rem; + font-size: 3rem; + font-weight: 24px; + padding-left: 0.rem; + font-family:Arial, Helvetica, sans-serif +} +.logo{ + font-size: 50px; + vertical-align: middle; + margin-left: 10px; + } h2 { @@ -99,6 +116,18 @@ p { cursor: pointer; transition: 0.5s; } +.clear-button{ + font-size:17px ; + margin-top: 1rem; + margin-left: 1rem; + font-family: Arial, sans-serif; + background-color: #7c77fe; + border-radius: 10em; + padding: 1.1rem 2rem; + cursor: pointer; + color: white; + +} .cancel-button { color: white; @@ -112,6 +141,12 @@ p { justify-content: center; } + +.clear-button:hover { + background-color: #6c7077; +} + + .submit-button:hover { box-shadow: rgba(0, 0, 0, 0.35) 0px 5px 15px; transform: scale(0.9); @@ -276,3 +311,6 @@ p { transform: rotate(360deg); } } +.footer1{ + font-size: 20px; +}
SUBMIT