├── .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 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |

26 |
Oops! Invalid location :/
27 |
28 |
29 |
30 |
![]()
31 |
32 |
33 |
34 |
35 |
36 |
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 | }
--------------------------------------------------------------------------------