From 9c2478ee85f3128e1f8c16c2a3b024c27ed597d9 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Fri, 27 Sep 2024 10:27:40 +0200 Subject: [PATCH 01/26] Add a HTML file with a basic structure. Add a JS file with DOM selectors and API URL and endpoints --- .vscode/settings.json | 3 +++ code/index.html | 29 +++++++++++++++++++++++++++++ code/script.js | 15 +++++++++++++++ instructions.md | 2 +- 4 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 .vscode/settings.json create mode 100644 code/index.html create mode 100644 code/script.js diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..6f3a2913e --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/code/index.html b/code/index.html new file mode 100644 index 000000000..6e90e98dc --- /dev/null +++ b/code/index.html @@ -0,0 +1,29 @@ + + + + + + Document + + +
+
+ +

Temp

+

City

+

Weather type

+

Sunrise:

+

Sunset:

+
+ +
+
+

Weekday

+ Image +

Empty P tag

+
+
+
+ + + \ No newline at end of file diff --git a/code/script.js b/code/script.js new file mode 100644 index 000000000..a0e851117 --- /dev/null +++ b/code/script.js @@ -0,0 +1,15 @@ + +//API URL and Endpoints +const BaseURL = "https://api.openweathermap.org/data/2.5/weather?" +const api_key = "" +const city = "Stockholm,Sweden" + +const todayURL = `${BaseURL}q=${city}&units=metric&APPID=${api_key}` +const forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast?" +const forecastURL = `${forecastBaseURL}q=${city}&units=metric&APPID=${api_key}` + +// DOM Selectors +const cityName = document.getElementById("city") +const temperature = document.getElementById("temp") +const sunriseTime = document.getElementById("sunrise") +const sunsetTime = document.getElementById("sunset") diff --git a/instructions.md b/instructions.md index 42fc411ce..d41ce5112 100644 --- a/instructions.md +++ b/instructions.md @@ -8,7 +8,7 @@ Start out with signing up for a [free Open Weather Map](https://home.openweather For example, to get the current weather in Stockholm, you can use the URL below. Remember to replace YOUR_API_KEY with the API key you copied from your dashboard. ``` -https://api.openweathermap.org/data/2.5/weather?q=Stockholm,Sweden&units=metric&APPID=YOUR_API_KEY +https://api.openweathermap.org/data/2.5/weather?q=Stockholm,Sweden&units=metric&APPID=617b18d1663716ef276314bb0808d62b ``` The response should look something like this (this has been run through jsonlint.com to add newlines and indentation): From 6789ee91592a2996bba76668422b01e29e351eb2 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Fri, 27 Sep 2024 10:49:19 +0200 Subject: [PATCH 02/26] Remove example of what an API key looks like and how it should be used that came along with the instructions, to avoid security leak mail from GitHub --- instructions.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instructions.md b/instructions.md index d41ce5112..4492dcfd5 100644 --- a/instructions.md +++ b/instructions.md @@ -8,7 +8,7 @@ Start out with signing up for a [free Open Weather Map](https://home.openweather For example, to get the current weather in Stockholm, you can use the URL below. Remember to replace YOUR_API_KEY with the API key you copied from your dashboard. ``` -https://api.openweathermap.org/data/2.5/weather?q=Stockholm,Sweden&units=metric&APPID=617b18d1663716ef276314bb0808d62b +https://api.openweathermap.org/data/2.5/weather?q=Stockholm,Sweden&units=metric&APPID=xxxxx ``` The response should look something like this (this has been run through jsonlint.com to add newlines and indentation): From 9d178178a3e72f9b7d3900c9bcfc9ee3b3195649 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Fri, 27 Sep 2024 13:03:15 +0200 Subject: [PATCH 03/26] Fetch data for City name, weather description, sunrise, sunset and temperatur. Update DOM selectors and HTML with correct ID and names. --- code/index.html | 5 +++-- code/script.js | 23 ++++++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/code/index.html b/code/index.html index 6e90e98dc..43603c39e 100644 --- a/code/index.html +++ b/code/index.html @@ -9,9 +9,10 @@
-

Temp

+

Temperature

City

-

Weather type

+

Weather description

+

Sunrise:

Sunset:

diff --git a/code/script.js b/code/script.js index a0e851117..b84bc0f28 100644 --- a/code/script.js +++ b/code/script.js @@ -10,6 +10,27 @@ const forecastURL = `${forecastBaseURL}q=${city}&units=metric&APPID=${api_key}` // DOM Selectors const cityName = document.getElementById("city") -const temperature = document.getElementById("temp") +const description = document.getElementById("description") +const temperature = document.getElementById("temperature") const sunriseTime = document.getElementById("sunrise") const sunsetTime = document.getElementById("sunset") + +//Fetch todays weather +const fetchTodaysWeatherAsync = async () => { + try { + const response = await fetch(`${todayURL}`) + //convert response to JSON + const data = await response.json() + console.log("Data is shown in JSON format: ", data) + + cityName.innerHTML = data.name + temperature.innerHTML = `${data.main.temp} °C` + description.innerHTML = data.weather[0].description + sunriseTime.innerHTML = data.sys.sunrise + sunsetTime.innerHTML = data.sys.sunset + } catch (error) { + //Handle any errors + console.error("Error when fetching Today's weather", error) + } +} +fetchTodaysWeatherAsync() \ No newline at end of file From b7ec8bbe4b1eabd031f4e954ea3239c0477cf22c Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Fri, 27 Sep 2024 13:43:00 +0200 Subject: [PATCH 04/26] Fetch data for forecast using async. Add variables for latitud and longitud, and add forecast BASE_URL and forecast URL. --- code/script.js | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/code/script.js b/code/script.js index b84bc0f28..259b4faab 100644 --- a/code/script.js +++ b/code/script.js @@ -1,12 +1,15 @@ //API URL and Endpoints const BaseURL = "https://api.openweathermap.org/data/2.5/weather?" -const api_key = "" +const api_key = "617b18d1663716ef276314bb0808d62b" const city = "Stockholm,Sweden" +const lat = "59.3326" +const lon = "18.0649" const todayURL = `${BaseURL}q=${city}&units=metric&APPID=${api_key}` const forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast?" -const forecastURL = `${forecastBaseURL}q=${city}&units=metric&APPID=${api_key}` +const forecastURL = `${forecastBaseURL}lat=${lat}&lon=${lon}&units=metric&appid=${api_key}` +// units=metric to get temperatures in Celcius // DOM Selectors const cityName = document.getElementById("city") @@ -21,7 +24,7 @@ const fetchTodaysWeatherAsync = async () => { const response = await fetch(`${todayURL}`) //convert response to JSON const data = await response.json() - console.log("Data is shown in JSON format: ", data) + //console.log("Data is shown in JSON format: ", data) cityName.innerHTML = data.name temperature.innerHTML = `${data.main.temp} °C` @@ -33,4 +36,19 @@ const fetchTodaysWeatherAsync = async () => { console.error("Error when fetching Today's weather", error) } } -fetchTodaysWeatherAsync() \ No newline at end of file +fetchTodaysWeatherAsync() + +//Fetch forecast weather +const fetchForecastWeatherAsync = async () => { + try { + const response = await fetch(`${forecastURL}`) + //convert response to JSON + const data = await response.json() + console.log("Data is shown in JSON format: ", data) + + } catch (error) { + //Handle any errors + console.error("Error when fetching Today's weather", error) + } +} +fetchForecastWeatherAsync() \ No newline at end of file From a8a5a265600039aec8a30902abf1f9fcf34ddcb5 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Fri, 27 Sep 2024 14:04:52 +0200 Subject: [PATCH 05/26] Update console log text. Remove test data. --- code/index.html | 1 + code/script.js | 20 ++++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/code/index.html b/code/index.html index 43603c39e..c4161b648 100644 --- a/code/index.html +++ b/code/index.html @@ -13,6 +13,7 @@

Temperature

City

Weather description

+

Sunrise:

Sunset:

