-
Notifications
You must be signed in to change notification settings - Fork 577
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Annas Weather App #418
Open
Anna2024WebDev
wants to merge
19
commits into
Technigo:master
Choose a base branch
from
Anna2024WebDev:master
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Annas Weather App #418
Changes from 17 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
752bb61
added HTML, CSS and API key + URL to JS
Anna2024WebDev 77dea67
fetch and converted sunset/sunrise time and updated CSS
Anna2024WebDev d26b6f1
added function with if/else statements to change background color
Anna2024WebDev 13730e4
added function to change color of background and fonts depending on w…
Anna2024WebDev 87fb4f4
fetched forecast data and created a loop for the first 5 days weather…
Anna2024WebDev a104759
added search bar and added event listeners to search on click also ch…
Anna2024WebDev 16a0a79
added more weather pictures and changed some texts in JS
Anna2024WebDev 960089a
small adjustments
Anna2024WebDev fb67fca
small fix
Anna2024WebDev 245d0f1
updated title and readme file
Anna2024WebDev a2089a5
updated color button in JS
Anna2024WebDev 40a91b8
small fix button font
Anna2024WebDev 9ccfec6
Update README.md
Anna2024WebDev 7998b89
css fix
Anna2024WebDev 6cef388
Merge branch 'master' of https://github.com/Anna2024WebDev/project-we…
Anna2024WebDev 39c4131
fixed sunset/sunrise timezone offset
Anna2024WebDev 7eb361b
added min/max temp
Anna2024WebDev 03877ea
updated HTML and JS indentation, added new date object to be able to …
Anna2024WebDev 2e24140
added function to capitalize letters in cities when fetching data
Anna2024WebDev File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"liveServer.settings.port": 5501 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,15 @@ | ||
# 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. | ||
This week the project was to create a weather app by using APIs and using different methods to retrieve and convert the data, such as fetch and convert unix time. | ||
|
||
## 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? | ||
I started with adding the HTML and CSS code. Then I moved on to JS where I added the API and console.logged it. Then I moved on to adding the DOM selectors and created the first function to fetch the current weather data and sunset/sunrise time. After this was achived I moved on to converting the sunset/sunrise time. I needed help from chatGPT to achieve this and also how to get the forecast data which was not as straight forward as the current weather data. | ||
|
||
Then I also managed to change the background color, color (fonts) and images depending on weather description, for this I used if/if else statements. | ||
|
||
If I had more time I would also look into the geolocation API. | ||
|
||
## 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. | ||
https://checkthe-weather.netlify.app/ |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File renamed without changes
File renamed without changes
File renamed without changes
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>Weather or Not</title> | ||
<link rel="stylesheet" type="text/css" href="./style.css"> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100..900;1,100..900&display=swap" rel="stylesheet"> | ||
<title>Check the Weather</title> | ||
</head> | ||
<body> | ||
<main><!-- Temperature and Condition Info --> | ||
<section class="weather-container" id="weatherContainer"> | ||
<div class="temperature-info"> | ||
<p id="condition"></p> | ||
<p>|</p> | ||
<p id="temperature"></p> | ||
</div> | ||
<!-- Sunset and Sunrise Info --> | ||
<div class="sun-times"> | ||
<p>sunrise <span id="sunriseTime"></span></p> | ||
<p>sunset <span id="sunsetTime"></span></p> | ||
</div> | ||
<img id="weatherImage" class="weather-img" src="" alt="Weather Image"> | ||
<p id="weatherMessage" class="weather-message"></p> <!-- Placeholder for dynamic weather message --> | ||
<section class="forecast-wrapper" id="forecastWrapper"> | ||
<ul id="forecastList"></ul> <!-- List items will be dynamically added here --> | ||
<div id="searchContainer"> | ||
<!-- <label for="cityInput">City:</label> --> | ||
<input type="text" id="cityInput" placeholder="Type a city.."> | ||
<button id="searchButton">Search</button> | ||
</div> | ||
</section> | ||
</main> | ||
<script src="./script.js"></script> | ||
<body> | ||
</html> | ||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
// Current weather API | ||
// ea9a90c62aeaaa3811505087d195520e | ||
// Base URL + API key | ||
//https://api.openweathermap.org/data/2.5/weather?q=Stockholm,Sweden&units=metric&APPID=ea9a90c62aeaaa3811505087d195520e | ||
//https://api.openweathermap.org/data/2.5/forecast?q=Stockholm,Sweden&units=metric&APPID=ea9a90c62aeaaa3811505087d195520e | ||
|
||
// True constants (SNAKECASE) | ||
const API_KEY = "ea9a90c62aeaaa3811505087d195520e"; | ||
const BASE_URL = "https://api.openweathermap.org/data/2.5/weather?q="; | ||
const FORECAST_BASE_URL = "https://api.openweathermap.org/data/2.5/forecast?q="; | ||
|
||
let CITY = "Stockholm"; // Dynamic city variable | ||
|
||
// DOM Selectors | ||
const temperatureDisplay = document.getElementById("temperature"); | ||
const conditionDisplay = document.getElementById("condition"); | ||
const sunriseDisplay = document.getElementById("sunriseTime"); | ||
const sunsetDisplay = document.getElementById("sunsetTime"); | ||
const weatherImg = document.getElementById("weatherImage"); | ||
const weatherMsg = document.getElementById("weatherMessage"); | ||
const forecastList = document.getElementById("forecastList"); | ||
const searchButton = document.getElementById("searchButton"); | ||
const cityInput = document.getElementById("cityInput"); | ||
|
||
// Function to fetch weather data | ||
function fetchWeatherData() { | ||
const URL = `${BASE_URL}${CITY}&units=metric&APPID=${API_KEY}`; | ||
const FORECAST_URL = `${FORECAST_BASE_URL}${CITY}&units=metric&APPID=${API_KEY}`; | ||
|
||
// Fetch current weather data | ||
fetch(URL) | ||
.then(response => response.json()) | ||
.then(data => { | ||
if (!data || data.cod !== 200) { | ||
throw new Error('City not found') | ||
} | ||
const stockholmTemp = data.main.temp; | ||
const weatherCondition = data.weather[0].description; | ||
const roundedTemp = Math.round(stockholmTemp); | ||
const sunrise = data.sys.sunrise; | ||
const sunset = data.sys.sunset; | ||
const timezoneOffset = data.timezone; // Timezone offset in seconds | ||
|
||
temperatureDisplay.innerText = `${roundedTemp}°C`; | ||
conditionDisplay.innerText = `${weatherCondition}`; | ||
|
||
// Function to convert UNIX timestamp to readable time format (24-hour clock) | ||
const convertUnixToTime = (unixTimestamp, timezoneOffset) => { | ||
const date = new Date((unixTimestamp + timezoneOffset)* 1000); | ||
const hours = date.getUTCHours(); | ||
const minutes = String(date.getUTCMinutes()).padStart(2, '0'); | ||
return `${hours}:${minutes}`; | ||
} | ||
// Convert and display sunrise and sunset times with timezone offset (so it is local time showing for the selected city) | ||
const sunriseTime = convertUnixToTime(sunrise, timezoneOffset); | ||
const sunsetTime = convertUnixToTime(sunset, timezoneOffset); | ||
sunriseDisplay.innerText = `${sunriseTime}`; | ||
sunsetDisplay.innerText = `${sunsetTime}`; | ||
|
||
updateUI(roundedTemp, weatherCondition); | ||
}) | ||
.catch(error => console.error('Error fetching weather data:', error)); | ||
|
||
fetch(FORECAST_URL) | ||
.then(response => response.json()) | ||
.then(forecastData => { | ||
forecastList.innerHTML = ''; | ||
|
||
const today = new Date(); | ||
|
||
// Loop through the next 5 days | ||
for (let i = 1; i <= 5; i++) { | ||
const forecastDate = new Date(today); | ||
forecastDate.setDate(today.getDate() + i); | ||
const forecastDateString = forecastDate.toISOString().split('T')[0]; | ||
|
||
// Filter forecasts for this specific date | ||
const dailyForecasts = forecastData.list.filter(item => { | ||
const itemDate = new Date(item.dt * 1000).toISOString().split('T')[0]; | ||
return itemDate === forecastDateString; | ||
}); | ||
|
||
if (dailyForecasts.length > 0) { | ||
// Initialize min and max temperature variables | ||
let minTemp = Infinity; | ||
let maxTemp = -Infinity; | ||
|
||
// Calculate min and max temperatures for the day | ||
dailyForecasts.forEach(item => { | ||
const temp = Math.round(item.main.temp); | ||
|
||
if (temp < minTemp) { | ||
minTemp = temp; | ||
} | ||
if (temp > maxTemp) { | ||
maxTemp = temp; | ||
} | ||
}); | ||
|
||
const weekDay = forecastDate.toLocaleDateString('en-US', { weekday: 'long' }); | ||
|
||
const listItem = document.createElement('li'); | ||
listItem.innerHTML = `${weekDay}: <span class="min-temp">${minTemp} / <span class="max-temp">${maxTemp}°C</span>`; | ||
forecastList.appendChild(listItem); | ||
} | ||
} | ||
}) | ||
|
||
.catch(error => console.error('Error fetching forecast data:', error)); | ||
} | ||
|
||
// Initial fetch for the default city | ||
fetchWeatherData(); | ||
|
||
// Event listener for the search button | ||
searchButton.addEventListener("click", () => { | ||
CITY = cityInput.value.trim(); // Update city variable with input value | ||
if (CITY) { | ||
fetchWeatherData(); // Fetch new weather data for the entered city | ||
} | ||
}); | ||
|
||
// Event listener for the Enter key in the input field | ||
cityInput.addEventListener("keypress", (event) => { | ||
if (event.key === "Enter") { // Check if the pressed key is Enter | ||
searchButton.click(); // Trigger the click event of the search button | ||
} | ||
}); | ||
|
||
function updateUI(temperature, weatherDescription) { | ||
const weatherContainer = document.getElementById("weatherContainer"); | ||
const searchButton = document.getElementById ("searchButton") | ||
const currentTime = new Date(); // Get the current time | ||
const sunset = new Date(sunsetTime * 1000); // Convert sunset time (already fetched) to Date object | ||
let weatherMessage; // Use let since the variable weatherMessage will change depending on weather | ||
|
||
// Update background and text color based on weather condition | ||
if (weatherDescription.toLowerCase().includes("rain") || | ||
weatherDescription.toLowerCase().includes("drizzle") || | ||
weatherDescription.toLowerCase().includes("mist")) { | ||
weatherContainer.style.backgroundColor = "#BDE8FA"; // Blue for rain | ||
weatherContainer.style.color = "#164A68"; // Rainy font color | ||
searchButton.style.backgroundColor ="#164A68" | ||
weatherImg.src = "assets/design-2/noun_Umbrella.svg"; | ||
weatherMessage = `Don’t forget your umbrella.<br>It’s wet in ${CITY} today.`; | ||
|
||
} else if (weatherDescription.toLowerCase().includes("few clouds")) { | ||
weatherContainer.style.backgroundColor = "#F7E9B9"; // Yellow for clear sky | ||
weatherContainer.style.color = "#2A5510"; // Green font color | ||
searchButton.style.backgroundColor ="#2A5510" | ||
weatherImg.src = "assets/design-2/noun_Sunglasses.svg"; | ||
weatherMessage = `Get your sunnies on. There are a few clouds, but it's still a lovely day in ${CITY}.`; | ||
|
||
} else if (weatherDescription.toLowerCase().includes("scattered clouds")) { | ||
weatherContainer.style.backgroundColor = "#F7E9B9"; // Yellow for clear sky | ||
weatherContainer.style.color = "#2A5510"; // Green font color | ||
searchButton.style.backgroundColor ="#2A5510" | ||
weatherImg.src = "assets/design-2/noun_cloud.svg"; | ||
weatherMessage = `There are some scattered clouds, but it's still a lovely day in ${CITY}.`; | ||
|
||
} else if (weatherDescription.toLowerCase().includes("clear")) { | ||
// Daytime clear sky | ||
weatherContainer.style.backgroundColor = "#F7E9B9"; // Yellow for clear sky | ||
weatherContainer.style.color = "#2A5510"; // Green font color | ||
searchButton.style.backgroundColor ="#2A5510" | ||
weatherImg.src = "assets/design-2/noun_Sunglasses.svg"; | ||
weatherMessage = `Get your sunnies on.<br>${CITY} is looking rather great today.`; | ||
|
||
// Check if it's after sunset for clear skies | ||
if (currentTime > sunset) { | ||
// Sunset condition | ||
weatherContainer.style.backgroundColor = "#F7E9B9"; // Keep the yellow for sunset | ||
weatherContainer.style.color = "#F47775"; // Orange font color | ||
searchButton.style.backgroundColor ="#F47775" | ||
weatherImg.src = "assets/design-2/sunset.png"; // Change to sunset image | ||
weatherMessage = `The sun has set.<br>Enjoy the evening and night in ${CITY}!`; | ||
} | ||
} else if (weatherDescription.toLowerCase().includes("clouds") || | ||
weatherDescription.toLowerCase().includes("fog") || | ||
weatherDescription.toLowerCase().includes("haze")) { | ||
weatherContainer.style.backgroundColor = "#FFFFFF"; // White background | ||
weatherContainer.style.color = "#F47775"; // Orange font color | ||
searchButton.style.backgroundColor ="#F47775" | ||
weatherImg.src = "assets/design-2/noun_Cloud.svg"; | ||
weatherMessage = `Light a fire and get cosy.<br>${CITY} is looking grey today.`; | ||
|
||
} else if (weatherDescription.toLowerCase().includes("snow")) { | ||
weatherContainer.style.backgroundColor = "#BDE8FA"; // Blue for cold weather | ||
weatherContainer.style.color = "#164A68"; // Blue font color | ||
searchButton.style.backgroundColor ="#164A68" //Blue font color | ||
weatherImg.src = "assets/design-2/snow.png"; | ||
weatherMessage = `It is snowing today in ${CITY}.<br> Put on your winter clothes and get ready to play in the snow!`; | ||
|
||
} else if (weatherDescription.toLowerCase().includes("thunderstorm")) { | ||
weatherContainer.style.backgroundColor = "#BDE8FA"; // Blue for storm | ||
weatherContainer.style.color = "#164A68"; // Blue font color | ||
searchButton.style.backgroundColor ="#164A68" //Blue font color | ||
weatherImg.src = "assets/design-2/thunderstorm.png"; | ||
weatherMessage = `Stormy weather ahead in ${CITY} today!<br> Seek shelter and avoid outdoor activities.`; | ||
} else { | ||
weatherContainer.style.backgroundColor = "white"; // Fallback background | ||
weatherContainer.style.color = "black"; // Fallback font color | ||
searchButton.style.backgroundColor ="black" //Blue font color | ||
weatherImg.src = "assets/design-2/sad-face-3.svg"; | ||
weatherMessage = `The weather description cannot be picked up at the moment.`; | ||
} | ||
|
||
weatherMsg.innerHTML = weatherMessage; // Update the weather message display | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove all empty lines
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for your feedback @HIPPIEKICK! I think I have updated according to the changes requested! Best, Anna