Skip to content
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

project-7-weather-app #425

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
# 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.
Did a weather app that you can search any city for the days weather and for a week ahead. You can se the temperature, weather description and time for sunset/sunrise.

## 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?
A really fun project where I really got to think. All parts were difficult but I got them working with some googling on the web. Except the search bar and the 5-day forecast. This where to difficult to understand at the time and will need to update the project after some help.

## 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.
Link to weather app: https://project-7-weather-app.netlify.app/
53 changes: 53 additions & 0 deletions code/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="style.css">
<title>WEATHER APP</title>
</head>
<body>

<!-- Weather Card Clear -->
<div class="weather-card" id="weather-card">
<!-- Width content -->
<div>

<!-- Upper info -->
<div class="weather-card-upper-info">
<p class="upper-info-weather">
<span id="upper-info-weather-type"></span> |
<span id="upper-info-weather-temp"></span> °C
</p>
<p class="upper-info-sunrise">sunrise |
<span id="upper-info-sunrise-time"></span>
</p>
<p class="upper-info-sunset">sunset |
<span id="upper-info-sunset-time"></span>
</p>
</div>
<!-- Icon & H2 -->
<div class="icon-h1">
<img id="icon-weather" src="" alt="" width="70">
<h1 id="title-weather"></h1>
</div>
<!-- Days & temperature -->
<section class="forecast-wrapper" id="ForecastWrapper">
<div class="forecast-row">
<div class="forecast-day"></div>
<div class="forecast-temp"></div>
</div>
</section>
</div>

<!-- Search bar and button - not working right now and will be implemented later on! -->
<!-- <input class="city-input" type="text" id="city-input" placeholder="Enter city name">
<button class="btn-city-input" id="btn-city-input">Search</button> -->
</div>



<!-- Javascript -->
<script src="script.js"></script>
</body>
</html>
174 changes: 174 additions & 0 deletions code/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,174 @@

/* JSON file - Weather API */
const API_KEY = "3cc790b1653416aade4ba256c95e0c67"
const BASE_URL = "https://api.openweathermap.org/data/2.5/weather"
const FORECAST_BASE_URL = "https://api.openweathermap.org/data/2.5/forecast?"
let cityWeather = "Sevilla";

/* URL for API */
const URL = `${BASE_URL}?q=${cityWeather}&units=metric&APPID=${API_KEY}`
const FORECAST_URL = `${FORECAST_BASE_URL}q=${cityWeather}&units=metric&APPID=${API_KEY}`



/* Function to fetch weather data based on the city name */

/* Get references to the input field and button */
// const searchInput = document.getElementById("city-input");
// const searchButton = document.getElementById("btn-city-input");


// /* Add event listener for the button click */
// searchButton.addEventListener("click", function() {
// cityWeather = searchInput.value;

// console.log('Search query:', cityWeather);

// });


// // Trigger the search when the Enter key is pressed
// searchInput.addEventListener('keypress', function(event) {
// if (event.key === 'Enter') {
// // Prevent the default action of the Enter key (form submission, etc.)
// event.preventDefault();

// // Get the value from the search input field
// cityWeather = searchInput.value;

// // Log the search query
// console.log('Search query (Enter pressed):', cityWeather);
// }
// });




/* DOM selectors */
const weatherTitle = document.getElementById("title-weather")
const weatherIcon = document.getElementById("icon-weather")
const weatherType = document.getElementById("upper-info-weather-type")
const weatherTemp = document.getElementById("upper-info-weather-temp")
const timeSunrise = document.getElementById("upper-info-sunrise-time")
const timeSunset = document.getElementById("upper-info-sunset-time")
const forecastWrapper = document.getElementById('ForecastWrapper')


/* Sparad data från JSON-fil */
const showNewHTML = (data) => {

/* const cityName = data.name;
cityWeather.innerText = cityName */

const description = data.weather[0].description
weatherType.innerText = description

const temp = data.main.temp
const roundedTemp = temp.toFixed(1);
weatherTemp.innerText = roundedTemp

/* Sunrise and sunset */
const sunrise = data.sys.sunrise;
const sunset = data.sys.sunset;
// Convert UNIX time to a readable format
const sunriseDate = new Date(sunrise * 1000);
const sunsetDate = new Date(sunset * 1000);
// Format the time (HH:MM)
const sunriseFormatted = sunriseDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
const sunsetFormatted = sunsetDate.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });

timeSunrise.innerText = sunriseFormatted
timeSunset.innerText = sunsetFormatted

