From c3d0d953fb31a660738824b5d4946617d7b7a226 Mon Sep 17 00:00:00 2001 From: Hantaro191702 Date: Tue, 7 Nov 2023 19:52:45 +0700 Subject: [PATCH 1/2] solved --- css/dark-theme.css | 58 ++++++++++++++++++++++++++++++++++++++ style.css => css/style.css | 0 index.html | 15 ++++++++-- app.js => js/app.js | 0 4 files changed, 70 insertions(+), 3 deletions(-) create mode 100644 css/dark-theme.css rename style.css => css/style.css (100%) rename app.js => js/app.js (100%) 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/style.css b/css/style.css similarity index 100% rename from style.css rename to css/style.css diff --git a/index.html b/index.html index 34a4d39..7670b5b 100644 --- a/index.html +++ b/index.html @@ -2,10 +2,19 @@ Weather App - + + - + + +
+ +
+

Weather App

@@ -16,6 +25,6 @@

Weather App

- + \ No newline at end of file diff --git a/app.js b/js/app.js similarity index 100% rename from app.js rename to js/app.js From ff8229d7d7f98cb9319283de039b272a39089655 Mon Sep 17 00:00:00 2001 From: Hantaro191702 Date: Wed, 8 Nov 2023 19:10:58 +0700 Subject: [PATCH 2/2] the switch button (solved by Hantaro) --- css/style.css | 94 +++++++++++++++++++++++++++++-- index.html | 61 ++++++++++++++------ js/app.js | 151 ++++++++++++++++++++++++++++++++++++-------------- 3 files changed, 242 insertions(+), 64 deletions(-) diff --git a/css/style.css b/css/style.css index b4baa99..e717eb0 100644 --- a/css/style.css +++ b/css/style.css @@ -1,6 +1,36 @@ body { - font-family: Arial, sans-serif; - background-color: #f2f2f2; + 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 { @@ -11,6 +41,7 @@ h1 { form { display: flex; justify-content: center; + align-items: center; margin-top: 30px; } @@ -25,32 +56,83 @@ input[type="text"] { border-radius: 5px; border: none; box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2); + margin-right: 10px; } -button[type="submit"] { +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; - cursor: pointer; } button[type="submit"]:hover { background-color: #3e8e41; } +button[type="reset"] { + background-color: #6c757d; + color: white; +} + #weather { margin-top: 30px; - font-size: 24px; + 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; - margin-bottom: 1rem; + 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 7670b5b..de1bf8e 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,18 @@ - + + 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 index cd74d66..0c90842 100644 --- a/js/app.js +++ b/js/app.js @@ -1,66 +1,133 @@ -const form = document.querySelector('form'); -const input = document.querySelector('input'); -const iconDiv = document.querySelector('#icon'); -const detailsDiv = document.querySelector('#details'); +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) => { +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}`; + 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}`; - // Fetch weather data for selected location - fetch(url) - .then(response => response.json()) - .then(data => { + // 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 = ``; - detailsDiv.innerHTML = `Temperature: ${temp}°C
Description: ${description}`; + + // 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 => { + .catch((error) => { console.error(error); - detailsDiv.innerHTML = 'An error occurred while fetching weather data.'; + 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'; + 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'; + return "question"; } -} \ No newline at end of file +}