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
104 changes: 0 additions & 104 deletions app.js

This file was deleted.

12 changes: 5 additions & 7 deletions index.html
Original file line number Diff line number Diff line change
@@ -1,26 +1,23 @@
<!DOCTYPE html>
<html lang="en">

<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Weather App - Find weather of any city</title>
<link rel="shortcut icon" href="images/favicon.png" type="image/x-icon">
<link rel="stylesheet" href="style.css">
<script src="app.js" defer></script>
<script src="script.js" defer></script>
</head>
<body>

<!-- Preloader -->
<div id="preloader">
<div class="loader"></div>
</div>

<body>

<div class="app-container">
<div class="search-box">
<input type="text" name="city" id="city-input" placeholder="Enter City Name" spellcheck="false">
<button id="search"><img src="images/search.png" alt=""></button>
</div>
<div id="recent" class="recent-box"></div>
<div class="error">
<p>Invalid City Name</p>
</div>
Expand Down Expand Up @@ -54,4 +51,5 @@ <h2 id="city">Kolkata</h2>

</div>
</body>

</html>
40 changes: 0 additions & 40 deletions readme.md

This file was deleted.

129 changes: 129 additions & 0 deletions script.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
const searchBox = document.querySelector(".search-box input");
const searchBtn = document.querySelector("#search");
const weatherIcon = document.querySelector(".weather-icon");
const appContainer = document.querySelector(".app-container");

const weatherApiKey = 'b2fa3271ab55c9c76e1b2a2d1afd0478';
const weatherURL = `https://api.openweathermap.org/data/2.5/weather?units=metric&q=`;

const imageApiKey = "2BsfBnNAfcAGF3oX4F_fRIlYnOXYBGYyJpeHfo8AWp4";
const imageURL = "https://api.unsplash.com/search/photos?page=1&query=";

let recentCities = [];

// Weather API call
async function checkWeather(city) {
const response = await fetch(weatherURL + city + `&appid=${weatherApiKey}`);
const data = await response.json();

if (response.status === 404 || data.cod === '404') {
document.querySelector(".error").style.display = 'block';
document.querySelector(".weather").style.visibility = "hidden";
appContainer.style.backgroundImage = `linear-gradient(rgba(0,0,0,0.5), rgba(0,0,0,0.5)), url("images/weather.jpg")`;
} else {
setTimeout(() => {
updateData(data);
}, 500);
}
}

// Update DOM with weather data
async function updateData(data) {
document.querySelector("#city").textContent = data.name;
document.querySelector("#temp").textContent = Math.round(data.main.temp) + "°c";
document.querySelector(".humidity").textContent = data.main.humidity + '%';
document.querySelector(".wind").textContent = data.wind.speed + "Km/h";

const weatherCondition = data.weather[0].main;

if (weatherCondition === 'Clear') {
weatherIcon.src = "images/clear.png";
} else if (weatherCondition === 'Clouds') {
weatherIcon.src = "images/clouds.png";
} else if (weatherCondition === 'Haze') {
weatherIcon.src = "images/drizzle.png";
} else if (weatherCondition === 'Mist') {
weatherIcon.src = "images/mist.png";
} else if (weatherCondition === 'Rain') {
weatherIcon.src = "images/rain.png";
} else if (weatherCondition === 'Snow') {
weatherIcon.src = "images/snow.png";
}

document.querySelector("#condition").textContent = data.weather[0].main;
document.querySelector(".weather").style.display = "block";
document.querySelector(".error").style.display = 'none';
}

// Unsplash Image API call
async function generateImage(city) {
try {
const response = await fetch(imageURL + city + `&client_id=${imageApiKey}`);
const data = await response.json();

if (data.results && data.results.length > 0) {
const img = data.results[0].urls.full;
appContainer.style.backgroundImage = `linear-gradient(rgba(0,0,0,0.4), rgba(0,0,0,0.4)), url(${img})`;
}
} catch (err) {
console.error("Image load failed:", err);
}
}

// Add a city to recent list and localStorage
function updateRecentCities(city) {
const formattedCity = city.toLowerCase();
if (!formattedCity || recentCities.includes(formattedCity)) return;

recentCities.unshift(formattedCity);
if (recentCities.length > 5) {
recentCities.pop();
}

localStorage.setItem("recentCities", JSON.stringify(recentCities));
renderRecentCities();
}

// Render recent cities from array
function renderRecentCities() {
const recentBox = document.querySelector("#recent");
if (!recentBox) return;

recentBox.innerHTML = '';

recentCities.forEach(city => {
const btn = document.createElement("button");
btn.textContent = city.charAt(0).toUpperCase() + city.slice(1);
btn.addEventListener("click", () => {
document.querySelector("#city-input").value = city;
generateImage(city);
checkWeather(city);
});
recentBox.appendChild(btn);
});
}

// Load from localStorage on page load
function loadRecentCities() {
const saved = localStorage.getItem("recentCities");
if (saved) {
recentCities = JSON.parse(saved);
renderRecentCities();
}
}

// Handle search
searchBtn.addEventListener('click', () => {
const city = searchBox.value.trim();
if (city === '') return;

generateImage(city);
checkWeather(city);
updateRecentCities(city);
});

// Initial load
loadRecentCities();
checkWeather("kolkata");
generateImage("kolkata");
updateRecentCities("kolkata");
25 changes: 25 additions & 0 deletions style.css
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,31 @@ html, body{
outline: none;
}

.recent-box {
margin-top: 20px;
display: flex;
justify-content: center;
flex-wrap: wrap;
gap: 10px;
}

.recent-box button {
padding: 8px 16px;
background: rgba(255, 255, 255, 0.15);
border: 1px solid rgba(255, 255, 255, 0.25);
color: #fff;
border-radius: 999px;
font-size: 0.9rem;
backdrop-filter: blur(6px);
cursor: pointer;
transition: all 0.3s ease;
}

.recent-box button:hover {
background: rgba(255, 255, 255, 0.25);
transform: scale(1.05);
}

#search{
background-color: #ebfffc;
border-radius: 50%;
Expand Down