diff --git a/code/script.js b/code/script.js index 259b4faab..314b6cfd8 100644 --- a/code/script.js +++ b/code/script.js @@ -1,14 +1,14 @@ - //API URL and Endpoints -const BaseURL = "https://api.openweathermap.org/data/2.5/weather?" +const BASE_URL = "https://api.openweathermap.org/data/2.5/weather?" const api_key = "617b18d1663716ef276314bb0808d62b" const city = "Stockholm,Sweden" -const lat = "59.3326" -const lon = "18.0649" +const LAT = "59.3326" +const LON = "18.0649" +const timestamps = 2 -const todayURL = `${BaseURL}q=${city}&units=metric&APPID=${api_key}` +const todayURL = `${BASE_URL}q=${city}&units=metric&APPID=${api_key}` const forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast?" -const forecastURL = `${forecastBaseURL}lat=${lat}&lon=${lon}&units=metric&appid=${api_key}` +const forecastURL = `${forecastBaseURL}lat=${LAT}&lon=${LON}&cnt=${timestamps}&units=metric&appid=${api_key}` // units=metric to get temperatures in Celcius // DOM Selectors @@ -17,6 +17,10 @@ const description = document.getElementById("description") const temperature = document.getElementById("temperature") const sunriseTime = document.getElementById("sunrise") const sunsetTime = document.getElementById("sunset") +const weekday = document.getElementById("weekday") + +//Other variables +const date = new Date() //Fetch todays weather const fetchTodaysWeatherAsync = async () => { @@ -44,11 +48,11 @@ const fetchForecastWeatherAsync = async () => { const response = await fetch(`${forecastURL}`) //convert response to JSON const data = await response.json() - console.log("Data is shown in JSON format: ", data) + console.log("Forecast data is shown in JSON format: ", data) } catch (error) { //Handle any errors - console.error("Error when fetching Today's weather", error) + console.error("Error when fetching the forecast", error) } } fetchForecastWeatherAsync() \ No newline at end of file From b0f7e29fce2e6c214746c7ae0c9d99b149fa61dd Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Sat, 28 Sep 2024 14:43:41 +0200 Subject: [PATCH 06/26] Make the function fetchTodayWeatherAsync dynamic by removing City as a global const and place the const for todayURL inside the function, and finally add city as a parameter to that function. Test dynamic city by adding Las Vegas as a param in function invocation --- code/script.js | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/code/script.js b/code/script.js index 314b6cfd8..ae6d4be1e 100644 --- a/code/script.js +++ b/code/script.js @@ -1,12 +1,11 @@ //API URL and Endpoints const BASE_URL = "https://api.openweathermap.org/data/2.5/weather?" const api_key = "617b18d1663716ef276314bb0808d62b" -const city = "Stockholm,Sweden" const LAT = "59.3326" const LON = "18.0649" const timestamps = 2 -const todayURL = `${BASE_URL}q=${city}&units=metric&APPID=${api_key}` +//const todayURL = `${BASE_URL}q=${city}&units=metric&APPID=${api_key}` const forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast?" const forecastURL = `${forecastBaseURL}lat=${LAT}&lon=${LON}&cnt=${timestamps}&units=metric&appid=${api_key}` // units=metric to get temperatures in Celcius @@ -21,11 +20,17 @@ const weekday = document.getElementById("weekday") //Other variables const date = new Date() - +//const lat = data.coord.lat +//const lon = data.coord.lon + //Fetch todays weather -const fetchTodaysWeatherAsync = async () => { +const fetchTodaysWeatherAsync = async (city) => { + const todayURL = `${BASE_URL}q=${city}&units=metric&APPID=${api_key}` try { const response = await fetch(`${todayURL}`) + if (!response.ok) { + throw new Error("Failed to fetch today's weather data"); + } //convert response to JSON const data = await response.json() //console.log("Data is shown in JSON format: ", data) @@ -40,12 +45,15 @@ const fetchTodaysWeatherAsync = async () => { console.error("Error when fetching Today's weather", error) } } -fetchTodaysWeatherAsync() +fetchTodaysWeatherAsync("Las Vegas") //Fetch forecast weather -const fetchForecastWeatherAsync = async () => { +const fetchForecastWeatherAsync = async (city) => { try { const response = await fetch(`${forecastURL}`) + if (!response.ok) { + throw new Error("Failed to fetch forecast weather data"); + } //convert response to JSON const data = await response.json() console.log("Forecast data is shown in JSON format: ", data) From 85b4e961728c8446eff139d17e9a4e17e591c225 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Sun, 29 Sep 2024 22:35:38 +0200 Subject: [PATCH 07/26] HTML: Add HTML element for five-day forecast. Delete element Weekday and Temp. JS: Fix forecast filtering, add forEach loop to display forecast at 12:00 and to add day name using weekdays array. --- code/index.html | 4 +--- code/script.js | 45 +++++++++++++++++++++++++++------------------ 2 files changed, 28 insertions(+), 21 deletions(-) diff --git a/code/index.html b/code/index.html index c4161b648..3390001b7 100644 --- a/code/index.html +++ b/code/index.html @@ -17,12 +17,10 @@

Sunrise:

Sunset:

-
+
-

Weekday

Image -

Empty P tag

diff --git a/code/script.js b/code/script.js index ae6d4be1e..3e9d5c806 100644 --- a/code/script.js +++ b/code/script.js @@ -1,14 +1,7 @@ //API URL and Endpoints const BASE_URL = "https://api.openweathermap.org/data/2.5/weather?" -const api_key = "617b18d1663716ef276314bb0808d62b" -const LAT = "59.3326" -const LON = "18.0649" -const timestamps = 2 - -//const todayURL = `${BASE_URL}q=${city}&units=metric&APPID=${api_key}` const forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast?" -const forecastURL = `${forecastBaseURL}lat=${LAT}&lon=${LON}&cnt=${timestamps}&units=metric&appid=${api_key}` -// units=metric to get temperatures in Celcius +const api_key = "617b18d1663716ef276314bb0808d62b" // DOM Selectors const cityName = document.getElementById("city") @@ -16,16 +9,15 @@ const description = document.getElementById("description") const temperature = document.getElementById("temperature") const sunriseTime = document.getElementById("sunrise") const sunsetTime = document.getElementById("sunset") -const weekday = document.getElementById("weekday") +const fiveDayForecast = document.getElementById('five-day-forecast') -//Other variables -const date = new Date() -//const lat = data.coord.lat -//const lon = data.coord.lon +//Array with weekdays +const weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] //Fetch todays weather const fetchTodaysWeatherAsync = async (city) => { const todayURL = `${BASE_URL}q=${city}&units=metric&APPID=${api_key}` + // units=metric to get temperatures in Celcius try { const response = await fetch(`${todayURL}`) if (!response.ok) { @@ -33,8 +25,8 @@ const fetchTodaysWeatherAsync = async (city) => { } //convert response to JSON const data = await response.json() - //console.log("Data is shown in JSON format: ", data) - + + //Update DOM with today's weather data cityName.innerHTML = data.name temperature.innerHTML = `${data.main.temp} °C` description.innerHTML = data.weather[0].description @@ -49,6 +41,8 @@ fetchTodaysWeatherAsync("Las Vegas") //Fetch forecast weather const fetchForecastWeatherAsync = async (city) => { + const forecastURL = `${forecastBaseURL}q=${city}&units=metric&appid=${api_key}` + // units=metric to get temperatures in Celcius try { const response = await fetch(`${forecastURL}`) if (!response.ok) { @@ -56,11 +50,26 @@ const fetchForecastWeatherAsync = async (city) => { } //convert response to JSON const data = await response.json() - console.log("Forecast data is shown in JSON format: ", data) - + + //Filter forecast on 12:00 + const filteredForecast = data.list.filter(forecast => { + const forecastDate = new Date(forecast.dt_txt) + return forecastDate.getHours() === 12 + }) + + filteredForecast.forEach(forecast => { + let forecastDate = new Date(forecast.dt_txt)//Convert date to Date const + let dayName = weekdays[forecastDate.getDay()] // Get weekday + + //Update HTML with weekday and temperture + fiveDayForecast.innerHTML += `

