├── .gitattributes
├── assets
├── wind.png
├── ._wind.png
├── cloud.png
├── search.png
├── ._cloud.png
├── ._favicon.ico
├── ._loading.gif
├── ._search.png
├── favicon.ico
├── humidity.png
├── loading.gif
├── location.png
├── not-found.png
├── ._humidity.png
└── ._not-found.png
├── index.html
├── style.css
└── index.js
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Auto detect text files and perform LF normalization
2 | * text=auto
3 |
--------------------------------------------------------------------------------
/assets/wind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/wind.png
--------------------------------------------------------------------------------
/assets/._wind.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/._wind.png
--------------------------------------------------------------------------------
/assets/cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/cloud.png
--------------------------------------------------------------------------------
/assets/search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/search.png
--------------------------------------------------------------------------------
/assets/._cloud.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/._cloud.png
--------------------------------------------------------------------------------
/assets/._favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/._favicon.ico
--------------------------------------------------------------------------------
/assets/._loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/._loading.gif
--------------------------------------------------------------------------------
/assets/._search.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/._search.png
--------------------------------------------------------------------------------
/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/favicon.ico
--------------------------------------------------------------------------------
/assets/humidity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/humidity.png
--------------------------------------------------------------------------------
/assets/loading.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/loading.gif
--------------------------------------------------------------------------------
/assets/location.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/location.png
--------------------------------------------------------------------------------
/assets/not-found.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/not-found.png
--------------------------------------------------------------------------------
/assets/._humidity.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/._humidity.png
--------------------------------------------------------------------------------
/assets/._not-found.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bhargav-tibadiya/Weather-App-API/HEAD/assets/._not-found.png
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Weather App
7 |
8 |
9 |
10 |
11 |
12 |
13 |
Weather App
14 |
15 |
16 |
Your Weather
17 |
Search Weather
18 |
19 |
20 |
21 |
22 |
23 |
24 |

25 |
Grant Location
26 |
Allow Access to get Weather Info
27 |
28 |
29 |
30 |
31 |
32 |
38 |
39 |
40 |
41 |

42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
![]()
52 |
53 |
54 |
55 |
56 |
![]()
57 |
58 |
59 |
60 |
61 |
62 |
63 |

64 |
wind Speed
65 |
66 |
67 |
68 |
69 |

70 |
Humidity
71 |
72 |
73 |
74 |
75 |

