Skip to content

Weather App - Team Fire 2 #19

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

Open
wants to merge 74 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
c12da6d
Created HTML, CSS and JavaScript files.
oskarnordin Mar 17, 2025
35c885f
added index startcode
ssofiejohansson Mar 17, 2025
c8d04fe
Linked the script.js and style.css to the HTML.
solen80a Mar 17, 2025
d0d6af2
Added a index.ts and compiled typescript to javascript.
solen80a Mar 17, 2025
6e86574
Added a HTML base.
solen80a Mar 18, 2025
fdf644a
button edit html
ssofiejohansson Mar 18, 2025
877ba97
added id/classes html
ssofiejohansson Mar 18, 2025
4a3ba5e
Added a fetch from the API.
solen80a Mar 18, 2025
43b400e
first set on styling
ssofiejohansson Mar 18, 2025
87f2022
styling done w 3 different classes
ssofiejohansson Mar 18, 2025
d36a0a6
Co-authored-by: Varvara Slugina <[email protected]>
solen80a Mar 18, 2025
50bfa6f
???
solen80a Mar 18, 2025
1aa8f79
Merge branch 'main' of https://github.com/oskarnordin/js-project-weat…
solen80a Mar 18, 2025
e8f9ae6
Added js to show city name.
solen80a Mar 18, 2025
4e488e5
centered content
ssofiejohansson Mar 18, 2025
1a096d1
Test
ssofiejohansson Mar 18, 2025
d855b69
Syncar changes
ssofiejohansson Mar 18, 2025
539c008
test1
ssofiejohansson Mar 18, 2025
1dc8726
update city sunrise
ssofiejohansson Mar 18, 2025
16a9318
Converting sunset/sunrise code to time.
oskarnordin Mar 18, 2025
6734dad
added update weather + temperature
oskarnordin Mar 18, 2025
6df3516
css animation
ssofiejohansson Mar 18, 2025
c6fa094
.
oskarnordin Mar 18, 2025
d873209
Merge branch 'main' of https://github.com/oskarnordin/js-project-weat…
oskarnordin Mar 18, 2025
8678bc3
Added search function.
oskarnordin Mar 18, 2025
291ed9f
added correct png images
ssofiejohansson Mar 19, 2025
8ba438e
changed and added animation
ssofiejohansson Mar 19, 2025
377aff0
styled animation
ssofiejohansson Mar 19, 2025
a93d1f0
converted to svg img
ssofiejohansson Mar 19, 2025
efe18c7
Removed index.ts and added script.ts
solen80a Mar 19, 2025
a99d8b7
Reverted my changes
solen80a Mar 19, 2025
5b627ad
changed the h2 text depending on weather
ssofiejohansson Mar 19, 2025
44b051c
added 3 city url
ssofiejohansson Mar 19, 2025
d95c405
styled images/icons
ssofiejohansson Mar 19, 2025
b425fba
changed some descriptions.
solen80a Mar 19, 2025
aeb661c
Merge branch 'main' of https://github.com/oskarnordin/js-project-weat…
solen80a Mar 19, 2025
334ea16
html edits
ssofiejohansson Mar 19, 2025
b4c1be2
Add forecast functionality.
oskarnordin Mar 19, 2025
9867f18
added Varias code and weather forecast
ssofiejohansson Mar 19, 2025
60ec10c
styling etc
ssofiejohansson Mar 19, 2025
e27f36f
Add weather icons.
oskarnordin Mar 19, 2025
2021a16
made the input empty after search
ssofiejohansson Mar 19, 2025
a51a7b6
space betweeen in list
ssofiejohansson Mar 19, 2025
c1953ce
minor styling
ssofiejohansson Mar 19, 2025
258775b
Updated typescript file with new js code.
solen80a Mar 19, 2025
995e077
Added netlify URL to readme.md
solen80a Mar 19, 2025
ff054a9
moved right arrow and changed some padding styling
ssofiejohansson Mar 19, 2025
285602d
made cloud slightly bigger
ssofiejohansson Mar 19, 2025
2d79575
Added forecast code to typescript.
solen80a Mar 20, 2025
b89b4cc
styling padding last min touches
ssofiejohansson Mar 20, 2025
86641cf
sync
ssofiejohansson Mar 20, 2025
bff5066
removed unneccesary css code
ssofiejohansson Mar 20, 2025
a8ff322
added backgroundcolor and color to body, to avoid white page while lo…
solen80a Mar 20, 2025
ea44bd8
Fixed error with the dates in the forecast and connected .ts to .js
solen80a Mar 20, 2025
4efa4c2
Added comments and changed the citys.
solen80a Mar 20, 2025
79f002a
Added more comments and changed the title in HTML.
solen80a Mar 20, 2025
c357b42
Cleared input after a search
ssofiejohansson Mar 20, 2025
f92c682
Fixed date and temp to be === 12, updated typescript.
solen80a Mar 20, 2025
663821f
syncing my changes
solen80a Mar 20, 2025
1cef895
Updates to scrip.js
solen80a Mar 20, 2025
55659ea
cleaned up code
ssofiejohansson Mar 20, 2025
573ba51
added snow icon and weather
ssofiejohansson Mar 20, 2025
d63480e
Update README.md
VariaSlu Mar 21, 2025
6f3c27d
Update README.md
VariaSlu Mar 21, 2025
b5f2201
Update README.md
VariaSlu Mar 21, 2025
d71226f
Update README.md
VariaSlu Mar 21, 2025
23185bd
Update README.md
VariaSlu Mar 21, 2025
148590c
Update README.md
VariaSlu Mar 21, 2025
1dc6b7d
Update README.md
VariaSlu Mar 21, 2025
37e7505
get
solen80a Mar 21, 2025
9031e57
corrected my local repo.
solen80a Mar 21, 2025
3ad22bf
Removed console.logs unessesary comment. Fixed the offset timezone, a…
solen80a Mar 21, 2025
92f8012
Update README.md
oskarnordin Mar 23, 2025
4593c1b
Changed to .slice(1, 5)
solen80a Mar 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added .DS_Store
Binary file not shown.
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,12 @@
# js-project-weather-app
# js-project-weather-app
HeatherWeather is a sleek and responsive weather app built with TypeScript. This app fetches data from the OpenWeather API and features UI with animations that enhance the user experience. It adapts perfectly to different screen sizes for a seamless experience.

