-
Notifications
You must be signed in to change notification settings - Fork 187
Added a weather app to fetch and display weather by city name #328
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
Changes from all commits
9a7775a
8f3c275
9d5bc00
06bb004
e5b25c2
57feb46
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,28 @@ | ||
| <!DOCTYPE html> | ||
| <html lang="en"> | ||
| <head> | ||
| <meta charset="UTF-8"> | ||
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
| <title>Weather App</title> | ||
| <link rel="stylesheet" href="./styles.css"/> | ||
| </head> | ||
| <body> | ||
| <h1>Weather App</h1> | ||
| <div class="parent-container" ><!-- main div --> | ||
| <div class="inputs-container"> | ||
| <input placeholder="enter city name" class="city-name-input"/> | ||
| <button class="srch-btn">Search weather</button> | ||
| </div> | ||
| <div class="outputs-container"> | ||
| <div class="city-name-output">city</div> | ||
| <div class="temp-container">Temperature<p class="temperature"></p></div> | ||
| <div class="text-container-parent"> | ||
| <div >Feels like<p class="feels-like"></p></div> | ||
| <div >Humidity<p class="humidity"></p></div> | ||
| <div>Windspeed<p class="windspeed"></p></div> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| <script src="./script.js"></script> | ||
| </body> | ||
| </html> |
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,79 @@ | ||||||||||||||
| const city = document.querySelector(".city-name-input"); | ||||||||||||||
| const temp = document.querySelector(".temperature"); | ||||||||||||||
| const feels_like = document.querySelector(".feels-like"); | ||||||||||||||
| const humidity = document.querySelector(".humidity"); | ||||||||||||||
| const windspeed = document.querySelector(".windspeed"); | ||||||||||||||
| const btn = document.querySelector(".srch-btn"); | ||||||||||||||
| const cityOp = document.querySelector(".city-name-output"); | ||||||||||||||
|
|
||||||||||||||
| // IMPORTANT: Replace "YOUR_API_KEY" with your actual OpenWeatherMap API key. | ||||||||||||||
| const apiKey = "YOUR_API_KEY"; | ||||||||||||||
| async function getWeatherInfo(city) { | ||||||||||||||
| try { | ||||||||||||||
| console.log(city); | ||||||||||||||
| if (city.length === 0) { | ||||||||||||||
| throw Error("Enter city name correctly"); | ||||||||||||||
| } | ||||||||||||||
|
|
||||||||||||||
| let res = await fetch( | ||||||||||||||
| `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${apiKey}` | ||||||||||||||
| ); | ||||||||||||||
| console.log(res); | ||||||||||||||
| if (!res.ok) { | ||||||||||||||
| if (res.status === 404) { | ||||||||||||||
| throw Error("City not found"); | ||||||||||||||
| } else if (res.status === 401) { | ||||||||||||||
| throw Error("Access denied.Check your api key "); | ||||||||||||||
|
||||||||||||||
| throw Error("Access denied.Check your api key "); | |
| throw Error("Access denied. Check your api key"); |
Copilot
AI
Oct 4, 2025
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.
Using innerHTML with dynamic content can lead to XSS vulnerabilities. Consider using textContent or properly sanitizing the content before insertion.
| feels_like.innerHTML = fl + "<sup>o</sup>C"; | |
| feels_like.textContent = fl; | |
| const sup = document.createElement("sup"); | |
| sup.textContent = "o"; | |
| feels_like.appendChild(sup); | |
| feels_like.appendChild(document.createTextNode("C")); |
Copilot
AI
Oct 5, 2025
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.
Lines 52-56 set innerHTML values that are immediately overwritten by textContent assignments in lines 58-60. The initial innerHTML assignments are redundant and should be removed.
Copilot
AI
Oct 4, 2025
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.
[nitpick] The hardcoded default city 'kurnool' should be configurable or removed. Consider using a more universally recognizable default city or removing the default load behavior.
| window.addEventListener("load", () => { | |
| getWeatherInfo("kurnool"); | |
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,161 @@ | ||
| /* ---------- Base styles ---------- */ | ||
| body { | ||
| background-color: #f2f4f7; | ||
| color: #1e1e1e; | ||
| font-family: "Poppins", sans-serif; | ||
| display: flex; | ||
| flex-direction: column; | ||
| min-height: 100vh; | ||
| justify-content: center; | ||
| align-items: center; | ||
| margin: 0; | ||
| } | ||
|
|
||
| h1 { | ||
| text-align: center; | ||
| margin-bottom: 1.5rem; | ||
| color: #2d6cdf; | ||
| font-weight: 600; | ||
| letter-spacing: 0.5px; | ||
| } | ||
|
|
||
| /* ---------- Containers ---------- */ | ||
| .parent-container { | ||
| background-color: #ffffff; | ||
| border: 2px solid #e2e8f0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| border-radius: 12px; | ||
| padding: 1.5rem; | ||
| width: 360px; | ||
| box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); | ||
| margin: 3rem; | ||
| transform: scale(1.2); | ||
| } | ||
|
|
||
| .inputs-container { | ||
| display: flex; | ||
| flex-direction: row; | ||
| gap: 0.5rem; | ||
| margin-bottom: 1.2rem; | ||
| } | ||
|
|
||
| /* ---------- Input + Button ---------- */ | ||
| .city-name-input { | ||
| flex: 1; | ||
| padding: 0.6rem; | ||
| border: 2px solid #cbd5e1; | ||
| border-radius: 8px; | ||
| background-color: #f9fafb; | ||
| color: #1e293b; | ||
| outline: none; | ||
| font-size: 0.95rem; | ||
| transition: border-color 0.2s ease, box-shadow 0.2s ease; | ||
| } | ||
|
|
||
| .city-name-input:focus { | ||
| border-color: #b1b1b1; | ||
| box-shadow: 0 2px 5px 3px #9097a133; | ||
| } | ||
|
|
||
| .srch-btn { | ||
| background-color: #3b82f6; | ||
| color: white; | ||
| border: none; | ||
| padding: 0.6rem 0.9rem; | ||
| border-radius: 8px; | ||
| cursor: pointer; | ||
| font-weight: 600; /* <-- Bold text */ | ||
| font-size: 0.9rem; | ||
| transition: background-color 0.2s ease, transform 0.1s ease; | ||
| } | ||
|
|
||
| .srch-btn:hover { | ||
| background-color: #2563eb; | ||
| } | ||
|
|
||
| .srch-btn:active { | ||
| transform: scale(0.97); | ||
| } | ||
|
|
||
| /* ---------- Outputs ---------- */ | ||
| .outputs-container { | ||
| border: 2px solid #e2e8f0; | ||
| display: flex; | ||
| flex-direction: column; | ||
| justify-content: center; | ||
| align-items: center; | ||
| padding: 1rem; | ||
| border-radius: 10px; | ||
| background-color: #f9fafb; | ||
| } | ||
|
|
||
| .city-name-output { | ||
| text-align: center; | ||
| font-size: 1.3rem; | ||
| margin-bottom: 0.5rem; | ||
| color: #2563eb; | ||
| } | ||
|
|
||
| .temp-container { | ||
| text-align: center; | ||
| margin-bottom: 1rem; | ||
| } | ||
|
|
||
| .temperature { | ||
| font-size: 2rem; | ||
| font-weight: 600; | ||
| color: #1e1e1e; | ||
| } | ||
|
|
||
| /* ---------- Text data boxes ---------- */ | ||
| .text-container-parent { | ||
| display: flex; | ||
| flex-direction: row; | ||
| justify-content: space-around; | ||
| width: 100%; | ||
| gap: 0.6rem; | ||
| } | ||
|
|
||
| .text-container-parent div { | ||
| flex: 1; | ||
| border: 2px solid #e2e8f0; | ||
| background-color: #ffffff; | ||
| border-radius: 10px; | ||
| padding: 0.8rem; | ||
| display: flex; | ||
| flex-direction: column; | ||
| align-items: center; | ||
| gap: 0.3rem; | ||
| box-shadow: 0 2px 6px rgba(0, 0, 0, 0.05); | ||
| } | ||
|
|
||
|
|
||
|
|
||
| .text-container-parent div p { | ||
| margin: 0; | ||
| font-weight: 600; | ||
| color: #0f172a; | ||
| font-size: 1rem; | ||
| } | ||
|
|
||
| .text-container-parent div span { | ||
| color: #475569; | ||
| font-size: 0.9rem; | ||
| } | ||
|
|
||
| /* Medium screens (tablets) */ | ||
| @media (max-width: 768px) { | ||
| .parent-container { | ||
| transform: scale(1); /* normal size */ | ||
| margin-top: 1.5rem; | ||
| } | ||
| } | ||
|
|
||
| /* Small screens (mobiles) */ | ||
| @media (max-width: 480px) { | ||
| .parent-container { | ||
| transform: scale(0.80); /* smaller size */ | ||
| margin-top: 1rem; | ||
| } | ||
| } |
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.
API key is hardcoded as a placeholder string. This should be moved to environment variables or a configuration file to prevent accidental exposure in version control.