├── .DS_Store ├── images ├── 404.png ├── clear.png ├── cloud.png ├── mist.png └── snow.png ├── index.html ├── index.js └── style.css /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OracleBrain/Thermospectra-app-with-javascript/8e05330b5469d35f67c4359fcec16ca3f59a6b62/.DS_Store -------------------------------------------------------------------------------- /images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OracleBrain/Thermospectra-app-with-javascript/8e05330b5469d35f67c4359fcec16ca3f59a6b62/images/404.png -------------------------------------------------------------------------------- /images/clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OracleBrain/Thermospectra-app-with-javascript/8e05330b5469d35f67c4359fcec16ca3f59a6b62/images/clear.png -------------------------------------------------------------------------------- /images/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OracleBrain/Thermospectra-app-with-javascript/8e05330b5469d35f67c4359fcec16ca3f59a6b62/images/cloud.png -------------------------------------------------------------------------------- /images/mist.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OracleBrain/Thermospectra-app-with-javascript/8e05330b5469d35f67c4359fcec16ca3f59a6b62/images/mist.png -------------------------------------------------------------------------------- /images/snow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OracleBrain/Thermospectra-app-with-javascript/8e05330b5469d35f67c4359fcec16ca3f59a6b62/images/snow.png -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | Weather App | OracleBrain 13 | 14 | 15 | 16 | 17 |
18 | 23 | 24 |
25 | 26 |

Oops! Invalid location :/

27 |
28 | 29 |
30 | 31 |

32 |

33 |
34 | 35 |
36 |
37 | 38 |
39 | 40 |

Humidity

41 |
42 |
43 |
44 | 45 |
46 | 47 |

Wind Speed