Features:
1. Real-time weather updates: Stay up-to-date with the latest conditions.
2. 4-day forecast: Plan ahead with daily weather details.
3. Responsive design: Enjoy a smooth experience across all devices.
4. CSS animations: Subtle, engaging effects bring the weather to life.

Live Demo
Check it out here:
https://heatherweather.netlify.app/
Binary file added img/.DS_Store
Binary file not shown.
7 changes: 7 additions & 0 deletions img/clear.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions img/cloud.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions img/rain.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
95 changes: 95 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta
name="viewport"
content="width=device-width, initial-scale=1.0"
>
<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>Team Fire 2 Weather App</title>
<link
rel="stylesheet"
href="./style.css"
>
<script
src="https://kit.fontawesome.com/beb1bc6f21.js"
crossorigin="anonymous"
></script>
</head>

<body class="">
<header>
<h1>Heather Weather</h1>
</header>
<main>

<section
class=""
id="city-card"
>
<div
class="container"
id="todaysForecast"
>
<p><span id="weatherDesc"></span> | <span id="mainTemp"></span></p>
<p>sunrise <span id="sunrise"></span></p>
<p>sunset <span id="sunset"></span></p>
</div>
<div
class="container"
id="weatherIcon"
>

</div>
<div class="container">
<h2 id="weatherMain"><span id="cityName"></span></h2>
</div>
<div id="nextCity"><i class="fa-solid fa-chevron-right"></i></div>

