diff --git a/src/App.js b/src/App.js index b02b91a..e1af006 100644 --- a/src/App.js +++ b/src/App.js @@ -1,4 +1,3 @@ -// src/App.js import React, { useEffect, useState } from 'react'; import Navbar from './components/Navbar'; import WeatherInfo from './components/WeatherInfo'; @@ -10,6 +9,7 @@ const API_KEY = '1fb9b7430ade9dc72614f3f70d323ea3'; // Replace with your OpenWea function App() { const [weatherData, setWeatherData] = useState(null); + const [forecastData, setForecastData] = useState(null); const [tempUnit, setTempUnit] = useState('celsius'); // State to hold temperature unit useEffect(() => { @@ -18,6 +18,7 @@ function App() { (position) => { const { latitude, longitude } = position.coords; fetchWeatherData(latitude, longitude); + fetchForecastData(latitude, longitude); }, (error) => { console.error('Error fetching user location:', error); @@ -37,6 +38,15 @@ function App() { } }; + const fetchForecastData = async (latitude, longitude) => { + try { + const response = await axios.get(`https://api.openweathermap.org/data/2.5/forecast?lat=${latitude}&lon=${longitude}&appid=${API_KEY}`); + setForecastData(response.data); + } catch (error) { + console.error('Error fetching forecast data:', error); + } + }; + const handleWeatherData = (data) => { setWeatherData(data); }; @@ -49,8 +59,7 @@ function App() {
- {weatherData && } - + {weatherData && }
); } diff --git a/src/components/Search.css b/src/components/Search.css index 8c434f2..e738ef1 100644 --- a/src/components/Search.css +++ b/src/components/Search.css @@ -1,6 +1,7 @@ /* src/components/Search.css */ .search-container { position: relative; + border: none; } .search-input { @@ -10,7 +11,13 @@ color: black; text-align: center; /* Center the placeholder text */ border-radius: 20px; /* Add a border radius of 20px */ - border: 1px solid #ccc; + border: none; /* Ensure no border is added */ + outline: none; /* Remove default focus outline */ +} + +.search-input:focus { + border: none; /* Ensure no border is added on focus */ + outline: none; /* Remove focus outline */ } .search-input::placeholder { @@ -24,13 +31,14 @@ position: absolute; width: 30vw; /* Match the width of the input */ background-color: white; - border: 1px solid #ccc; border-radius: 20px; /* Add a border radius of 20px */ z-index: 1000; overflow: hidden; /* Ensure border-radius is applied */ + overflow-x: visible; } .suggestion-item { + border: none; padding: 10px; cursor: pointer; color: black; /* Set the dropdown text color to black */ @@ -41,9 +49,11 @@ } .suggestions-list .suggestion-item:first-child:hover { + border: none; border-radius: 20px 20px 0 0; /* Apply border-radius to the top */ } .suggestions-list .suggestion-item:last-child:hover { + border: none; border-radius: 0 0 20px 20px; /* Apply border-radius to the bottom */ } diff --git a/src/components/WeatherInfo.css b/src/components/WeatherInfo.css index 1cb0a4b..36204c7 100644 --- a/src/components/WeatherInfo.css +++ b/src/components/WeatherInfo.css @@ -1,98 +1,158 @@ /* src/components/WeatherInfo.css */ * { - padding: 0; - margin: 0; - box-sizing: border-box; - color: white; + padding: 0; + margin: 0; + box-sizing: border-box; + color: white; + } .full-weather { - height: 75vh; - display: flex; - align-items: center; - justify-content: center; - + height: 75vh; + display: flex; + align-items: center; + justify-content: center; } .weather-info { - background: rgba(0,0,0, 0.3); - border-radius: 10px; - width: 70vw; - height: 65vh; - margin: 20px auto; - padding: 20px; - box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); - } + overflow-x: hidden; + background: rgba(0, 0, 0, 0.3); + border-radius: 10px; + width: 70vw; + height: 65vh; + margin: 20px auto; + padding: 20px; + box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1); +} + +.weather-info button { + height: 40px; + width: 120px; + border-radius: 10px; + background: rgba(0, 0, 0, 0.3); + border: none; + margin-right: 10px; + font-size: 18px; +} + +.weather-info button:focus, +.weather-info button:hover { + background-color: rgba(255, 255, 255, 0.1); + /* border: 1px solid white; */ + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + border-bottom: 0; +} .weather-top { - background: rgba(255,255,255, 0.1); - border-radius: 10px; - width: 100%; - height: 10vh; - padding-left: 50px; - display: flex; - align-items: center; - justify-content: center; + background: rgba(255, 255, 255, 0.1); + border-radius: 10px; + width: 100%; + height: 10vh; + padding-left: 50px; + display: flex; + align-items: center; + justify-content: center; } .weatherbelow { - width: 100%; - height: 50vh; - display: flex; + width: 100%; + height: 50vh; + display: flex; } .weather-left { - width: 50%; - display: flex; - flex-direction: column; + width: 50%; + display: flex; + flex-direction: column; } .weather-left-row { - width: 80%; - display: flex; - align-items: center; - justify-content: space-around; + width: 80%; + display: flex; + align-items: center; + justify-content: space-around; } .weather-left-row img { - height: 10vh; + height: 10vh; } .row1 { - height: 50%; + height: 50%; } .row1 h2 { - font-size: 5rem; + font-size: 5rem; } .row1 p { - font-size: 2.5rem; + font-size: 2.5rem; } .row2 { - height: 30%; + height: 30%; } .row2-main { - display: flex; + display: flex; } .weather-right { - padding-top: 20px; - width: 50%; - display: flex; - flex-direction: column; - + padding-top: 20px; + width: 50%; + display: flex; + flex-direction: column; } .right-rows { - display: flex; - align-items: center; - justify-items: center; - height: 13%; + display: flex; + align-items: center; + justify-items: center; + height: 11%; } .right-rows h2 { - width: 50%; + width: 50%; } .right-rows p { - font-size: 1.3rem; - font-weight: 600; -} \ No newline at end of file + font-size: 1.3rem; + font-weight: 600; +} + +/* Add this CSS code to your existing WeatherInfo.css file */ + +.forecast { + display: flex; + flex-direction: column; + width: 100%; +} + +.forecast-day h3 { + /* background-color: rgba(255, 255, 255, 0.1); */ + border-radius: 20px; + /* margin: 10px 0; */ + padding: 10px 20px; + font-size: 25px; +} + +.forecast-column { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + background-color: rgba(255, 255, 255, 0.2); + border-radius: 10px; + padding: 5px; + margin: 5px; + width: 115px; + height: 100px; +} + +.forecast-items { + display: flex; +} + +.forecast-item { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + diff --git a/src/components/WeatherInfo.js b/src/components/WeatherInfo.js index 7493ea1..b4f598d 100644 --- a/src/components/WeatherInfo.js +++ b/src/components/WeatherInfo.js @@ -1,14 +1,17 @@ -// src/components/WeatherInfo.js -import React from "react"; +import React, { useState } from "react"; import "./WeatherInfo.css"; +import axios from "axios"; -const WeatherInfo = ({ weatherData, tempUnit }) => { - const { name, sys, main, weather, wind, visibility, clouds, coord } = weatherData; - console.log(weatherData); +const WeatherInfo = ({ weatherData, forecastData, tempUnit }) => { + const { name, sys, main, weather, wind, visibility, clouds, coord } = + weatherData; + const [displayMode, setDisplayMode] = useState("today"); // Function to convert temperature based on selected unit const convertTemperature = (temp) => { - return tempUnit === 'celsius' ? (temp - 273.15).toFixed(0) + '°C' : ((temp - 273.15) * 9 / 5 + 32).toFixed(0) + '°F'; + return tempUnit === "celsius" + ? (temp - 273.15).toFixed(0) + "°C" + : (((temp - 273.15) * 9) / 5 + 32).toFixed(0) + "°F"; }; // Function to capitalize the first letter of a string @@ -16,69 +19,177 @@ const WeatherInfo = ({ weatherData, tempUnit }) => { return str.charAt(0).toUpperCase() + str.slice(1); }; + const handleTodayClick = () => { + setDisplayMode("today"); + }; + + const handle5DaysClick = () => { + setDisplayMode("5days"); + }; + return (
-
-

Current Weather in {name}, {sys.country}

-
-
-
-
-
- -

{convertTemperature(main.temp)}

-

{capitalize(weather[0].description)}

-
-
-
-
- -
- -

Sunrise

-

{new Date(sys.sunrise * 1000).toLocaleTimeString()}

-
-
-

Sunset

-

{new Date(sys.sunset * 1000).toLocaleTimeString()}

-
+ + + + {displayMode === "today" && ( + + )} + + {displayMode === "5days" && forecastData && ( + + )} +
+
+ ); +}; + +const Forecast = ({ name, country, forecastData, tempUnit, convertTemperature }) => { + let groupedForecast = {}; + + // Group forecast data by date and time + forecastData.list.forEach((forecast) => { + const dateTime = new Date(forecast.dt_txt); + const date = dateTime.toDateString(); + const time = dateTime.toLocaleTimeString([], { + hour: "2-digit", + minute: "2-digit", + }); + if (!groupedForecast[date]) { + groupedForecast[date] = {}; + } + if (!groupedForecast[date][time]) { + groupedForecast[date][time] = []; + } + groupedForecast[date][time].push(forecast); + }); + + return ( + <> +
+

+ 5-Day forecast for {name}, {country} +

+
+
+ {Object.keys(groupedForecast).map((date, index) => ( +
+

+ Day -{" "} + {new Date(date).toLocaleDateString(undefined, { + weekday: "long", + })} +

+
+ {Object.keys(groupedForecast[date]).map((time, i) => ( +
+

{time}

+ {groupedForecast[date][time].map((forecast, j) => ( +
+

{convertTemperature(forecast.main.temp)}

+

{forecast.weather[0].description}

+
+ ))} +
+ ))}
-
-
-

Latitude

-

{coord.lat}

-
-
-

Longitude

-

{coord.lon}

-
-
-

Humidity

-

{main.humidity}%

-
-
-

Pressure

-

{main.pressure} hPa

-
-
-

Visibility

-

{visibility} meters

-
-
-

Wind

-

Speed: {wind.speed} m/s

-
-
-

Cloudiness

-

{clouds.all}%

-
+ ))} +
+ + ); +}; + +const WeatherDetails = ({ + name, + sys, + main, + weather, + wind, + visibility, + clouds, + coord, + tempUnit, + convertTemperature, + capitalize, +}) => ( + <> +
+

+ Current Weather in {name}, {sys.country} +

+
+
+
+
+
+

{convertTemperature(main.temp)}

+

{capitalize(weather[0].description)}

+
+
+
+
+
+

Sunrise

+

{new Date(sys.sunrise * 1000).toLocaleTimeString()}

+
+
+

Sunset

+

{new Date(sys.sunset * 1000).toLocaleTimeString()}

+
+
+

Latitude

+

{coord.lat}

+
+
+

Longitude

+

{coord.lon}

+
+
+

Humidity

+

{main.humidity}%

+
+
+

Pressure

+

{main.pressure} hPa

+
+
+

Visibility

+

{visibility} meters

+
+
+

Wind

+

Speed: {wind.speed} m/s

+
+
+

Cloudiness

+

{clouds.all}%

+
+
- ); -}; + +); export default WeatherInfo;