-
-
Notifications
You must be signed in to change notification settings - Fork 40
NW6| Zeliha Pala| [TECH ED] JavaScript Challenges | Week-3 #14
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
base: master
Are you sure you want to change the base?
Changes from all commits
d6ebf86
6296a56
edc1788
425ea22
129aa38
2f9e3a4
fafe08c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,2 @@ | ||
| OpenWeather API Key: 6d0fbc92848b733471a1093b6ce30a2a | ||
| Unsplash Access Key: ZN0G43FIimsZIYP8Duic-99-R8mkuVHJUSr9mVtThJY | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,6 +21,7 @@ | |
| html, | ||
| body { | ||
| height: 100%; | ||
| background-color: rgb(151, 149, 151); | ||
| } | ||
|
|
||
| html { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -38,7 +38,7 @@ | |
|
|
||
| overflow: hidden; | ||
| position: relative; | ||
| margin: 20px 0; | ||
| margin: 20px; | ||
| } | ||
|
|
||
| .photo::before { | ||
|
|
@@ -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; | ||
|
|
@@ -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 { | ||
|
|
@@ -160,6 +156,8 @@ | |
| .controls { | ||
| padding: 5px 10px; | ||
| background: rgba(255, 255, 255, 0.25); | ||
| margin: 20px; | ||
|
|
||
| } | ||
|
|
||
| .search, | ||
|
|
@@ -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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. :) |
||
| } | ||
|
|
||
|
|
||
|
|
||
| .btn { | ||
| text-align: center; | ||
|
|
||
| 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> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,93 @@ | ||
| const openWeatherAPIKey = "6d0fbc92848b733471a1093b6ce30a2a"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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); | ||
| } | ||
| }); | ||
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.
Just a quick heads up – it's important NOT to commit API keys or any sensitive information directly into the codebase. You can use
.envfile for them. https://www.codementor.io/@parthibakumarmurugesan/what-is-env-how-to-set-up-and-run-a-env-file-in-node-1pnyxw9yxj