76 |
Clouds
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | *,*::before,*::after {
2 | margin: 0;
3 | padding: 0;
4 | box-sizing: border-box;
5 | font-family: 'Merriweather Sans', sans-serif;
6 | }
7 |
8 | :root {
9 | --colorDark1: #112D4E;
10 | --colorDark2: #3F72AF;
11 | --colorLight1: #DBE2EF;
12 | --colorLight2: #F9F7F7;
13 | }
14 |
15 | .wrapper{
16 | width:100vw;
17 | height:100vh;
18 | color: var(--colorLight2);
19 | background-image: linear-gradient(160deg, #112d4e 0%, #3f72af 100%);;
20 | }
21 |
22 | h1 {
23 | text-align: center;
24 | text-transform:uppercase;
25 | padding-top: 20px;
26 | }
27 |
28 | .tab-container {
29 | width:90%;
30 | max-width: 550px;
31 | margin: 0 auto;
32 | margin-top: 4rem;
33 | display: flex;
34 | justify-content: space-between;
35 | }
36 |
37 | .tab{
38 | cursor: pointer;
39 | font-size: 0.875rem;
40 | letter-spacing: 1.75px;
41 | padding: 5px 8px;
42 | }
43 |
44 | .tab.current-tab{
45 | background-color: rgba(219, 226, 239, 0.5);
46 | border-radius: 4px;
47 | }
48 |
49 | .weather-container{
50 | margin-block:4rem;
51 | }
52 |
53 | .btn{
54 | all: unset;
55 | /* appearance: none;
56 | border:none;
57 | color: white; */
58 | font-size: 0.85rem;
59 | text-transform: uppercase;
60 | border-radius: 5px;
61 | background-color: var(--colorDark2);
62 | cursor: pointer;
63 | padding: 10px 30px;
64 | margin-bottom: 10px;
65 | }
66 |
67 | .sub-container{
68 | display:flex;
69 | flex-direction:column;
70 | align-items: center;
71 | }
72 |
73 | .grant-location-container{
74 | display:none;
75 | }
76 |
77 | .grant-location-container.active{
78 | display:flex;
79 | }
80 |
81 | .grant-location-container img{
82 | margin-bottom: 2rem;
83 | }
84 |
85 | .grant-location-container p:first-of-type{
86 | font-size: 1.75rem;
87 | font-weight: 600;
88 | }
89 |
90 | .grant-location-container p:last-of-type{
91 | font-size:0.85rem;
92 | font-weight: 500;
93 | margin-top: 0.75rem;
94 | margin-bottom: 1.75rem;
95 | letter-spacing: 0.75px;
96 | }
97 |
98 | .loading-container{
99 | display: none;
100 | }
101 |
102 | .loading-container.active{
103 | display: flex;
104 | }
105 |
106 | .loading-container p{
107 | text-transform: uppercase;
108 | }
109 |
110 | .user-info-container{
111 | display:none;
112 | }
113 |
114 | .user-info-container.active{
115 | display: flex;
116 | /* flex-direction: column; */
117 | }
118 |
119 | .name{
120 | display: flex;
121 | align-items: center;
122 | gap: 0 0.5rem;
123 | margin-bottom: 1rem;
124 | }
125 |
126 | .user-info-container p{
127 | font-size:1.5rem;
128 | font-weight:200;
129 | }
130 |
131 | .user-info-container img{
132 | width:90px;
133 | height:90px;
134 | }
135 |
136 | .name p{
137 | font-size:2rem;
138 | }
139 |
140 | .name img{
141 | width: 30px;
142 | height:30px;
143 | object-fit: contain;
144 | }
145 |
146 | .user-info-container p[data-temp] {
147 | font-size:2.75rem;
148 | font-weight:700;
149 | }
150 |
151 | .parameter-container{
152 | width:90%;
153 | display: flex;
154 | gap: 10px 20px;
155 | justify-content: center;
156 | align-items: center;
157 | margin-top: 2rem;
158 | }
159 |
160 | .parameter{
161 | width:30%;
162 | max-width:200px;
163 | background-color: rgba(219, 226, 239, 0.5);;
164 | border-radius: 5px;
165 | padding:1rem;
166 | display: flex;
167 | flex-direction: column;
168 | gap:5px 0;
169 | /* justify-content: space-between; */
170 | align-items: center;
171 | }
172 |
173 | .parameter img{
174 | width:50px;
175 | height:50px;
176 | }
177 |
178 | .parameter p:first-of-type{
179 | font-size: 1.15rem;
180 | font-weight:600;
181 | text-transform: uppercase;
182 | }
183 |
184 | .parameter p:last-of-type{
185 | font-size: 1rem;
186 | font-weight: 200;
187 | }
188 |
189 | .form-container{
190 | display: none;
191 | width:90%;
192 | max-width:550px;
193 | margin:0 auto;
194 | justify-content: center;
195 | align-items: center;
196 | gap: 0 10px;
197 | margin-bottom: 3rem;
198 | }
199 |
200 | .form-container.active{
201 | display: flex;
202 | }
203 |
204 | .form-container input{
205 | all:unset;
206 | width: calc(100% - 80px);
207 | height:40px;
208 | padding: 0 20px;
209 | background-color:rgba(219, 226, 239, 0.5);
210 | border-radius: 10px;
211 | }
212 |
213 | .form-container input::placeholder{
214 | color: rgba(255, 255, 255, 0.7);
215 | }
216 |
217 | .form-container input:focus{
218 | outline: 3px solid rgba(255, 255, 255, 0.7);
219 | }
220 |
221 | .form-container .btn {
222 | padding:unset;
223 | width: 40px;
224 | height: 40px;
225 | display: flex;
226 | align-items: center;
227 | justify-content: center;
228 | border-radius: 100%;
229 | margin-bottom:1px;
230 | }
231 |
232 |
233 | .user-info-container.active
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const userTab = document.querySelector("[data-userWeather]");
2 | const searchTab = document.querySelector("[data-searchWeather]");
3 | const userContainer = document.querySelector(".weather-container");
4 |
5 | const grantAccessContainer = document.querySelector(".grant-location-container");
6 | const searchForm = document.querySelector("[data-searchForm]");
7 | const loadingScreen = document.querySelector(".loading-container");
8 | const userInfoContainer = document.querySelector(".user-info-container");
9 |
10 | //initially vairables need????
11 |
12 | let oldTab = userTab;
13 | const API_KEY = "d1845658f92b31c64bd94f06f7188c9c";
14 | oldTab.classList.add("current-tab");
15 | getfromSessionStorage();
16 |
17 | function switchTab(newTab) {
18 | if(newTab != oldTab) {
19 | oldTab.classList.remove("current-tab");
20 | oldTab = newTab;
21 | oldTab.classList.add("current-tab");
22 |
23 | if(!searchForm.classList.contains("active")) {
24 | //kya search form wala container is invisible, if yes then make it visible
25 | userInfoContainer.classList.remove("active");
26 | grantAccessContainer.classList.remove("active");
27 | searchForm.classList.add("active");
28 | }
29 | else {
30 | //main pehle search wale tab pr tha, ab your weather tab visible karna h
31 | searchForm.classList.remove("active");
32 | userInfoContainer.classList.remove("active");
33 | //ab main your weather tab me aagya hu, toh weather bhi display karna poadega, so let's check local storage first
34 | //for coordinates, if we haved saved them there.
35 | getfromSessionStorage();
36 | }
37 | }
38 | }
39 |
40 | userTab.addEventListener("click", () => {
41 | //pass clicked tab as input paramter
42 | switchTab(userTab);
43 | });
44 |
45 | searchTab.addEventListener("click", () => {
46 | //pass clicked tab as input paramter
47 | switchTab(searchTab);
48 | });
49 |
50 | //check if cordinates are already present in session storage
51 | function getfromSessionStorage() {
52 | const localCoordinates = sessionStorage.getItem("user-coordinates");
53 | if(!localCoordinates) {
54 | //agar local coordinates nahi mile
55 | grantAccessContainer.classList.add("active");
56 | }
57 | else {
58 | const coordinates = JSON.parse(localCoordinates);
59 | fetchUserWeatherInfo(coordinates);
60 | }
61 |
62 | }
63 |
64 | async function fetchUserWeatherInfo(coordinates) {
65 | const {lat, lon} = coordinates;
66 | // make grantcontainer invisible
67 | grantAccessContainer.classList.remove("active");
68 | //make loader visible
69 | loadingScreen.classList.add("active");
70 |
71 | //API CALL
72 | try {
73 | const response = await fetch(
74 | `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${API_KEY}&units=metric`
75 | );
76 | const data = await response.json();
77 |
78 | loadingScreen.classList.remove("active");
79 | userInfoContainer.classList.add("active");
80 | renderWeatherInfo(data);
81 | }
82 | catch(err) {
83 | loadingScreen.classList.remove("active");
84 | //HW
85 |
86 | }
87 |
88 | }
89 |
90 | function renderWeatherInfo(weatherInfo) {
91 | //fistly, we have to fethc the elements
92 |
93 | const cityName = document.querySelector("[data-cityName]");
94 | const countryIcon = document.querySelector("[data-countryIcon]");
95 | const desc = document.querySelector("[data-weatherDesc]");
96 | const weatherIcon = document.querySelector("[data-weatherIcon]");
97 | const temp = document.querySelector("[data-temp]");
98 | const windspeed = document.querySelector("[data-windspeed]");
99 | const humidity = document.querySelector("[data-humidity]");
100 | const cloudiness = document.querySelector("[data-cloudiness]");
101 |
102 | //fetch values from weatherINfo object and put it UI elements
103 | cityName.innerText = weatherInfo?.name;
104 | countryIcon.src = `https://flagcdn.com/144x108/${weatherInfo?.sys?.country.toLowerCase()}.png`;
105 | desc.innerText = weatherInfo?.weather?.[0]?.description;
106 | weatherIcon.src = `http://openweathermap.org/img/w/${weatherInfo?.weather?.[0]?.icon}.png`;
107 | temp.innerText = weatherInfo?.main?.temp;
108 | windspeed.innertext = weatherInfo?.wind?.speed;
109 | humidity.innertext = weatherInfo?.main?.humidity;
110 | cloudiness.innerText = weatherInfo?.clouds?.all;
111 |
112 |
113 | }
114 |
115 | function getLocation() {
116 | if(navigator.geolocation) {
117 | navigator.geolocation.getCurrentPosition(showPosition);
118 | }
119 | else {
120 | //HW - show an alert for no gelolocation support available
121 | }
122 | }
123 |
124 | function showPosition(position) {
125 |
126 | const userCoordinates = {
127 | lat: position.coords.latitude,
128 | lon: position.coords.longitude,
129 | }
130 |
131 | sessionStorage.setItem("user-coordinates", JSON.stringify(userCoordinates));
132 | fetchUserWeatherInfo(userCoordinates);
133 |
134 | }
135 |
136 | const grantAccessButton = document.querySelector("[data-grantAccess]");
137 | grantAccessButton.addEventListener("click", getLocation);
138 |
139 | const searchInput = document.querySelector("[data-searchInput]");
140 |
141 | searchForm.addEventListener("submit", (e) => {
142 | e.preventDefault();
143 | let cityName = searchInput.value;
144 |
145 | if(cityName === "")
146 | return;
147 | else
148 | fetchSearchWeatherInfo(cityName);
149 | })
150 |
151 | async function fetchSearchWeatherInfo(city) {
152 | loadingScreen.classList.add("active");
153 | userInfoContainer.classList.remove("active");
154 | grantAccessContainer.classList.remove("active");
155 |
156 | try {
157 | const response = await fetch(
158 | `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${API_KEY}&units=metric`
159 | );
160 | const data = await response.json();
161 | loadingScreen.classList.remove("active");
162 | userInfoContainer.classList.add("active");
163 | renderWeatherInfo(data);
164 | }
165 | catch(err) {
166 | //hW
167 | }
168 | }
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 | // const api_key = 'cb690d983d68ef169ff9bbc5201fb01d';
203 |
204 |
205 | // console.log('Hello Jee');
206 |
207 | // async function showWeather() {
208 |
209 | // try {
210 | // let latitude = 15.3333;
211 | // let longitudde = 74.0833;
212 |
213 | // let city = "Goa";
214 |
215 |
216 | // const responce = await fetch(`https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${api_key}`);
217 | // console.log("Responce get");
218 |
219 | // const data = await responce.json();
220 | // console.log("Converted to JSON");
221 |
222 | // console.log("Weather Data : ", data);
223 |
224 | // let newPara = document.createElement('p');
225 | // newPara.textContent= ` ${data?.main?.temp.toFixed(2)} °C`;
226 | // document.body.appendChild(newPara);
227 |
228 | // } catch (error) {
229 | // console.log(error);
230 | // }
231 | // }
232 |
233 | // async function getCustomWeather(){
234 | // let latitude = 15.6333;
235 | // let longitude = 18.3333;
236 |
237 | // let responce = await fetch(`https://api.openweathermap.org/data/2.5/weather?lat=${latitude}&lon=${longitude}&appid=${api_key}`);
238 | // let data = await responce.json();
239 |
240 | // console.log(data);
241 | // }
--------------------------------------------------------------------------------