/* Layout to what weather is shown */
if (description.includes("clear")) {
document.body.classList.remove("weather-card-clear", "weather-card-rain", "weather-card-cloudy", "btn-city-input-cloudy", "city-input-cloudy", "btn-city-input-rain", "city-input-rain"); // Rensa tidigare klasser
weatherTitle.innerText = `Get your sunnies on. ${cityWeather} is looking rather great today.`;
weatherIcon.src = "../assets/design-2/noun_Sunglasses_2055147.svg"; // Bild för soligt väder
document.body.classList.add("weather-card-clear");
document.getElementById("city-input").className = "city-input-clear";
document.getElementById("btn-city-input").className = "btn-city-input-clear";
} else if (description.includes("rain")) {
document.body.classList.remove("weather-card-clear", "weather-card-rain", "weather-card-cloudy", "btn-city-input-cloudy", "city-input-cloudy", "btn-city-input-clear", "city-input-clear", "btn-city-input-rain", "city-input-rain"); // Rensa tidigare klasser
weatherTitle.innerText = `Don’t forget your umbrella. It’s wet in ${cityWeather} today.`;
weatherIcon.src = "../assets/design-2/noun_Umbrella_2030530.svg"; // Bild för regnigt väder
document.body.classList.add("weather-card-rain");
document.getElementById("city-input").className = "city-input-rain";
document.getElementById("btn-city-input").className = "btn-city-input-rain";
} else if (description.includes("cloud")) {
document.body.classList.remove("weather-card-clear", "weather-card-rain", "weather-card-cloudy", "btn-city-input-cloudy", "city-input-cloudy", "btn-city-input-clear", "city-input-clear", "btn-city-input-rain", "city-input-rain"); // Rensa tidigare klasser
weatherTitle.innerText = `Light a fire and get cosy. ${cityWeather} is looking grey today. `;
weatherIcon.src = "../assets/design-2/noun_Cloud_1188486.svg"; // Bild för molnigt väder
document.body.classList.add("weather-card-cloudy");
document.getElementById("city-input").className = "city-input-cloudy";
document.getElementById("btn-city-input").className = "btn-city-input-cloudy";
} else {
document.body.classList.remove("weather-card-clear", "weather-card-rain", "weather-card-cloudy", "btn-city-input-cloudy", "city-input-cloudy", "btn-city-input-clear", "city-input-clear", "btn-city-input-rain", "city-input-rain"); // Rensa tidigare klasser
weatherTitle.innerText = `${cityWeather} is offering a weather today thats not in my vocabulary.`;
weatherIcon.src = "../assets/design-2/noun_Cloud_1188486.svg"; // Bild för molnigt väder
document.body.classList.add("weather-card-cloudy");
document.getElementById("city-input").className = "city-input-cloudy";
document.getElementById("btn-city-input").className = "btn-city-input-cloudy";
}
}

/* Hämta data/väderlek från JSON-fil */
fetch(URL)
.then(response => response.json())
.then(data => {
console.log(data)

showNewHTML(data)


})

/* Hämta data/väderlek för 5 dagar från JSON-fil */
fetch(FORECAST_URL)
.then(response => response.json())
.then(data => {
updateForecastHTML(data)
})


const updateForecastHTML = (data) => {
forecastWrapper.innerHTML = '' // Clear previous forecast
const forecastArray = data.list

// Group forecasts by day
const dailyForecasts = {}
forecastArray.forEach(entry => {
const date = new Date(entry.dt * 1000)
const day = date.toLocaleDateString('en-SE', { weekday: 'short' })
const today = new Date().toLocaleDateString('en-SE', { weekday: 'short' })
if (day === today) return // Skip today's forecast
if (!dailyForecasts[day]) {
dailyForecasts[day] = []
}
dailyForecasts[day].push(entry)
})

// Process each day's forecast
Object.keys(dailyForecasts).forEach(day => {
const forecasts = dailyForecasts[day]
let tempHigh = -Infinity
let tempLow = Infinity

forecasts.forEach(forecast => {
if (forecast.main.temp_max > tempHigh) {
tempHigh = forecast.main.temp_max
}
if (forecast.main.temp_min < tempLow) {
tempLow = forecast.main.temp_min
}
})

const forecastRow = document.createElement('div')
forecastRow.classList.add('forecast-row')
forecastRow.innerHTML = `
<div class="forecast-day">${day}</div>
<div class="forecast-temp">${Math.round(tempHigh)} / ${Math.round(tempLow)}°C</div>
`
forecastWrapper.appendChild(forecastRow)
})
}
93 changes: 93 additions & 0 deletions code/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
* {
padding: 0;
margin: 0;
font-family:Arial, Helvetica, sans-serif;
box-sizing: border-box;
}
body {
background: #fff;
}
.weather-card {
width: 90%;
max-width: 470px;
margin: 100px auto 0;
border-radius: 20px;
padding: 40px 35px;
}
/* clear */
.weather-card-clear {
color: rgba(42, 85, 16, 1);
background: rgba(247, 233, 185, 1);
}
.btn-city-input-clear {
background-color: rgba(42, 85, 16, 1);
color: rgba(247, 233, 185, 1);
}
.city-input-clear {
border: 1px solid rgba(42, 85, 16, 1);
color: rgba(244, 119, 117, 1);
}
/* rain */
.weather-card-rain {
background: rgba(189, 232, 250, 1);
color: rgba(22, 74, 104, 1);
}
.btn-city-input-rain {
color: rgba(189, 232, 250, 1);
background-color: rgba(22, 74, 104, 1);
}
.city-input-rain {
color: rgba(189, 232, 250, 1);
border: 1px solid rgba(22, 74, 104, 1);
}
/* cloudy */
.weather-card-cloudy {
background: rgba(249, 253, 254, 1);
color: rgba(244, 119, 117, 1);
}
.btn-city-input-cloudy {
color: rgba(249, 253, 254, 1);
background-color: rgba(244, 119, 117, 1);
}
.city-input-cloudy {
border: 1px solid rgba(244, 119, 117, 1);
color: rgba(244, 119, 117, 1);
}
.weather-card>div {
display: flex;
flex-direction: column;
row-gap: 30px;
}
.icon-h1 {
display: flex;
flex-direction: column;
row-gap: 20px;
}
/* .days-temp {
margin: 0 0 20px;
}
.days-temp>div {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: #222 1px dotted;
padding: 2px 0 2px;
} */
.forecast-row {
display: flex;
justify-content: space-between;
align-items: center;
border-bottom: #222 1px dotted;
padding: 2px 0 2px;
}
.btn-city-input{
padding: 8px 20px;
border: none;
border-radius: 3px;
}
.city-input {
padding: 8px 5px;
border-radius: 3px;
}