48 |
49 |
50 |
51 | 52 |
53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | const container = document.querySelector('.container'); 2 | const search = document.querySelector('.search-box button'); 3 | const weatherBox = document.querySelector('.weather-box'); 4 | const weatherDetails = document.querySelector('.weather-details'); 5 | const error404 = document.querySelector('.not-found'); 6 | 7 | search.addEventListener('click', async () => { 8 | const APIKey = 'dca88e35d2fc0ec09e1b8bc5c08243a1'; 9 | const city = document.querySelector('.search-box input').value; 10 | 11 | if (city === '') return; 12 | 13 | try { 14 | const response = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&units=metric&appid=${APIKey}`); 15 | const json = await response.json(); 16 | 17 | if (json.cod === '404') { 18 | showError(); 19 | return; 20 | } 21 | 22 | hideError(); 23 | updateWeatherUI(json); 24 | } catch (error) { 25 | console.error(error); 26 | } 27 | }); 28 | 29 | function showError() { 30 | container.style.height = '400px'; 31 | weatherBox.style.display = 'none'; 32 | weatherDetails.style.display = 'none'; 33 | error404.style.display = 'block'; 34 | error404.classList.add('fadeIn'); 35 | } 36 | 37 | function hideError() { 38 | error404.style.display = 'none'; 39 | error404.classList.remove('fadeIn'); 40 | } 41 | 42 | function updateWeatherUI(json) { 43 | const image = document.querySelector('.weather-box img'); 44 | const temperature = document.querySelector('.weather-box .temperature'); 45 | const description = document.querySelector('.weather-box .description'); 46 | const humidity = document.querySelector('.weather-details .humidity span'); 47 | const wind = document.querySelector('.weather-details .wind span'); 48 | 49 | const weatherMain = json.weather[0].main; 50 | const weatherImages = { 51 | 'Clear': 'images/clear.png', 52 | 'Rain': 'images/rain.png', 53 | 'Snow': 'images/snow.png', 54 | 'Clouds': 'images/cloud.png', 55 | 'Haze': 'images/mist.png' 56 | }; 57 | 58 | image.src = weatherImages[weatherMain] || ''; 59 | temperature.innerHTML = `${parseInt(json.main.temp)}°C`; 60 | description.innerHTML = `${json.weather[0].description}`; 61 | humidity.innerHTML = `${json.main.humidity}%`; 62 | wind.innerHTML = `${parseInt(json.wind.speed)}Km/h`; 63 | 64 | weatherBox.style.display = ''; 65 | weatherDetails.style.display = ''; 66 | weatherBox.classList.add('fadeIn'); 67 | weatherDetails.classList.add('fadeIn'); 68 | container.style.height = '590px'; 69 | } -------------------------------------------------------------------------------- /style.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This CSS code snippet sets some global styles for all elements and defines styles for the body and container elements. 3 | */ 4 | 5 | /* Set default styles for all elements */ 6 | * { 7 | margin: 0; 8 | padding: 0; 9 | border: 0; 10 | outline: none; 11 | box-sizing: border-box; 12 | } 13 | 14 | /* Style the body element */ 15 | body { 16 | height: 100vh; 17 | display: flex; 18 | align-items: center; 19 | justify-content: center; 20 | background: linear-gradient(90deg, #74EBD5 0%, #9FACE6 100%); 21 | } 22 | 23 | /* Style the container element */ 24 | .container { 25 | position: relative; 26 | width: 400px; 27 | height: 105px; 28 | background: linear-gradient(0deg, #FFDEE9 0%, #B5FFFC 100%); 29 | padding: 28px 32px; 30 | overflow: hidden; 31 | border-radius: 18px; 32 | font-family: 'Roboto', sans-serif; 33 | transition: 0.6s ease-out; 34 | } 35 | 36 | /* 37 | Code Explanation: 38 | The code snippet defines the styles for a search box component in CSS. 39 | */ 40 | 41 | .search-box { 42 | width: 100%; 43 | height: min-content; 44 | display: flex; 45 | align-items: center; 46 | justify-content: space-between; 47 | } 48 | 49 | .search-box input { 50 | color: #250821; 51 | width: 80%; 52 | font-size: 24px; 53 | font-weight: 500; 54 | text-transform: uppercase; 55 | padding-left: 32px; 56 | } 57 | 58 | .search-box input::placeholder { 59 | font-size: 20px; 60 | font-weight: 500; 61 | color: #250821; 62 | text-transform: capitalize; 63 | } 64 | 65 | .search-box button { 66 | cursor: pointer; 67 | width: 50px; 68 | height: 50px; 69 | color: #250821; 70 | background: #dff6df; 71 | border-radius: 50%; 72 | font-size: 22px; 73 | transition: 0.4s ease; 74 | } 75 | 76 | /* 77 | Code Explanation: 78 | The code snippet defines the styles for the weather box component in CSS. 79 | */ 80 | 81 | .search-box button:hover{ 82 | color: #ffffff; 83 | background: #250821; 84 | } 85 | 86 | .search-box i{ 87 | position: absolute; 88 | color: #250821; 89 | font-size: 28px; 90 | } 91 | 92 | .weather-box{ 93 | text-align: center; 94 | } 95 | 96 | .weather-box img{ 97 | width: 60%; 98 | margin-top: 30px; 99 | } 100 | 101 | .weather-box .temperature{ 102 | position: relative; 103 | color: #250821; 104 | font-size: 4rem; 105 | font-weight: 800; 106 | margin-top: 30px; 107 | margin-left: -16px; 108 | } 109 | 110 | .weather-box .temperature span{ 111 | position: absolute; 112 | margin-left: 4px; 113 | font-size: 1.5rem; 114 | } 115 | 116 | .weather-box .description{ 117 | color: #250821; 118 | font-size: 22px; 119 | font-weight: 500; 120 | text-transform: capitalize; 121 | } 122 | 123 | .weather-details { 124 | width: 100%; 125 | display: flex; 126 | justify-content: space-between; 127 | margin-top: 30px; 128 | } 129 | 130 | .weather-details .humidity, 131 | .weather-details .wind { 132 | display: flex; 133 | align-items: center; 134 | width: 50%; 135 | height: 100px; 136 | } 137 | 138 | .weather-details .humidity { 139 | padding-left: 20px; 140 | justify-content: flex-start; 141 | } 142 | 143 | .weather-details .wind { 144 | padding-right: 20px; 145 | justify-content: flex-end; 146 | } 147 | 148 | .weather-details i { 149 | color: #250821; 150 | font-size: 26px; 151 | margin-right: 10px; 152 | margin-top: 6px; 153 | } 154 | 155 | .weather-details span, 156 | .weather-details p { 157 | color: #250821; 158 | font-size: 22px; 159 | font-weight: 500; 160 | } 161 | 162 | .weather-details p { 163 | font-size: 14px; 164 | } 165 | 166 | .not-found { 167 | width: 100%; 168 | text-align: center; 169 | margin-top: 50px; 170 | scale: 0; 171 | opacity: 0; 172 | display: none; 173 | } 174 | 175 | .not-found img { 176 | width: 70%; 177 | } 178 | 179 | .not-found p { 180 | color: #250821; 181 | font-size: 22px; 182 | font-weight: 500; 183 | margin-top: 12px; 184 | } 185 | 186 | .weather-box, 187 | .weather-details { 188 | scale: 0; 189 | opacity: 0; 190 | } 191 | 192 | .fadeIn { 193 | animation: 0.5s fadeIn forwards; 194 | animation-delay: 0.5s; 195 | } 196 | 197 | @keyframes fadeIn { 198 | to { 199 | scale: 1; 200 | opacity: 1; 201 | } 202 | } --------------------------------------------------------------------------------