${dayName}: ${forecast.main.temp} °C

` + + + console.log(`Day: ${dayName}, Temp: ${forecast.main.temp} °C`) + }) } catch (error) { //Handle any errors console.error("Error when fetching the forecast", error) } } -fetchForecastWeatherAsync() \ No newline at end of file +fetchForecastWeatherAsync("Las Vegas") \ No newline at end of file From 70c33e67d7148840d6808963433d726d5c7ce2cf Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Sun, 29 Sep 2024 22:50:56 +0200 Subject: [PATCH 08/26] Add Math.round to today and forecast temperature to display a whole number. --- code/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/script.js b/code/script.js index 3e9d5c806..e2c4574f0 100644 --- a/code/script.js +++ b/code/script.js @@ -28,7 +28,7 @@ const fetchTodaysWeatherAsync = async (city) => { //Update DOM with today's weather data cityName.innerHTML = data.name - temperature.innerHTML = `${data.main.temp} °C` + temperature.innerHTML = `${Math.round(data.main.temp)} °C` description.innerHTML = data.weather[0].description sunriseTime.innerHTML = data.sys.sunrise sunsetTime.innerHTML = data.sys.sunset @@ -62,7 +62,7 @@ const fetchForecastWeatherAsync = async (city) => { let dayName = weekdays[forecastDate.getDay()] // Get weekday //Update HTML with weekday and temperture - fiveDayForecast.innerHTML += `

${dayName}: ${forecast.main.temp} °C

` + fiveDayForecast.innerHTML += `

${dayName}: ${Math.round(forecast.main.temp)} °C

` console.log(`Day: ${dayName}, Temp: ${forecast.main.temp} °C`) From d1998e09b30b62396e8d13f8cfc68541e43aaba0 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Sun, 29 Sep 2024 22:59:40 +0200 Subject: [PATCH 09/26] Convert Sunset/Sunrise from seconds to milliseconds by multiplying by 1000, which the date object requires --- code/script.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/code/script.js b/code/script.js index e2c4574f0..3c7cc526d 100644 --- a/code/script.js +++ b/code/script.js @@ -21,7 +21,7 @@ const fetchTodaysWeatherAsync = async (city) => { try { const response = await fetch(`${todayURL}`) if (!response.ok) { - throw new Error("Failed to fetch today's weather data"); + throw new Error("Failed to fetch today's weather data") } //convert response to JSON const data = await response.json() @@ -30,8 +30,14 @@ const fetchTodaysWeatherAsync = async (city) => { cityName.innerHTML = data.name temperature.innerHTML = `${Math.round(data.main.temp)} °C` description.innerHTML = data.weather[0].description - sunriseTime.innerHTML = data.sys.sunrise - sunsetTime.innerHTML = data.sys.sunset + //Convert Sunset/Sunrise from seconds to milliseconds by multiplying by 1000, which the date object requires + const sunrise = new Date(data.sys.sunrise * 1000).toLocaleTimeString() + const sunset = new Date(data.sys.sunset * 1000).toLocaleTimeString() + + sunriseTime.innerHTML = `Sunrise: ${sunrise}`; + sunsetTime.innerHTML = `Sunset: ${sunset}` + //sunriseTime.innerHTML = data.sys.sunrise + //sunsetTime.innerHTML = data.sys.sunset } catch (error) { //Handle any errors console.error("Error when fetching Today's weather", error) @@ -46,7 +52,7 @@ const fetchForecastWeatherAsync = async (city) => { try { const response = await fetch(`${forecastURL}`) if (!response.ok) { - throw new Error("Failed to fetch forecast weather data"); + throw new Error("Failed to fetch forecast weather data") } //convert response to JSON const data = await response.json() From ca9a504057bbbe8c98ca96f5674792e0572f5486 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Sun, 29 Sep 2024 23:52:41 +0200 Subject: [PATCH 10/26] Add CSS styling. Adapt app do different screen sizes. Add weather icons for sun, cloudy and few clouds. --- code/index.html | 6 ++-- code/script.js | 29 ++++++++++++---- code/styles.css | 91 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 116 insertions(+), 10 deletions(-) create mode 100644 code/styles.css diff --git a/code/index.html b/code/index.html index 3390001b7..6df9fcd1f 100644 --- a/code/index.html +++ b/code/index.html @@ -3,12 +3,13 @@ - Document + Project Weather App +
- + Current Weather Icon

Temperature

City

Weather description

@@ -20,7 +21,6 @@

- Image
diff --git a/code/script.js b/code/script.js index 3c7cc526d..2a8eb8816 100644 --- a/code/script.js +++ b/code/script.js @@ -13,6 +13,12 @@ const fiveDayForecast = document.getElementById('five-day-forecast') //Array with weekdays const weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] + +const weatherIcons = { + "scattered clouds": "/assets/design-1/Group16.png", // Cloudy + "few clouds": "/assets/design-1/Group34.png", // Few clouds + "clear sky": "/assets/design-1/Group37.png", // Sunny + } //Fetch todays weather const fetchTodaysWeatherAsync = async (city) => { @@ -30,14 +36,21 @@ const fetchTodaysWeatherAsync = async (city) => { cityName.innerHTML = data.name temperature.innerHTML = `${Math.round(data.main.temp)} °C` description.innerHTML = data.weather[0].description + + const weatherDescription = data.weather[0].description + + //Weather icon + const weatherIconURL = weatherIcons[weatherDescription] || "/assets/design-1/Group16.png"; // Default icon + document.getElementById("weather-icon").src = weatherIconURL + + //Convert Sunset/Sunrise from seconds to milliseconds by multiplying by 1000, which the date object requires const sunrise = new Date(data.sys.sunrise * 1000).toLocaleTimeString() const sunset = new Date(data.sys.sunset * 1000).toLocaleTimeString() - sunriseTime.innerHTML = `Sunrise: ${sunrise}`; + sunriseTime.innerHTML = `Sunrise: ${sunrise}` sunsetTime.innerHTML = `Sunset: ${sunset}` - //sunriseTime.innerHTML = data.sys.sunrise - //sunsetTime.innerHTML = data.sys.sunset + } catch (error) { //Handle any errors console.error("Error when fetching Today's weather", error) @@ -66,12 +79,14 @@ const fetchForecastWeatherAsync = async (city) => { filteredForecast.forEach(forecast => { let forecastDate = new Date(forecast.dt_txt)//Convert date to Date const let dayName = weekdays[forecastDate.getDay()] // Get weekday - - //Update HTML with weekday and temperture - fiveDayForecast.innerHTML += `

${dayName}: ${Math.round(forecast.main.temp)} °C

` + //Get weather icon + const weatherDescription = forecast.weather[0].description + + //Update HTML with weekday, temperture and icon + const forecastIconURL = weatherIcons[weatherDescription] || "/assets/design-1/Group16.png"; // Default icon + fiveDayForecast.innerHTML += `

${dayName}: weather icon ${Math.round(forecast.main.temp)} °C