<div class="container">
<ul id="weekForecast">
</ul>
</div>

<form
class="container"
id="searchBar"
>
<input
type="text"
placeholder="Type a city..."
id="searchInput"
>
<button
type="button"
id="inputBtn"
>Search</button>
</form>

</section>


</main>
<footer class="">
<p>Created by: Oskar, Sofia, Sofie & Varia</p>
<a href="https://github.com/oskarnordin/js-project-weather-app"><i class="fa-brands fa-github"></i></a>
</footer>

<script src="./script.js"></script>
</body>

</html>
201 changes: 201 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@

//API URL
const defaultURL = "https://api.openweathermap.org/data/2.5/forecast?lat=59.334591&lon=18.063240&appid=15a1790288c26c9ab80c3b6f2209e071"; //Default Stockholm
const parURL = "https://api.openweathermap.org/data/2.5/forecast?lat=48.85341&lon=2.3488&appid=15a1790288c26c9ab80c3b6f2209e071"; // Paris
const barURL = "https://api.openweathermap.org/data/2.5/forecast?lat=41.38879&lon=2.15899&appid=15a1790288c26c9ab80c3b6f2209e071"; // Barcelona

//DOM Elements
const cityName = document.getElementById("cityName");
const weatherDesc = document.getElementById("weatherDesc");
const sunrise = document.getElementById("sunrise");
const mainTemp = document.getElementById("mainTemp");
const weatherIcon = document.getElementById("weatherIcon");
const searchButton = document.getElementById("inputBtn");
const weatherMain = document.getElementById("weatherMain");
const nextCity = document.getElementById("nextCity");
let fetchedData = [];

//Fetch API data
const fetchData = async (url) => {
try {
const response = await fetch(url);

if (!response.ok) {
throw new Error(`Status ${response.status}`);
}
const data = await response.json();
fetchedData = [data]; // Wrap the response in an array

updateCity();
fetchForecastData(url); // Fetch forecast data after fetching main weather data
}
catch (error) {
alert("There was an error, please try again later: " + error);
console.error("Error fetching data:", error);
}
};

//Fetch Forecast data
const fetchForecastData = async (url) => {
try {
const response = await fetch(url);
if (!response.ok) {
throw new Error(`HTPP errror! Status: ${response.status}`);
}
const data = await response.json();
if (!data.list || data.list.length === 0) {
throw new Error("Forecast data is empty or undefined");
}
//filterr out for clsoest to 12:00
fetchedData.forecast = data.list
.filter(item => {
const date = new Date(item.dt * 1000);
const hours = date.getUTCHours();
return hours === 12;
})
.slice(0, 4) //for 4 days only
.map(item => {
return {
date: new Date(item.dt * 1000).toLocaleDateString('en-US', { month: 'short', day: 'numeric' }),
temp: Math.round(item.main.temp - 273.15), //from Kelevin to Celsius
description: item.weather[0].description,
icon: item.weather[0].icon
};
});
updateForecast();
} catch (error) {
console.error("Errrror fetching forecast data:", error);
alert("There was an error, please try again later: " + error.message);
}
};
const updateForecast = () => {
const forecastContainer = document.getElementById("weekForecast");
forecastContainer.innerHTML = ``;
fetchedData.forecast.forEach((day) => {
const listItem = document.createElement("li");
const iconCode = day.icon;
const iconUrl = `https://openweathermap.org/img/wn/${iconCode}.png`;
listItem.innerHTML = `<span>${day.date}</span> <span>${day.temp}°C</span> <img src="${iconUrl}" alt="${day.description} icon"> <span>${day.description}</span>`;
forecastContainer.appendChild(listItem);
});
};

