Skip to content
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
2 changes: 2 additions & 0 deletions challenge-weather-app/api_keys.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
OpenWeather API Key: 6d0fbc92848b733471a1093b6ce30a2a
Unsplash Access Key: ZN0G43FIimsZIYP8Duic-99-R8mkuVHJUSr9mVtThJY
Comment on lines +1 to +2
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a quick heads up – it's important NOT to commit API keys or any sensitive information directly into the codebase. You can use .env file for them. https://www.codementor.io/@parthibakumarmurugesan/what-is-env-how-to-set-up-and-run-a-env-file-in-node-1pnyxw9yxj

1 change: 1 addition & 0 deletions challenge-weather-app/assets/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
html,
body {
height: 100%;
background-color: rgb(151, 149, 151);
}

html {
Expand Down
26 changes: 16 additions & 10 deletions challenge-weather-app/assets/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

overflow: hidden;
position: relative;
margin: 20px 0;
margin: 20px;
}

.photo::before {
Expand Down Expand Up @@ -83,19 +83,18 @@

-webkit-overflow-scrolling: touch;
scroll-behavior: smooth;

overflow-x: auto;
overflow-y: hidden;
height: var(--thumbs-h);
padding: var(--thumbs-py) 0;
background: rgba(0, 0, 0, 0.25);
gap: 10px;
height: calc(var(--thumbs-h) * 1.5);
width: auto;
}

.thumbs__link {
flex: 0 0 auto;

animation: 0.25s forwards fade-in;

width: var(--thumb-w);
height: var(--thumb-h);
margin: 0 1px;
Expand All @@ -115,17 +114,14 @@
display: block;
opacity: 0;
object-fit: cover;

width: 100%;
flex: 0 0 auto;

width: var(--thumb-w);
height: var(--thumb-h);
gap: 5px;
margin: 0 1px;
opacity: 0;
background: rgba(0, 0, 0, 0.5);
}


/* Credits
------------------------------------------------------------------------------*/
.info {
Expand Down Expand Up @@ -160,6 +156,8 @@
.controls {
padding: 5px 10px;
background: rgba(255, 255, 255, 0.25);
margin: 20px;

}

.search,
Expand All @@ -173,6 +171,14 @@
font: inherit;
background: #fff;
}
.search__label,
.search__input,
.search__btn {
font-size: 14px; /* Tüm form elemanlarının yazı boyutunu büyütür */
/* İhtiyacınıza göre diğer özellikler ekleyebilirsiniz */
Comment on lines +177 to +178
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

:)

}



.btn {
text-align: center;
Expand Down
97 changes: 51 additions & 46 deletions challenge-weather-app/index.html
Original file line number Diff line number Diff line change
@@ -1,49 +1,54 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">

<title>Meteoropolis</title>
<link rel="stylesheet" href="assets/globals.css">
<link rel="stylesheet" href="assets/styles.css">
</head>

<body>
<!-- Structure -->
<main class="content">
<header class="header">
<h1 class="title">
<i>Meteor</i>
<i>opolis</i>
</h1>
</header>

<figure class="photo" id="photo"></figure>

<div class="info">
<p class="info__item info__item--conditions" id="conditions"></p>
<p class="info__item info__item--credits">
<a href="#" id="credit-user"></a>
<span>on</span>
<a href="#" id="credit-platform">Unsplash</a>
</p>
</div>

<div class="thumbs" id="thumbs"></div>

<div class="controls">
<form class="search" id="search">
<label class="search__label" for="search-tf">City</label>
<input class="search__input" id="search-tf" name="city" placeholder="Enter city name" autocomplete="city" />
<button class="btn search__btn">Go</button>
</form>
</div>
</main>

<!-- JS goes here -->
</body>

<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />

<title>Meteoropolis</title>
<link rel="stylesheet" href="assets/globals.css" />
<link rel="stylesheet" href="assets/styles.css" />
</head>

<body>
<!-- Structure -->
<main class="content">
<header class="header">
<h1 class="title">
<i>Meteor</i>
<i>opolis</i>
</h1>
</header>

<figure class="photo" id="photo"></figure>

<div class="info">
<p class="info__item info__item--conditions" id="conditions"></p>
<p class="info__item info__item--credits">
<a href="#" id="credit-user"></a>
<span>on</span>
<a href="#" id="credit-platform">Unsplash</a>
</p>
</div>

<div class="thumbs" id="thumbs"></div>

<div class="controls">
<form class="search" id="search">
<label class="search__label" for="search-tf">City</label>
<input
class="search__input"
id="search-tf"
name="city"
placeholder="Enter city name"
autocomplete="city"
/>
<button class="btn search__btn">Go</button>
</form>
</div>
</main>

<!-- JS goes here -->
<script src="script.js"></script>
</body>
</html>
93 changes: 93 additions & 0 deletions challenge-weather-app/script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
const openWeatherAPIKey = "6d0fbc92848b733471a1093b6ce30a2a";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here for API keys

const fetchWeatherData = async (city) => {
try {
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${openWeatherAPIKey}`
);
const data = await response.json();
return data;
} catch (error) {
console.error("Weather data error:", error);
throw error;
}
};
Comment on lines +3 to +13
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well done, great usage of async await with try/catch


const unsplashAccessKey = "ZN0G43FIimsZIYP8Duic-99-R8mkuVHJUSr9mVtThJY";
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here!

const fetchImages = async (description) => {
try {
const response = await fetch(
`https://api.unsplash.com/search/photos?query=${description}&client_id=${unsplashAccessKey}`
);
const data = await response.json();
return data.results;
} catch (error) {
console.error("Image fetch error:", error);
throw error;
}
};

// changes the main image takes the URL of the clicked image.
const setMainImage = async (imageUrl) => {
const photoElement = document.getElementById("photo");
photoElement.innerHTML = `<img src="${imageUrl}" alt="Main Image">`;
};

// displays small images, adds a click event listener to each small images.
const displayThumbnails = (images) => {
const thumbnailsContainer = document.getElementById("thumbs");
thumbnailsContainer.innerHTML = "";
images.forEach((image) => {
thumbnailsContainer.innerHTML += `<img src="${image.urls.thumb}" alt="${image.alt_description}" class="thumbnail" onclick="setMainImage('${image.urls.regular}')">`;
});
};

const fetchAndDisplayImages = async (city) => {
try {
const weatherData = await fetchWeatherData(city);
const description = weatherData.weather[0].description;
const images = await fetchImages(description);

if (images.length > 0) {
displayThumbnails(images);
setMainImage(images[3].urls.regular)// index 3
} else {
console.error("No weather images");
}
} catch (error) {
console.error("Error fetching and displaying images:", error);
}
};

const updateWeatherDisplay = (weatherData) => {
const conditionsElement = document.getElementById("conditions");
conditionsElement.textContent = `Current weather: ${weatherData.weather[0].description}`;
};

const handleFormSubmit = async (event) => {
event.preventDefault();
const cityInput = document.getElementById("search-tf").value.trim();
if (cityInput) {
try {
const weatherData = await fetchWeatherData(cityInput);
updateWeatherDisplay(weatherData);
fetchAndDisplayImages(cityInput);
} catch (error) {
console.error("Weather data error:", error);
}
} else {
console.error("Invalid city name");
}
};

const searchForm = document.getElementById("search");
searchForm.addEventListener("submit", handleFormSubmit);

window.addEventListener("load", async () => {
try {
const defaultWeatherData = await fetchWeatherData("London");
updateWeatherDisplay(defaultWeatherData);
fetchAndDisplayImages("London");
} catch (error) {
console.error("Default data error:", error);
}
});