` - console.log(`Day: ${dayName}, Temp: ${forecast.main.temp} °C`) }) } catch (error) { //Handle any errors diff --git a/code/styles.css b/code/styles.css new file mode 100644 index 000000000..cb5470d79 --- /dev/null +++ b/code/styles.css @@ -0,0 +1,91 @@ +/*Ensure images adapts well to all devices*/ +img { + display: block; + max-width: 100%; +} +/* Tablet */ + +@media screen and (min-width: 501px) and (max-width: 1024px) { + .container { + width: 600px; + padding: 40px; + } + + .temperature h1 { + font-size: 60px; + } + + .forecast p { + font-size: 16px; + } +} +/* Desktop */ +@media screen and (min-width: 1025px) { + .container { + width: 800px; + padding: 50px; + } + .temperature h1 { + font-size: 72px; + } + .forecast p { + font-size: 18px; + } +} +body { + font-family: 'Arial', sans-serif; + margin: 0; + padding: 0; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + background-color: #f5f5f5; + } + + .container { + background: linear-gradient(to bottom, #d1c4e9, #fff); + border-radius: 20px; + box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.1); + padding: 20px; + width: 320px; + text-align: center; + } + + .temperature h1 { + font-size: 72px; + font-weight: bold; + color: #fff; + } + + .sunrise_sunset { + font-size: 14px; + color: grey; + opacity: 0.6; + } + + .forecast { + margin-top: 20px; + } + + .forecast #five-day-forecast p { + font-size: 14px; + color: #333; + margin: 5px 0; + display: flex; + justify-content: space-between; + } + + .forecast-day { + display: flex; + align-items: center; + justify-content: space-between; + padding: 10px 0; + border-bottom: 1px solid #ddd; + } + + .forecast img { + width: 24px; + height: 24px; + } + \ No newline at end of file From 2ede3e4e991260e877db8224cbc016351b73ef16 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 00:07:44 +0200 Subject: [PATCH 11/26] Copy folder with images to the code folder. Update paths to icons i the JS code --- README.md | 2 +- code/assets/design-1/Group16.png | Bin 0 -> 1101 bytes code/assets/design-1/Group34.png | Bin 0 -> 1159 bytes code/assets/design-1/Group36.png | Bin 0 -> 1074 bytes code/assets/design-1/Group37.png | Bin 0 -> 1074 bytes code/assets/design-1/Group38.png | Bin 0 -> 1074 bytes code/assets/design-2/noun_Cloud_1188486.svg | 7 ++++++ .../design-2/noun_Sunglasses_2055147.svg | 23 ++++++++++++++++++ .../assets/design-2/noun_Umbrella_2030530.svg | 16 ++++++++++++ code/index.html | 1 - code/script.js | 6 ++--- 11 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 code/assets/design-1/Group16.png create mode 100644 code/assets/design-1/Group34.png create mode 100644 code/assets/design-1/Group36.png create mode 100644 code/assets/design-1/Group37.png create mode 100644 code/assets/design-1/Group38.png create mode 100644 code/assets/design-2/noun_Cloud_1188486.svg create mode 100644 code/assets/design-2/noun_Sunglasses_2055147.svg create mode 100644 code/assets/design-2/noun_Umbrella_2030530.svg diff --git a/README.md b/README.md index f8b15f4cb..021fedb6c 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,4 @@ Describe how you approached to problem, and what tools and techniques you used t ## View it live -Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about. +project-weather-app-by-joe diff --git a/code/assets/design-1/Group16.png b/code/assets/design-1/Group16.png new file mode 100644 index 0000000000000000000000000000000000000000..c2d0e3f5a573364a03e0fd8e208af5cfffb72ceb GIT binary patch literal 1101 zcmV-T1hV^yP)pORlz0?V7J6`4{8w1>62tk6;xMj&Uhk^s0 z;9Q7e@EYtNWO3Pb6?K0=I)Y@9Xc{($gUB*;vP_thqL95v6da?}m6u_%49d08YfF1q zb4|bzdKAp=pS%2i-{<>ze)oLyLm!sSa%&eNwqk6I0U30SMu=5ADJ+6s@960X@9 zShIG0SU;zeh6{~fPH?P0o}#F^umu3H2uzaX27-v{mq#d+UXKT&W7IHoZvYav?SS}% zXCdXebU{z6We~3Z*n0bvo(hU8Dk{|cyQZdQeAyXO6eVK0z{BL!^tFlGli{hSql5YY z$HA0+5_-))1H-tWpzx?5{D-z?=kUF|Hzg8rtl#ffa)AJbVVFI@1+LA^I1IJ5wPW+e z!4v1_=VRNGlJ6fmTBac)BL$7=X*;xDY=n|y<$$7CNZsGoAxPM~bzzU=Sm4*pH-55; zFwr|Yowl3b41)D~gSp_XceB^6SB4$Wuw@W#^>o4OZxqA$*a&bO2Qe{fh`@=kwdYOs z&aqM3UZc_2gODUyl#!KF|MK1gD^6wK%^om!b%0tE2O^Oucq0CL|Eq^VB9ScHK%KGb zfyd2kLngY3s{x~3|suGM{HK;Xm5izi{AseTp{Sycc&LRuU#=9 zI-QOw|L9}6ToJKiu#k|?z&EC|@Bw*T&}-U03C&Gk-$p3?snPezN)3VtUSg|i=+|F5 zK_-*KuJo*sbw1x5)Svn65f8Q$A1i+*0>@Vc5EA$QaR+Qx3miC97*gV9Tu^8Hl;LOG z`pUk8hmuluJ`wQvs11I<)dL6fibDELjE};1&5hlBsxvmKH0>p&AFg>46?S#;{8x~Zy9c6UR7)zH4jRsx>U;In z$;^dBeNt8R#m@8>O42ei|2O>mOW#6tvu zlV@;($lH>bq|$7P2b>^);{w13J`h;!HNWPY^TNb~F&G*gfY`XrkhJ5!ta!a1py_EC zxo>d{TL%088u&A}rKN>kxH2ENBuR3sR31hItu=NtDavKCj24L@^XNmKF1Q zxdNYaGqVzjRLWtP*yVA%Fa$+eg#w>qnAvqGim@!~r==2k-^>hs!DuwLKF;|UPMC>g TTmc{V00000NkvXXu0mjf?e`Gl literal 0 HcmV?d00001 diff --git a/code/assets/design-1/Group34.png b/code/assets/design-1/Group34.png new file mode 100644 index 0000000000000000000000000000000000000000..f7e90e552c1375d85f1654594bb8d042479df958 GIT binary patch literal 1159 zcmV;21bF+2P)X1^@s6%>pGE00004b3#c}2nYxW zdZg;K_kO@w7GI*Hj2WJ9Ckl4;0>PF?0g zoVu~N1VVfH(X>FOZ!8fgiSJe#Q4&Ioc#e2wO*C<^J>X?)!ev=iT$pJNF`3rhzg39soWhgj@_35(N`1_PJWE?)7@Tg|)S{ zKLztF8x&*Acs!mjj7H;?WreEM>g@oq(_k>D=LW_YZ$Jpi`8kGRIs!rS^73RH$BF9d z>L!=GQjGC70LUVQXfVdRghFVNM+)8H62$Sa>tpUHkq8}gySaQq$P_=PR;yJAp*4gM z%-;uvVvG}9E?1Pt;~A>2uXp=bq0tmJ$z{}Q@9&P4t%?)PF3#cfLQDG;+jq%fak;%) z03ZPX6oil;{GxzRK8;eTOeYqLlANqFJ|Qt_=GxW47^yU393iU3W}EI(MhiYG%8i$W zOQ?XKu%piktsT=BDyu(v_I|+w(29zq-$h0#($mtOTeRHLU0PcH<&Ny#`_?^`x@e$Zc)aOz*tXdMNr_^(dYuK<#X*FWg0+u_!LOGcaQfWT zH+IL}3XbE}-}6kNf`WpL$ti13?c1N1yksH(uq+Fwzy1_%j$0rlISCX>B{=Lh82W1% zBEz}6qhm8Agb*?>y;`l-_(J9@`RQ97cH_11h`Zm+4)M*;wcN=wT|a}O1+ULlVPY79kiqS-Vt zaHW5b!C>e_TCMI(*3P%G*Qag>C1y}>%bAlSzg+0y_uEqlWBlgk^yeF2&Dymhs51mX zb5jGq(j24Fc;43>bh^?T?;glcRL0I0SP0<*TdR)hJZAHqNR!Fr^g;PeI6h%j>wypO z;(Oo{UaSAoMQA(w?eWUW%Duko^?Pe-$QA%^+j|EK_zGLr!RS9ShlPn_X`1%VgYq{j zmFngA#MKR3GhRwbeP&b0;J=3l;Y4$zGa@2FPSdn&wmIA%xwyDkDHclz%R1iPl$K!^ z3Ptj0MGUxHEQrNnzUzO3Pm=G1;u}Jt7(5=APh*?5ItK>&Z8q!l@XU-olVKRgT+Ty} zD>O}u&1UlsilUz2I8MkPIVg&n@_N1gADU0q?6HC4I2%Gp1^~A?j=Lie2znWY`7=3FwcS=X(wLyJGm4nG#KaE@lPDUq528_l zU?iF;+ph0*Ev*~tM9r8E+k0=FR%${74G=Zz1T`uyi^hG>K>{&gNEjCCkd?M89ow$G z?KLHKnM-@zT}X`azP``z`906`d;a7g(D`{hp7Km4Gm0^;)9C_0y+E(mYmy`>f-$~P zuaEyGd2@5Kv8=3Yk0^@IT(`_Qj;l8q4CnoR|0TUn)#3`49U=53gm3_3{Pj{t4u|75 znx^XsAq~|Q+CCANe}xbpl_cpzC=?n~B5rMMt)wU_8w>_7=j@7Vju0B8C@Lrj!jZhg z?H$hVSp$7{O*KQ^dNXUb)f&L>Q3;$qCrwVK=VsDZ=7)QF0~-qkfDj5o2!F#EznyQp3EB-B38^i5A5yT_DDHP9c+Ep zYEq-+m6q4 z#?H-x{a+*w`*!%75JDjc;X?BeLe4;h(9;mYvW3BiFewPaU}s1B@P;PK>Xr6|C(S|p z_)8ib9!iD#b_p-?JiiG5usD;LQp3Ia=xS5cMHqdY77=zO$n&AmVomYvLO0r2E-EC_~|hzo=RsL2L=Ylb2y&o z-Gq>cD2gAeDtlX7+j53se#RKv3IPy8PXGY!saVFWr5OU}=Rr1=p8J*%a=gF4e{d&<=x?MG%^g62m}Jh7vofEUWka}IF_bqH^#U}OCZ;U s{QvvY@ULc`YgVVzX%++_p;z<20G0-ok{TUnlmGw#07*qoM6N<$f@n7UssI20 literal 0 HcmV?d00001 diff --git a/code/assets/design-1/Group37.png b/code/assets/design-1/Group37.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9c147cfbcf523c7422d6d0fe743be6dfcd14d4 GIT binary patch literal 1074 zcmV-21kL-2P)3FwcS=X(wLyJGm4nG#KaE@lPDUq528_l zU?iF;+ph0*Ev*~tM9r8E+k0=FR%${74G=Zz1T`uyi^hG>K>{&gNEjCCkd?M89ow$G z?KLHKnM-@zT}X`azP``z`906`d;a7g(D`{hp7Km4Gm0^;)9C_0y+E(mYmy`>f-$~P zuaEyGd2@5Kv8=3Yk0^@IT(`_Qj;l8q4CnoR|0TUn)#3`49U=53gm3_3{Pj{t4u|75 znx^XsAq~|Q+CCANe}xbpl_cpzC=?n~B5rMMt)wU_8w>_7=j@7Vju0B8C@Lrj!jZhg z?H$hVSp$7{O*KQ^dNXUb)f&L>Q3;$qCrwVK=VsDZ=7)QF0~-qkfDj5o2!F#EznyQp3EB-B38^i5A5yT_DDHP9c+Ep zYEq-+m6q4 z#?H-x{a+*w`*!%75JDjc;X?BeLe4;h(9;mYvW3BiFewPaU}s1B@P;PK>Xr6|C(S|p z_)8ib9!iD#b_p-?JiiG5usD;LQp3Ia=xS5cMHqdY77=zO$n&AmVomYvLO0r2E-EC_~|hzo=RsL2L=Ylb2y&o z-Gq>cD2gAeDtlX7+j53se#RKv3IPy8PXGY!saVFWr5OU}=Rr1=p8J*%a=gF4e{d&<=x?MG%^g62m}Jh7vofEUWka}IF_bqH^#U}OCZ;U s{QvvY@ULc`YgVVzX%++_p;z<20G0-ok{TUnlmGw#07*qoM6N<$f@n7UssI20 literal 0 HcmV?d00001 diff --git a/code/assets/design-1/Group38.png b/code/assets/design-1/Group38.png new file mode 100644 index 0000000000000000000000000000000000000000..ce9c147cfbcf523c7422d6d0fe743be6dfcd14d4 GIT binary patch literal 1074 zcmV-21kL-2P)3FwcS=X(wLyJGm4nG#KaE@lPDUq528_l zU?iF;+ph0*Ev*~tM9r8E+k0=FR%${74G=Zz1T`uyi^hG>K>{&gNEjCCkd?M89ow$G z?KLHKnM-@zT}X`azP``z`906`d;a7g(D`{hp7Km4Gm0^;)9C_0y+E(mYmy`>f-$~P zuaEyGd2@5Kv8=3Yk0^@IT(`_Qj;l8q4CnoR|0TUn)#3`49U=53gm3_3{Pj{t4u|75 znx^XsAq~|Q+CCANe}xbpl_cpzC=?n~B5rMMt)wU_8w>_7=j@7Vju0B8C@Lrj!jZhg z?H$hVSp$7{O*KQ^dNXUb)f&L>Q3;$qCrwVK=VsDZ=7)QF0~-qkfDj5o2!F#EznyQp3EB-B38^i5A5yT_DDHP9c+Ep zYEq-+m6q4 z#?H-x{a+*w`*!%75JDjc;X?BeLe4;h(9;mYvW3BiFewPaU}s1B@P;PK>Xr6|C(S|p z_)8ib9!iD#b_p-?JiiG5usD;LQp3Ia=xS5cMHqdY77=zO$n&AmVomYvLO0r2E-EC_~|hzo=RsL2L=Ylb2y&o z-Gq>cD2gAeDtlX7+j53se#RKv3IPy8PXGY!saVFWr5OU}=Rr1=p8J*%a=gF4e{d&<=x?MG%^g62m}Jh7vofEUWka}IF_bqH^#U}OCZ;U s{QvvY@ULc`YgVVzX%++_p;z<20G0-ok{TUnlmGw#07*qoM6N<$f@n7UssI20 literal 0 HcmV?d00001 diff --git a/code/assets/design-2/noun_Cloud_1188486.svg b/code/assets/design-2/noun_Cloud_1188486.svg new file mode 100644 index 000000000..c2375e901 --- /dev/null +++ b/code/assets/design-2/noun_Cloud_1188486.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/code/assets/design-2/noun_Sunglasses_2055147.svg b/code/assets/design-2/noun_Sunglasses_2055147.svg new file mode 100644 index 000000000..a1fcd7e8b --- /dev/null +++ b/code/assets/design-2/noun_Sunglasses_2055147.svg @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/code/assets/design-2/noun_Umbrella_2030530.svg b/code/assets/design-2/noun_Umbrella_2030530.svg new file mode 100644 index 000000000..8a414b15f --- /dev/null +++ b/code/assets/design-2/noun_Umbrella_2030530.svg @@ -0,0 +1,16 @@ + + + + + + + + + + + + + + + + diff --git a/code/index.html b/code/index.html index 6df9fcd1f..6264efd6b 100644 --- a/code/index.html +++ b/code/index.html @@ -13,7 +13,6 @@

Temperature

City

Weather description

-

Sunrise:

Sunset:

diff --git a/code/script.js b/code/script.js index 2a8eb8816..42d0f63ef 100644 --- a/code/script.js +++ b/code/script.js @@ -15,9 +15,9 @@ const fiveDayForecast = document.getElementById('five-day-forecast') const weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] const weatherIcons = { - "scattered clouds": "/assets/design-1/Group16.png", // Cloudy - "few clouds": "/assets/design-1/Group34.png", // Few clouds - "clear sky": "/assets/design-1/Group37.png", // Sunny + "scattered clouds": "/code/assets/design-1/Group16.png", // Cloudy + "few clouds": "/code/assets/design-1/Group34.png", // Few clouds + "clear sky": "/code/assets/design-1/Group37.png", // Sunny } //Fetch todays weather From 6f7212db8b59a4c67f6b55b3601a1debd18e77d9 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 00:15:24 +0200 Subject: [PATCH 12/26] Update weather icaon paths --- code/script.js | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/code/script.js b/code/script.js index 42d0f63ef..6672c1c0d 100644 --- a/code/script.js +++ b/code/script.js @@ -15,10 +15,10 @@ const fiveDayForecast = document.getElementById('five-day-forecast') const weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] const weatherIcons = { - "scattered clouds": "/code/assets/design-1/Group16.png", // Cloudy - "few clouds": "/code/assets/design-1/Group34.png", // Few clouds - "clear sky": "/code/assets/design-1/Group37.png", // Sunny - } + "scattered clouds": "./assets/design-1/Group16.png", // Cloudy + "few clouds": "./assets/design-1/Group34.png", // Few clouds + "clear sky": "./assets/design-1/Group37.png", // Sunny +} //Fetch todays weather const fetchTodaysWeatherAsync = async (city) => { @@ -40,7 +40,8 @@ const fetchTodaysWeatherAsync = async (city) => { const weatherDescription = data.weather[0].description //Weather icon - const weatherIconURL = weatherIcons[weatherDescription] || "/assets/design-1/Group16.png"; // Default icon + const weatherIconURL = weatherIcons[weatherDescription] || "./assets/design-1/Group16.png"; // Default icon + console.log("Weather icon path:", weatherIconURL) document.getElementById("weather-icon").src = weatherIconURL @@ -84,7 +85,7 @@ const fetchForecastWeatherAsync = async (city) => { const weatherDescription = forecast.weather[0].description //Update HTML with weekday, temperture and icon - const forecastIconURL = weatherIcons[weatherDescription] || "/assets/design-1/Group16.png"; // Default icon + const forecastIconURL = weatherIcons[weatherDescription] || "./assets/design-1/Group16.png"; // Default icon fiveDayForecast.innerHTML += `

${dayName}: weather icon ${Math.round(forecast.main.temp)} °C

` }) From 13277fd925f1c0d45d8de9cd7c098396c8dcd56d Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 00:34:36 +0200 Subject: [PATCH 13/26] Add more CSS Styling --- code/index.html | 1 - code/styles.css | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/code/index.html b/code/index.html index 6264efd6b..1a7cf0af1 100644 --- a/code/index.html +++ b/code/index.html @@ -13,7 +13,6 @@

Temperature

City

Weather description

-

Sunrise:

Sunset:

diff --git a/code/styles.css b/code/styles.css index cb5470d79..a473f26bf 100644 --- a/code/styles.css +++ b/code/styles.css @@ -3,6 +3,15 @@ img { display: block; max-width: 100%; } + +/*Mobile*/ +@media screen and (max-width: 600px) { +.container { + padding: 10px; + max-width: 100%; + max-height: 100%; + } +} /* Tablet */ @media screen and (min-width: 501px) and (max-width: 1024px) { @@ -52,6 +61,11 @@ body { text-align: center; } + #weather-icon { + display: block; + margin: 0 auto; + width: 100px; +} .temperature h1 { font-size: 72px; font-weight: bold; @@ -67,6 +81,16 @@ body { .forecast { margin-top: 20px; } + + #five-day-forecast { + display: flex; + flex-direction: column; + align-items: center; +} + + .forecast #five-day-forecast { + text-align: center; +} .forecast #five-day-forecast p { font-size: 14px; @@ -78,14 +102,13 @@ body { .forecast-day { display: flex; - align-items: center; - justify-content: space-between; + align-items: center; + justify-content: center; padding: 10px 0; border-bottom: 1px solid #ddd; - } +} - .forecast img { - width: 24px; - height: 24px; - } +.forecast-day img { + margin-right: 10px; +} \ No newline at end of file From ed47e823b36d5d769bb3b42be8b147dbf9b10dd1 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 00:43:29 +0200 Subject: [PATCH 14/26] Change weekdays array to start with Sun --- code/script.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/script.js b/code/script.js index 6672c1c0d..86f5d30ef 100644 --- a/code/script.js +++ b/code/script.js @@ -12,7 +12,7 @@ const sunsetTime = document.getElementById("sunset") const fiveDayForecast = document.getElementById('five-day-forecast') //Array with weekdays -const weekdays = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] +const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] const weatherIcons = { "scattered clouds": "./assets/design-1/Group16.png", // Cloudy From d1063b3a63b267805b1b5e2bc86686f459ebc445 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 09:57:56 +0200 Subject: [PATCH 15/26] Adapt site to desktop --- code/index.html | 2 +- code/script.js | 4 ++-- code/styles.css | 11 +++++++---- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/code/index.html b/code/index.html index 1a7cf0af1..2723d8234 100644 --- a/code/index.html +++ b/code/index.html @@ -17,7 +17,7 @@

Weather description

Sunset:

-
+
diff --git a/code/script.js b/code/script.js index 86f5d30ef..82bb5b821 100644 --- a/code/script.js +++ b/code/script.js @@ -9,7 +9,7 @@ const description = document.getElementById("description") const temperature = document.getElementById("temperature") const sunriseTime = document.getElementById("sunrise") const sunsetTime = document.getElementById("sunset") -const fiveDayForecast = document.getElementById('five-day-forecast') +const fourDayForecast = document.getElementById('four-day-forecast') //Array with weekdays const weekdays = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] @@ -86,7 +86,7 @@ const fetchForecastWeatherAsync = async (city) => { //Update HTML with weekday, temperture and icon const forecastIconURL = weatherIcons[weatherDescription] || "./assets/design-1/Group16.png"; // Default icon - fiveDayForecast.innerHTML += `

${dayName}: weather icon ${Math.round(forecast.main.temp)} °C

` + fourDayForecast.innerHTML += `

${dayName}: weather icon ${Math.round(forecast.main.temp)} °C

` }) } catch (error) { diff --git a/code/styles.css b/code/styles.css index a473f26bf..c7708b15c 100644 --- a/code/styles.css +++ b/code/styles.css @@ -32,6 +32,8 @@ img { @media screen and (min-width: 1025px) { .container { width: 800px; + height: 100%; + margin-top: 40px; padding: 50px; } .temperature h1 { @@ -56,9 +58,10 @@ body { background: linear-gradient(to bottom, #d1c4e9, #fff); border-radius: 20px; box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.1); - padding: 20px; + padding: 50px;; width: 320px; text-align: center; + overflow-y: auto } #weather-icon { @@ -82,17 +85,17 @@ body { margin-top: 20px; } - #five-day-forecast { + #four-day-forecast { display: flex; flex-direction: column; align-items: center; } - .forecast #five-day-forecast { + .forecast #four-day-forecast { text-align: center; } - .forecast #five-day-forecast p { + .forecast #four-day-forecast p { font-size: 14px; color: #333; margin: 5px 0; From 8fe39b228ca61e1b4b0e09bad9011af9820c5c20 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 10:04:21 +0200 Subject: [PATCH 16/26] Add cnt=32 to forecastURL to display 4 day forecast instead of default --- code/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/script.js b/code/script.js index 82bb5b821..fc00d95df 100644 --- a/code/script.js +++ b/code/script.js @@ -61,8 +61,8 @@ fetchTodaysWeatherAsync("Las Vegas") //Fetch forecast weather const fetchForecastWeatherAsync = async (city) => { - const forecastURL = `${forecastBaseURL}q=${city}&units=metric&appid=${api_key}` - // units=metric to get temperatures in Celcius + const forecastURL = `${forecastBaseURL}q=${city}&units=metric&cnt=32&appid=${api_key}` + // units=metric to get temperatures in Celcius and cnt=32 for a 4 day forecast try { const response = await fetch(`${forecastURL}`) if (!response.ok) { From 9d83dc2afd2a92c48fc65c9b25a44ad5a0dd9a6f Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 10:08:17 +0200 Subject: [PATCH 17/26] Add padding and margin to CSS. Change background color. --- code/styles.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/code/styles.css b/code/styles.css index c7708b15c..179cac8fa 100644 --- a/code/styles.css +++ b/code/styles.css @@ -8,6 +8,7 @@ img { @media screen and (max-width: 600px) { .container { padding: 10px; + margin-top: 10px; max-width: 100%; max-height: 100%; } @@ -17,7 +18,8 @@ img { @media screen and (min-width: 501px) and (max-width: 1024px) { .container { width: 600px; - padding: 40px; + margin-top: 40px; + padding: 50px; } .temperature h1 { @@ -51,13 +53,14 @@ body { justify-content: center; align-items: center; height: 100vh; - background-color: #f5f5f5; + background-color: #d1c4e9; } .container { background: linear-gradient(to bottom, #d1c4e9, #fff); border-radius: 20px; box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.1); + margin-top: 40px; padding: 50px;; width: 320px; text-align: center; From 1b94468b36dbfc1d7499f80b3ffe65704be69d4b Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 10:12:58 +0200 Subject: [PATCH 18/26] Update code --- code/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/script.js b/code/script.js index fc00d95df..e6d4588db 100644 --- a/code/script.js +++ b/code/script.js @@ -46,8 +46,8 @@ const fetchTodaysWeatherAsync = async (city) => { //Convert Sunset/Sunrise from seconds to milliseconds by multiplying by 1000, which the date object requires - const sunrise = new Date(data.sys.sunrise * 1000).toLocaleTimeString() - const sunset = new Date(data.sys.sunset * 1000).toLocaleTimeString() + const sunrise = new Date(data.sys.sunrise * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) + const sunset = new Date(data.sys.sunset * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) sunriseTime.innerHTML = `Sunrise: ${sunrise}` sunsetTime.innerHTML = `Sunset: ${sunset}` From 2ced24fcd994a34e3841923bb8bb3cb7d1a77312 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 12:57:15 +0200 Subject: [PATCH 19/26] Remove todays forcast in the forecastDate filter. Add a const for today for comparison in the forecast. --- code/.DS_Store | Bin 0 -> 6148 bytes code/script.js | 41 +++++++++++++++++++++-------------------- 2 files changed, 21 insertions(+), 20 deletions(-) create mode 100644 code/.DS_Store diff --git a/code/.DS_Store b/code/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 { - const forecastURL = `${forecastBaseURL}q=${city}&units=metric&cnt=32&appid=${api_key}` - // units=metric to get temperatures in Celcius and cnt=32 for a 4 day forecast + const forecastURL = `${forecastBaseURL}q=${city}&units=metric&cnt=40&appid=${api_key}` + // units=metric to get temperatures in Celcius and cnt=40 for a 5 day forecast, then we remove todays forecast try { const response = await fetch(`${forecastURL}`) if (!response.ok) { throw new Error("Failed to fetch forecast weather data") - } - //convert response to JSON - const data = await response.json() - - //Filter forecast on 12:00 - const filteredForecast = data.list.filter(forecast => { - const forecastDate = new Date(forecast.dt_txt) - return forecastDate.getHours() === 12 - }) - - filteredForecast.forEach(forecast => { - let forecastDate = new Date(forecast.dt_txt)//Convert date to Date const - let dayName = weekdays[forecastDate.getDay()] // Get weekday + } + //convert response to JSON + const data = await response.json() - //Get weather icon - const weatherDescription = forecast.weather[0].description + //Filter forecast on 12:00 + const filteredForecast = data.list.filter(forecast => { + const forecastDate = new Date(forecast.dt_txt) + return forecastDate.getHours() === 12 && forecastDate.getDate() !== today + }) + filteredForecast.forEach(forecast => { + let forecastDate = new Date(forecast.dt_txt)//Convert date to Date const + let dayName = weekdays[forecastDate.getDay()] // Get weekday + // Get weather icon + const weatherDescription = forecast.weather[0].description - //Update HTML with weekday, temperture and icon - const forecastIconURL = weatherIcons[weatherDescription] || "./assets/design-1/Group16.png"; // Default icon - fourDayForecast.innerHTML += `

${dayName}: weather icon ${Math.round(forecast.main.temp)} °C

` + //Update HTML with weekday, temperture and icon + const forecastIconURL = weatherIcons[weatherDescription] || "./assets/design-1/Group16.png"; // Default icon + fourDayForecast.innerHTML += `

${dayName}: weather icon ${Math.round(forecast.main.temp)} °C

` }) } catch (error) { From 74d16eca0a8a4fc6c8ea91ab4f439c63b90b4b5a Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 14:42:31 +0200 Subject: [PATCH 20/26] Add README-file. Update the BASE_URL and forecastBaseURL for better URL management. --- README.md | 21 +++++++++++++++++---- code/script.js | 7 +++---- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 021fedb6c..8dacc332c 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,25 @@ # Weather App -Replace this readme with your own information about your project. - -Start by briefly describing the assignment in a sentence or two. Keep it short and to the point. +The assignment is to fetch data from an API using fetch() in JavaScript and create an app should have a city name, current temperature, weather description, sunrise/sunset time, and a 4-day forecast. The data should be presented in a user-friendly format, and the app should be responsive to different devices. ## The problem -Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next? +## Time +This project was fun to work with and I wish I had more time. + +I made a plan, and stuck to it, which was good. The plan was the following: +1. Create HTML File: Set up an HTML file with (the required) fields for city name, current temperature, weather description, sunrise and sunset times, and placeholders for the forecast. +2. Add API URL and Endpoints: Create API URL and endpoints in the JavaScript file, and set up the DOM Selectors. +3. Fetch today’s weather: Use async/await to fetch today's weather, convert the response to json format, populate the innerHTML, and add the error handling. When all fields for today's weather are fetched and displayed, start with the forecast. +4. Fetch and display Forecast: Retrieve and display the forecast dataFetch and display the Forecast data. +5. Format the data: Ensure the data is correctly formatted. +6. Design and responsiveness: Work on the design and make the site responsive. + +All went smoothly until I began working on the forecast. I had go back in the material (especially the Live sessions) multiple times just to get a hang of what I was expected to do next. On top of that there were so many JavaScript default behaviors that I needed to find solutions for, such as JavaScript weeks start on Sunday and the need to convert sunset times from seconds to milliseconds. These were fun challenges but I needed more time. As a result, the design part isn't fully completed. + +## If I had more time +I would improve my code by updating the BASE_URL and forecastBaseURL for better URL management, create a constant for updating the HTML to keep the functions clean, and find a way to combine the "calls" for today’s weather and the forecast into a single "call". Fetch and display lowest and highest temperature. Use images from the API, instead of using only the three that came along in the assets. + ## View it live diff --git a/code/script.js b/code/script.js index 025fbe1a4..f60222f81 100644 --- a/code/script.js +++ b/code/script.js @@ -1,6 +1,5 @@ //API URL and Endpoints -const BASE_URL = "https://api.openweathermap.org/data/2.5/weather?" -const forecastBaseURL = "https://api.openweathermap.org/data/2.5/forecast?" +const BASE_URL = "https://api.openweathermap.org/data/2.5/" const api_key = "617b18d1663716ef276314bb0808d62b" // DOM Selectors @@ -25,7 +24,7 @@ const weatherIcons = { //Fetch todays weather const fetchTodaysWeatherAsync = async (city) => { - const todayURL = `${BASE_URL}q=${city}&units=metric&APPID=${api_key}` + const todayURL = `${BASE_URL}weather?q=${city}&units=metric&APPID=${api_key}` // units=metric to get temperatures in Celcius try { const response = await fetch(`${todayURL}`) @@ -64,7 +63,7 @@ fetchTodaysWeatherAsync("Las Vegas") //Fetch forecast weather const fetchForecastWeatherAsync = async (city) => { - const forecastURL = `${forecastBaseURL}q=${city}&units=metric&cnt=40&appid=${api_key}` + const forecastURL = `${BASE_URL}forecast?q=${city}&units=metric&cnt=40&appid=${api_key}` // units=metric to get temperatures in Celcius and cnt=40 for a 5 day forecast, then we remove todays forecast try { const response = await fetch(`${forecastURL}`) From 85b8caee26230d4c4ba966ba1c92cca4fb1e647b Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 15:00:34 +0200 Subject: [PATCH 21/26] Update README file. Fix height issues on container for Desktop. --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8dacc332c..5f13d4139 100644 --- a/README.md +++ b/README.md @@ -18,9 +18,8 @@ I made a plan, and stuck to it, which was good. The plan was the following: All went smoothly until I began working on the forecast. I had go back in the material (especially the Live sessions) multiple times just to get a hang of what I was expected to do next. On top of that there were so many JavaScript default behaviors that I needed to find solutions for, such as JavaScript weeks start on Sunday and the need to convert sunset times from seconds to milliseconds. These were fun challenges but I needed more time. As a result, the design part isn't fully completed. ## If I had more time -I would improve my code by updating the BASE_URL and forecastBaseURL for better URL management, create a constant for updating the HTML to keep the functions clean, and find a way to combine the "calls" for today’s weather and the forecast into a single "call". Fetch and display lowest and highest temperature. Use images from the API, instead of using only the three that came along in the assets. - +I would improve my code by create a constant for updating the HTML to keep the functions clean, and find a way to combine the "calls" for today’s weather and the forecast into a single "call". Fetch and display lowest and highest temperature. Use images from the API, instead of using only the three that came along in the assets. And of course, pay more attention to the design. ## View it live -project-weather-app-by-joe +LINK: https://project-weather-app-by-joe.netlify.app/ From eafc9ec8ba09002eab2177e8734d55b821eab860 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 15:23:14 +0200 Subject: [PATCH 22/26] Add margin and padding on body for desktop --- code/styles.css | 35 +++++++++++++++++++++-------------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/code/styles.css b/code/styles.css index 179cac8fa..f61d4ef70 100644 --- a/code/styles.css +++ b/code/styles.css @@ -6,22 +6,28 @@ img { /*Mobile*/ @media screen and (max-width: 600px) { -.container { - padding: 10px; - margin-top: 10px; - max-width: 100%; - max-height: 100%; + body { + margin-top: 10px; + } + .container { + padding: 10px; + margin-top: 10px; + max-width: 100%; + max-height: 100%; } } /* Tablet */ @media screen and (min-width: 501px) and (max-width: 1024px) { + body { + padding: 10px; + margin: 40px; + } .container { - width: 600px; + width: 800px; margin-top: 40px; padding: 50px; } - .temperature h1 { font-size: 60px; } @@ -32,11 +38,12 @@ img { } /* Desktop */ @media screen and (min-width: 1025px) { + body { + padding: 10px; + margin: 40px; + } .container { - width: 800px; - height: 100%; - margin-top: 40px; - padding: 50px; + width: 100%; } .temperature h1 { font-size: 72px; @@ -47,8 +54,6 @@ img { } body { font-family: 'Arial', sans-serif; - margin: 0; - padding: 0; display: flex; justify-content: center; align-items: center; @@ -61,8 +66,9 @@ body { border-radius: 20px; box-shadow: 0px 5px 15px rgba(0, 0, 0, 0.1); margin-top: 40px; - padding: 50px;; + padding: 50px; width: 320px; + height: 100%; text-align: center; overflow-y: auto } @@ -96,6 +102,7 @@ body { .forecast #four-day-forecast { text-align: center; + margin: 5px; } .forecast #four-day-forecast p { From f6411c9e12d900ed010322891082790f715efc76 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 19:56:59 +0200 Subject: [PATCH 23/26] Add footer to the HTML --- code/index.html | 1 + 1 file changed, 1 insertion(+) diff --git a/code/index.html b/code/index.html index 2723d8234..bd0fa511e 100644 --- a/code/index.html +++ b/code/index.html @@ -23,5 +23,6 @@

Weather description

+
2024-09-15 Johanna Eriksson
\ No newline at end of file From c6373335ce249865b423c48fc14f2381f61f7cf3 Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Mon, 30 Sep 2024 20:08:37 +0200 Subject: [PATCH 24/26] Add more css to footer --- code/index.html | 4 +++- code/styles.css | 15 ++++++++++++--- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/code/index.html b/code/index.html index bd0fa511e..a59350f64 100644 --- a/code/index.html +++ b/code/index.html @@ -21,8 +21,10 @@

Weather description

+
+
2024-09-29 Johanna Eriksson
+
-
2024-09-15 Johanna Eriksson
\ No newline at end of file diff --git a/code/styles.css b/code/styles.css index f61d4ef70..2e6576da5 100644 --- a/code/styles.css +++ b/code/styles.css @@ -6,9 +6,6 @@ img { /*Mobile*/ @media screen and (max-width: 600px) { - body { - margin-top: 10px; - } .container { padding: 10px; margin-top: 10px; @@ -124,4 +121,16 @@ body { .forecast-day img { margin-right: 10px; } + +footer { + display: flex; + justify-content: center; + margin-top: 20px; + color: #fff; + background-color: #d1c4e9; + border-radius: 20px; + border-style: dotted; + padding: 10px; + margin-top: 20px; +} \ No newline at end of file From a41b834041490c9532c94d1318dedeb0d5bfbb6f Mon Sep 17 00:00:00 2001 From: Johanna Eriksson Date: Thu, 10 Oct 2024 09:49:47 +0200 Subject: [PATCH 25/26] Give sunrise and sunset the correct local time zone --- code/script.js | 9 ++++++--- code/styles.css | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/code/script.js b/code/script.js index f60222f81..f448d1bc5 100644 --- a/code/script.js +++ b/code/script.js @@ -47,9 +47,12 @@ const fetchTodaysWeatherAsync = async (city) => { document.getElementById("weather-icon").src = weatherIconURL - //Convert Sunset/Sunrise from seconds to milliseconds by multiplying by 1000, which the date object requires - const sunrise = new Date(data.sys.sunrise * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) - const sunset = new Date(data.sys.sunset * 1000).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) + //Sunset/Sunrise + + //Convert Time zone and Sunset / Sunrise from seconds to milliseconds by multiplying by 1000, which the date object requires + const localTimezone = data.timezone * 1000 + const sunrise = new Date((data.sys.sunrise * 1000) + localTimezone).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) + const sunset = new Date((data.sys.sunset * 1000) + localTimezone).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' }) sunriseTime.innerHTML = `Sunrise: ${sunrise}` sunsetTime.innerHTML = `Sunset: ${sunset}` diff --git a/code/styles.css b/code/styles.css index 2e6576da5..9f00d03d7 100644 --- a/code/styles.css +++ b/code/styles.css @@ -12,6 +12,9 @@ img { max-width: 100%; max-height: 100%; } + footer { + width: 300px; + } } /* Tablet */ From 918d8531b92210d9b61b64a9099ae62c8315f91b Mon Sep 17 00:00:00 2001 From: Johanna Eriksson <43312637+joheri1@users.noreply.github.com> Date: Wed, 11 Dec 2024 22:00:23 +0100 Subject: [PATCH 26/26] Update script.js --- code/script.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/script.js b/code/script.js index f448d1bc5..24b1f294f 100644 --- a/code/script.js +++ b/code/script.js @@ -1,6 +1,6 @@ //API URL and Endpoints const BASE_URL = "https://api.openweathermap.org/data/2.5/" -const api_key = "617b18d1663716ef276314bb0808d62b" +const api_key = "xxx" // DOM Selectors const cityName = document.getElementById("city") @@ -97,4 +97,4 @@ const fetchForecastWeatherAsync = async (city) => { console.error("Error when fetching the forecast", error) } } -fetchForecastWeatherAsync("Las Vegas") \ No newline at end of file +fetchForecastWeatherAsync("Las Vegas")