diff --git a/app.js b/app.js deleted file mode 100644 index cd74d66..0000000 --- a/app.js +++ /dev/null @@ -1,66 +0,0 @@ -const form = document.querySelector('form'); -const input = document.querySelector('input'); -const iconDiv = document.querySelector('#icon'); -const detailsDiv = document.querySelector('#details'); - -// Add event listener to search form -form.addEventListener('submit', (e) => { - e.preventDefault(); - const city = input.value; - const apiKey = 'f235c5e839c641aa861661c219ae7237'; - const url = `https://api.weatherbit.io/v2.0/current?city=${city}&key=${apiKey}`; - - // Fetch weather data for selected location - fetch(url) - .then(response => response.json()) - .then(data => { - const temp = data.data[0].temp; - const description = data.data[0].weather.description; - let iconCode = data.data[0].weather.icon; - // remove the first character from the icon code - // to get the correct icon name - iconCode = iconCode.substring(1); - - // Display weather data and icon - iconDiv.innerHTML = ``; - detailsDiv.innerHTML = `Temperature: ${temp}°C
Description: ${description}`; - }) - .catch(error => { - console.error(error); - detailsDiv.innerHTML = 'An error occurred while fetching weather data.'; - }); -}); - -// Get icon code based on weather condition -function getIcon(iconCode) { - switch (iconCode) { - case '01d': - return 'sun'; - case '01n': - return 'moon'; - case '02d': - case '02n': - case '03d': - case '03n': - return 'cloud'; - case '04d': - case '04n': - return 'cloud-meatball'; - case '09d': - case '09n': - case '10d': - case '10n': - return 'cloud-showers-heavy'; - case '11d': - case '11n': - return 'bolt'; - case '13d': - case '13n': - return 'snowflake'; - case '50d': - case '50n': - return 'smog'; - default: - return 'question'; - } -} \ No newline at end of file diff --git a/css/dark-theme.css b/css/dark-theme.css new file mode 100644 index 0000000..8928463 --- /dev/null +++ b/css/dark-theme.css @@ -0,0 +1,58 @@ +#light-switch { + appearance: none; + display: none; +} + +.switch-button { + top: 10px; + margin-left: 10%; +} + +.switch-mode { + position: relative; + display: block; + width: 70px; + height: 40px; + background: #1f4b66; + cursor: pointer; + border-radius: 20px; + overflow: hidden; + transition: ease-in 0.5s; +} + +#light-switch:checked~.switch-mode { + background: #fff; +} + +.switch-mode:before { + content: ''; + position: absolute; + top: 8px; + left: 10px; + background: #fff; + width: 25px; + height: 25px; + border-radius: 50%; + transition: 0.5s; +} + +#light-switch:checked~.switch-mode:before { + transform: translateX(30px); +} + +.switch-mode:after { + content: ''; + position: absolute; + top: 8px; + left: 10px; + background: #1f4b66; + width: 25px; + height: 25px; + border-radius: 50%; + transition: 0.5s; + transform: translateX(30px); +} + +#light-switch:checked~.switch-mode:after { + transform: translateX(0); +} \ No newline at end of file diff --git a/css/style.css b/css/style.css new file mode 100644 index 0000000..e717eb0 --- /dev/null +++ b/css/style.css @@ -0,0 +1,138 @@ +body { + color: black; + font-size: 25px; + transition: background-color 0.5s; +} + +.dark-mode { + background-color: black; + color: white; +} + +.light-mode { + background-color: #1c92d2; + color: black; +} + + +table { + width: 60%; + margin: auto; +} + +table td { + padding: 5px; +} + +table i { + margin-right: 5px; +} + +.container { + width: 80%; + margin: auto; +} + +h1 { + text-align: center; + margin-top: 50px; +} + +form { + display: flex; + justify-content: center; + align-items: center; + margin-top: 30px; +} + +label { + font-size: 18px; + margin-right: 10px; +} + +input[type="text"] { + font-size: 18px; + padding: 5px; + border-radius: 5px; + border: none; + box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + margin-right: 10px; +} + +button[type="submit"], +button[type="reset"] { + font-size: 18px; + padding: 5px 10px; + border-radius: 5px; + border: none; + cursor: pointer; + margin-left: 10px; +} + +button[type="submit"] { + background-color: #4CAF50; + color: white; +} + +button[type="submit"]:hover { + background-color: #3e8e41; +} + +button[type="reset"] { + background-color: #6c757d; + color: white; +} + +#weather { + margin-top: 30px; + background-color: #f0f0f0; + color: black; +} + +#get-weekly-forecast { + background-color: #f0f0f0; + color: black; +} + +.card { + background-color: white; + padding: 20px; + border-radius: 10px; + box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1); +} + +#icon { + font-size: 5rem; + text-align: center; +} + +#details { + font-size: 1.5rem; +} + +.loading-spinner { + border: 6px solid rgba(0, 0, 0, 0.1); + border-left: 6px solid #3498db; + border-radius: 50%; + width: 30px; + height: 30px; + animation: spin 1s linear infinite; + display: none; + margin: auto; + margin-top: 20px; +} + +@keyframes spin { + 0% { + transform: rotate(0deg); + } + + 100% { + transform: rotate(360deg); + } +} + +footer { + text-align: center; + padding: 20px; +} \ No newline at end of file diff --git a/index.html b/index.html index 34a4d39..de1bf8e 100644 --- a/index.html +++ b/index.html @@ -1,21 +1,59 @@ - + + Weather App - + + - - -

Weather App

-
- - - -
-
-
-
+ + + + + + + +
+
- - + + + + + +
+

Weather App

+
+ + + + +
+
+
+

Enter city name to see the weather information

+
+
+
+
+
+

Weekly Forecast

+
    +
+
+
Made with ❤️ by Thanusha
+ + + \ No newline at end of file diff --git a/js/app.js b/js/app.js new file mode 100644 index 0000000..0c90842 --- /dev/null +++ b/js/app.js @@ -0,0 +1,133 @@ +const form = document.querySelector("form"); +const input = document.querySelector("#city"); +const iconDiv = document.querySelector("#icon"); +const detailsDiv = document.querySelector("#details"); +const loadingSpinner = document.querySelector("#loadingSpinner"); +const weatherTitle = document.querySelector("#weatherTitle"); +const weeklyForecastButton = document.querySelector("#get-weekly-forecast"); + +// Add event listener to search form +form.addEventListener("submit", (e) => { + e.preventDefault(); + const city = input.value; + const apiKey = "f235c5e839c641aa861661c219ae7237"; + const currentWeatherUrl = `https://api.weatherbit.io/v2.0/current?city=${city}&key=${apiKey}`; + const weeklyForecastUrl = `https://api.weatherbit.io/v2.0/forecast/daily?city=${city}&key=${apiKey}`; + + // show the loading spinner while fetching data + loadingSpinner.style.display = "block"; + + // Fetch current weather + fetch(currentWeatherUrl) + .then((response) => response.json()) + .then((data) => { + // Display current weather data as before + const temp = data.data[0].temp; + const description = data.data[0].weather.description; + const humidity = data.data[0].rh; + const pressure = data.data[0].pres; + const windSpeed = data.data[0].wind_spd; + + let iconCode = data.data[0].weather.icon; + // remove the first character from the icon code + // to get the correct icon name + iconCode = iconCode.substring(1); + + // hide the loading spinner after data is fetched + loadingSpinner.style.display = "none"; + + // Display weather data and icon + iconDiv.innerHTML = ``; + + // set the title attribute for the tooltip + iconDiv.title = `Weather Condition: ${description}`; + + detailsDiv.innerHTML = ` + + + + + + + + + + + + + + + + + + + + + +
Temperature: ${temp}°C
Description: ${description}
Humidity: ${humidity}%
Pressure: ${pressure}mbar
Wind Speed: ${windSpeed}m/s
+ `; + weatherTitle.textContent = `Current Weather Conditions in ${city}`; + + // Fetch weekly forecast + return fetch(weeklyForecastUrl); + }) + .then((response) => response.json()) + .then((data) => { + const weeklyForecastData = data.data; + const weeklyForecastList = document.getElementById("weeklyForecastList"); + weeklyForecastList.innerHTML = ""; + + weeklyForecastData.forEach((forecast) => { + const date = forecast.valid_date; + const maxTemp = forecast.max_temp; + const minTemp = forecast.min_temp; + const description = forecast.weather.description; + + const listItem = document.createElement("li"); + listItem.innerHTML = ` + ${date}: Max Temp: ${maxTemp}°C, Min Temp: ${minTemp}°C, Description: ${description} + `; + weeklyForecastList.appendChild(listItem); + }); + }) + .catch((error) => { + console.error(error); + detailsDiv.innerHTML = "An error occurred while fetching weather data."; + }); + // hide the loading spinner after data is fetched + loadingSpinner.style.display = "none"; +}); + +// Get icon code based on weather condition +function getIcon(iconCode) { + switch (iconCode) { + case "01d": + return "sun"; + case "01n": + return "moon"; + case "02d": + case "02n": + case "03d": + case "03n": + return "cloud"; + case "04d": + case "04n": + return "cloud-meatball"; + case "09d": + case "09n": + case "10d": + case "10n": + return "cloud-showers-heavy"; + case "11d": + case "11n": + return "bolt"; + case "13d": + case "13n": + return "snowflake"; + case "50d": + case "50n": + return "smog"; + default: + return "question"; + } +} diff --git a/style.css b/style.css deleted file mode 100644 index b4baa99..0000000 --- a/style.css +++ /dev/null @@ -1,56 +0,0 @@ -body { - font-family: Arial, sans-serif; - background-color: #f2f2f2; -} - -h1 { - text-align: center; - margin-top: 50px; -} - -form { - display: flex; - justify-content: center; - margin-top: 30px; -} - -label { - font-size: 18px; - margin-right: 10px; -} - -input[type="text"] { - font-size: 18px; - padding: 5px; - border-radius: 5px; - border: none; - box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); -} - -button[type="submit"] { - font-size: 18px; - padding: 5px 10px; - border-radius: 5px; - border: none; - background-color: #4CAF50; - color: white; - cursor: pointer; -} - -button[type="submit"]:hover { - background-color: #3e8e41; -} - -#weather { - margin-top: 30px; - font-size: 24px; -} - -#icon { - font-size: 5rem; - margin-bottom: 1rem; -} - -#details { - font-size: 1.5rem; -} \ No newline at end of file