//Time conversion
const timeConversion = () => {
const timestamps = {
sunrise: fetchedData[0].city.sunrise,
sunset: fetchedData[0].city.sunset,
};
const timezone = fetchedData[0].city.timezone;

Object.entries(timestamps).forEach(([key, value]) => {
const date = new Date((value + timezone) * 1000);
const hours = date.getUTCHours().toString().padStart(2, '0');
const minutes = date.getUTCMinutes().toString().padStart(2, '0');

// Update the respective HTML elements
const element = document.getElementById(key);
if (element) {
element.innerHTML = `${hours}:${minutes}`;
}
else {
console.warn(`Element with id '${key}' not found in the DOM.`);
alert("There was an error, please try again later");
}
});
};

//Update City
const updateCity = () => {
if (fetchedData[0].city && fetchedData[0].city.name) {
cityName.innerHTML = fetchedData[0].city.name;
weatherDesc.innerHTML = fetchedData[0].list[0].weather[0].description;
updateWeather();
timeConversion();
updateMainTemp();
}
else {
console.error("City data is missing in fetchedData", fetchedData);
}
};

//Update Weather
const updateWeather = () => {
document.body.className = '';
if (fetchedData[0].list[0].weather[0].main === "Clear") {
document.body.classList.add("clear");
weatherMain.innerHTML = `Get your sunnies on. ${fetchedData[0].city.name} is looking great today.`;
weatherIcon.innerHTML = `<img
src="./img/clear.svg"
alt="Sunglasses for clear weather"
class="weatherIcon weatherIconClear"
>`;
}
else if (fetchedData[0].list[0].weather[0].main === "Clouds") {
document.body.classList.add("cloud");
weatherMain.innerHTML = `It's sweater weather in ${fetchedData[0].city.name} today. Get cosy!`;
weatherIcon.innerHTML = `<i class="fa-solid fa-cloud weatherIcon weatherIconCloud"></i>`;
} else if (fetchedData[0].list[0].weather[0].main === "Snow") {
document.body.classList.add("snow")
weatherMain.innerHTML = `It's snowing in ${fetchedData[0].city.name} today. Grab your sled!`
weatherIcon.innerHTML = `<i class="fa-solid fa-snowflake weatherIcon weatherIconSnow"></i>`
} else if (fetchedData[0].list[0].weather[0].main === "Rain") {
document.body.classList.add("rain");
weatherMain.innerHTML = `Don't forget your umbrella. It's wet in ${fetchedData[0].city.name} today.`;
weatherIcon.innerHTML = `<img
src="./img/rain.svg"
alt="An umbrella for rainy weather"
class="weatherIcon weatherIconRain"
>`;
} else {
document.body.classList.add("");
}
};

//Update Main Temperature
const updateMainTemp = () => {
if (fetchedData[0].list[0].main.temp) {
const tempInCelsius = fetchedData[0].list[0].main.temp - 273.15;
mainTemp.innerHTML = tempInCelsius.toFixed(0) + "°C";
}
else {
console.error("Main temperature is missing in fetchedData", fetchedData);
}
};

//Search City
const searchCity = () => {
const inputElement = document.getElementById("searchInput");
if (!inputElement) {
alert("Search input element not found in the DOM");
return;
}
const input = inputElement.value;
if (input.trim() === "") {
alert("Please enter a city name");
return;
}
let searchURL = `https://api.openweathermap.org/data/2.5/forecast?q=${input}&appid=15a1790288c26c9ab80c3b6f2209e071`;
fetchData(searchURL);

// This clears the input field after the search
document.getElementById("searchInput").value = ""
};

//Event Listeners
searchButton.addEventListener("click", searchCity);
const nextCityClick = () => {
if (fetchedData[0].city.name === "Stockholm") {
fetchData(parURL);
}
else if (fetchedData[0].city.name === "Paris") {
fetchData(barURL);
}
else {
fetchData(defaultURL);
}
};
nextCity.addEventListener("click", nextCityClick);

//Initial fetch
fetchData(defaultURL);
Loading