├── LICENSE
├── README.md
├── package-lock.json
├── package.json
├── public
├── favicon.ico
├── index.html
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
└── src
├── App.css
├── App.js
├── App.test.js
├── apiKeys.js
├── currentLocation.js
├── forcast.js
├── images
├── WeatherIcons.gif
├── background.jpg
├── background1.jpg
├── city.jpg
├── city1.jpg
└── forecast.png
├── index.css
├── index.js
├── logo.svg
├── serviceWorker.js
└── setupTests.js
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Gaurav Ghai
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | View Complete Installation details .
7 |
8 |
9 | View Live demo .
10 |
11 |
12 | ## Setup
13 |
14 | ```
15 | npm i && npm start
16 | ```
17 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "weather",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^4.2.4",
7 | "@testing-library/react": "^9.3.2",
8 | "@testing-library/user-event": "^7.1.2",
9 | "axios": "^0.19.2",
10 | "react": "^16.13.1",
11 | "react-animated-weather": "^4.0.1",
12 | "react-dom": "^16.13.1",
13 | "react-geolocated": "^3.0.1",
14 | "react-live-clock": "^4.0.5",
15 | "react-scripts": "3.4.1",
16 | "react-skycons": "^0.7.0",
17 | "skycons": "^1.0.0"
18 | },
19 | "scripts": {
20 | "start": "react-scripts start",
21 | "build": "react-scripts build",
22 | "test": "react-scripts test",
23 | "eject": "react-scripts eject"
24 | },
25 | "eslintConfig": {
26 | "extends": "react-app"
27 | },
28 | "browserslist": {
29 | "production": [
30 | ">0.2%",
31 | "not dead",
32 | "not op_mini all"
33 | ],
34 | "development": [
35 | "last 1 chrome version",
36 | "last 1 firefox version",
37 | "last 1 safari version"
38 | ]
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/public/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | Live weather app built by using React.js
28 |
29 |
33 |
42 |
43 |
44 | You need to enable JavaScript to run this app.
45 |
46 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React App",
3 | "name": "Create React App Sample",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | /*--
2 | Author: W3layouts
3 | Author URL: http://w3layouts.com
4 | License: Creative Commons Attribution 3.0 Unported
5 | License URL: http://creativecommons.org/licenses/by/3.0/
6 | --*/
7 |
8 | /*-- Reset Code --*/
9 |
10 | html,
11 | body,
12 | div,
13 | span,
14 | applet,
15 | object,
16 | iframe,
17 | h1,
18 | h2,
19 | h3,
20 | h4,
21 | h5,
22 | h6,
23 | p,
24 | blockquote,
25 | pre,
26 | a,
27 | abbr,
28 | acronym,
29 | address,
30 | big,
31 | cite,
32 | code,
33 | del,
34 | dfn,
35 | em,
36 | img,
37 | ins,
38 | kbd,
39 | q,
40 | s,
41 | samp,
42 | small,
43 | strike,
44 | strong,
45 | sub,
46 | sup,
47 | tt,
48 | var,
49 | b,
50 | u,
51 | i,
52 | dl,
53 | dt,
54 | dd,
55 | ol,
56 | nav ul,
57 | nav li,
58 | fieldset,
59 | form,
60 | label,
61 | legend,
62 | table,
63 | caption,
64 | tbody,
65 | tfoot,
66 | thead,
67 | tr,
68 | th,
69 | td,
70 | article,
71 | aside,
72 | canvas,
73 | details,
74 | embed,
75 | figure,
76 | figcaption,
77 | footer,
78 | header,
79 | hgroup,
80 | menu,
81 | nav,
82 | output,
83 | ruby,
84 | section,
85 | summary,
86 | time,
87 | mark,
88 | audio,
89 | video {
90 | margin: 0;
91 | padding: 0;
92 | border: 0;
93 | font-size: 100%;
94 | font: inherit;
95 | vertical-align: baseline;
96 | }
97 | article,
98 | aside,
99 | details,
100 | figcaption,
101 | figure,
102 | footer,
103 | header,
104 | hgroup,
105 | menu,
106 | nav,
107 | section {
108 | display: block;
109 | }
110 | ol,
111 | ul {
112 | list-style: none;
113 | padding: 0;
114 | margin: 0;
115 | }
116 | blockquote,
117 | q {
118 | quotes: none;
119 | }
120 | blockquote:before,
121 | blockquote:after,
122 | q:before,
123 | q:after {
124 | content: "";
125 | content: none;
126 | }
127 | table {
128 | border-collapse: collapse;
129 | border-spacing: 0;
130 | }
131 | /* start editing from here */
132 | a {
133 | text-decoration: none;
134 | }
135 | .txt-rt {
136 | text-align: right;
137 | } /* text align right */
138 | .txt-lt {
139 | text-align: left;
140 | } /* text align left */
141 | .txt-center {
142 | text-align: center;
143 | } /* text align center */
144 | .float-rt {
145 | float: right;
146 | } /* float right */
147 | .float-lt {
148 | float: left;
149 | } /* float left */
150 | .clear {
151 | clear: both;
152 | } /* clear float */
153 | .pos-relative {
154 | position: relative;
155 | } /* Position Relative */
156 | .pos-absolute {
157 | position: absolute;
158 | } /* Position Absolute */
159 | .vertical-base {
160 | vertical-align: baseline;
161 | } /* vertical align baseline */
162 | .vertical-top {
163 | vertical-align: top;
164 | } /* vertical align top */
165 | .underline {
166 | padding-bottom: 5px;
167 | border-bottom: 1px solid #eee;
168 | margin: 0 0 20px 0;
169 | } /* Add 5px bottom padding and a underline */
170 | nav.vertical ul li {
171 | display: block;
172 | } /* vertical menu */
173 | nav.horizontal ul li {
174 | display: inline-block;
175 | } /* horizontal menu */
176 | img {
177 | max-width: 100%;
178 | }
179 | .current-time {
180 | font-size: 35px;
181 | font-weight: 100;
182 | margin-bottom: 10px;
183 | letter-spacing: 1px;
184 | }
185 | .current-date {
186 | font-size: 18px;
187 | font-weight: 100;
188 | letter-spacing: 1px;
189 | }
190 |
191 | /*-- //Reset Code --*/
192 |
193 | /*-- Index-Page-Styling --*/
194 |
195 | body {
196 | background: url("./images/background.jpg");
197 | background-repeat: no-repeat;
198 | background-attachment: fixed;
199 | background-position: center;
200 | background-size: cover;
201 | -webkit-background-size: cover;
202 | -moz-background-size: cover;
203 | -o-background-size: cover;
204 | font-family: "Open Sans", sans-serif;
205 | text-align: center;
206 | }
207 |
208 | body a {
209 | transition: 0.5s all;
210 | -webkit-transition: 0.5s all;
211 | -moz-transition: 0.5s all;
212 | -o-transition: 0.5s all;
213 | -ms-transition: 0.5s all;
214 | text-decoration: none;
215 | }
216 |
217 | h1 {
218 | font-size: 50px;
219 | font-weight: 400;
220 | color: #f9f9f9;
221 | font-family: "Oxygen", sans-serif;
222 | letter-spacing: 7px;
223 | margin-top: 50px;
224 | }
225 |
226 | .container {
227 | width: 65%;
228 | height: 80vh;
229 | margin: 50px auto;
230 | background-color: rgba(0, 0, 0, 0.73);
231 | }
232 |
233 | .city {
234 | width: 60%;
235 | height: 100%;
236 | float: left;
237 | background: url("./images/city.jpg");
238 | background-repeat: no-repeat;
239 | background-size: cover;
240 | -webkit-background-size: cover;
241 | -moz-background-size: cover;
242 | -o-background-size: cover;
243 | min-height: 500px;
244 | position: relative;
245 | background-position-x: -30px;
246 | }
247 |
248 | .title {
249 | float: right;
250 | font-family: "Oxygen", sans-serif;
251 | padding: 30px 30px 0 0;
252 | }
253 |
254 | .title h2 {
255 | color: #fff;
256 | font-size: 30px;
257 | font-weight: bold;
258 | }
259 |
260 | .title h3 {
261 | font-size: 25px;
262 | font-weight: bold;
263 | color: #eee;
264 | margin-top: 0px;
265 | text-align: right;
266 | }
267 |
268 | .date-time {
269 | position: absolute;
270 | bottom: 0;
271 | color: #fff;
272 | width: 90%;
273 | padding: 0 30px 10px 30px;
274 | font-family: "Oxygen", sans-serif;
275 | }
276 |
277 | div#txt {
278 | font-size: 35px;
279 | font-weight: 100;
280 | margin-bottom: 10px;
281 | letter-spacing: 1px;
282 | }
283 |
284 | .dmy {
285 | float: left;
286 | text-align: left;
287 | position: absolute;
288 | }
289 |
290 | .temperature {
291 | width: 50%;
292 | float: right;
293 | position: relative;
294 | left: 10px;
295 | }
296 |
297 | .temperature p {
298 | font-family: "Raleway", sans-serif;
299 | font-size: 80px;
300 | font-weight: 100;
301 | margin: 0 40px;
302 | }
303 |
304 | .temperature p span {
305 | font-size: 50px;
306 | font-weight: 200;
307 | }
308 |
309 | .forecast {
310 | width: 40%;
311 | float: left;
312 | height: 100%;
313 | }
314 |
315 | .forecast-icon {
316 | padding: 25px 0;
317 | /* background: white; */
318 | }
319 |
320 | .today-weather h3 {
321 | text-transform: capitalize;
322 | font-size: 50px;
323 | color: #fff;
324 | width: 80%;
325 | margin: 0 auto 10px;
326 | padding-bottom: 10px;
327 | border-width: thin;
328 | border-bottom: 1px solid #eee;
329 | }
330 |
331 | .today-weather ul li {
332 | width: 74%;
333 | margin: 0 auto;
334 | line-height: 39px;
335 | border-width: thin;
336 | border-bottom: 1px solid #777;
337 | color: #eee;
338 | font-weight: 600;
339 | text-align: left;
340 | padding-left: 20px;
341 | }
342 |
343 | .today-weather ul li span {
344 | float: right;
345 | padding-right: 10px;
346 | }
347 |
348 | .today-weather ul li:nth-child(5) {
349 | border-bottom: none;
350 | }
351 |
352 | .footer {
353 | padding-bottom: 20px;
354 | }
355 |
356 | .copyright p {
357 | color: #fff;
358 | }
359 |
360 | .copyright p a {
361 | color: #fff;
362 | }
363 | /*--w3layouts--*/
364 | /*--agileits--*/
365 | .copyright p a:hover {
366 | color: #ffeb3b;
367 | }
368 |
369 | /*-- //Index-Page-Styling --*/
370 |
371 | /*-- Responsive Code --*/
372 |
373 | @media screen and (max-width: 1920px) {
374 | .container {
375 | width: 50%;
376 | }
377 | }
378 |
379 | @media screen and (max-width: 1440px) {
380 | .container {
381 | width: 55%;
382 | }
383 | }
384 |
385 | @media screen and (max-width: 1280px) {
386 | .container {
387 | width: 60%;
388 | }
389 | }
390 |
391 | @media screen and (max-width: 1024px) {
392 | .container {
393 | width: 75%;
394 | }
395 | }
396 |
397 | @media screen and (max-width: 966px) {
398 | .container {
399 | width: 90%;
400 | }
401 | }
402 |
403 | @media screen and (max-width: 853px) {
404 | h1 {
405 | font-size: 45px;
406 | }
407 | /*--w3layouts--*/
408 | /*--agileits--*/
409 | }
410 |
411 | @media screen and (max-width: 800px) {
412 | h1 {
413 | font-size: 35px;
414 | }
415 | .temperature p {
416 | font-size: 100px;
417 | }
418 | .dmy {
419 | padding-top: 25px;
420 | }
421 | }
422 |
423 | @media screen and (max-width: 736px) {
424 | .temperature p {
425 | font-size: 80px;
426 | }
427 | .dmy {
428 | padding-top: 10px;
429 | }
430 | div#txt {
431 | font-size: 30px;
432 | }
433 | .forecast-icon img {
434 | width: 110px;
435 | }
436 | }
437 |
438 | @media screen and (max-width: 667px) {
439 | h1 {
440 | font-size: 40px;
441 | margin-top: 30px;
442 | }
443 | .container {
444 | width: 95%;
445 | margin-top: 30px;
446 | }
447 | }
448 |
449 | @media screen and (max-width: 640px) {
450 | h1 {
451 | font-size: 30px;
452 | margin-top: 45px;
453 | }
454 | div#txt {
455 | font-size: 25px;
456 | }
457 | /*--w3layouts--*/
458 | /*--agileits--*/
459 | .dmy {
460 | padding-top: 17px;
461 | }
462 | .temperature p {
463 | padding-bottom: 10px;
464 | }
465 | }
466 |
467 | @media screen and (max-width: 603px) {
468 | h1 {
469 | font-size: 35px;
470 | }
471 | .city {
472 | width: 100%;
473 | min-height: 300px;
474 | }
475 | .temperature {
476 | text-align: right;
477 | }
478 | .temperature p {
479 | font-size: 100px;
480 | }
481 | .dmy {
482 | padding-top: 35px;
483 | }
484 | .forecast-icon {
485 | margin: 10px 0;
486 | }
487 | .forecast {
488 | width: 100%;
489 | padding-bottom: 30px;
490 | }
491 | .copyright {
492 | padding-bottom: 20px;
493 | }
494 | .copyright p {
495 | line-height: 30px;
496 | font-size: 14px;
497 | }
498 | }
499 |
500 | @media screen and (max-width: 533px) {
501 | h1 {
502 | font-size: 33px;
503 | }
504 | }
505 |
506 | @media screen and (max-width: 480px) {
507 | /*--w3layouts--*/
508 | /*--agileits--*/
509 | h1 {
510 | font-size: 28px;
511 | letter-spacing: 2px;
512 | }
513 | .container {
514 | margin-bottom: 20px;
515 | }
516 | .forecast-icon {
517 | margin: 40px 0 10px;
518 | }
519 | .forecast-icon img {
520 | width: 100px;
521 | }
522 | .today-weather h3 {
523 | font-size: 40px;
524 | }
525 | .city {
526 | min-height: 450px;
527 | }
528 | .title h2 {
529 | font-size: 25px;
530 | }
531 | .title h3 {
532 | font-size: 14px;
533 | }
534 | .date-time {
535 | width: 100%;
536 | padding: 0;
537 | }
538 | .dmy {
539 | padding: 0;
540 | margin-bottom: 35px;
541 | text-align: center;
542 | width: 100%;
543 | }
544 | div#txt {
545 | font-size: 30px;
546 | }
547 | .date {
548 | font-size: 22px;
549 | }
550 | .temperature {
551 | text-align: center;
552 | width: 100%;
553 | }
554 | .copyright {
555 | padding: 20px;
556 | }
557 | .temperature p {
558 | font-size: 60px;
559 | padding-bottom: 15px;
560 | }
561 | .forecast-icon img {
562 | width: 65px;
563 | }
564 | .today-weather h3 {
565 | font-size: 30px;
566 | }
567 | .copyright p {
568 | line-height: 25px;
569 | font-size: 13px;
570 | }
571 | .container {
572 | height: 60vh;
573 | margin-top: 60px;
574 | }
575 | .mb-icon {
576 | top: 20% !important;
577 | display: block !important;
578 | }
579 | .forecast-icon,
580 | .today-weather h3 {
581 | display: none;
582 | }
583 | .today-weather {
584 | background-color: rgba(0, 0, 0, 0.73);
585 | margin-top: 22px;
586 | padding: 25px 0px;
587 | }
588 | }
589 |
590 | @media screen and (max-width: 375px) {
591 | h1 {
592 | font-size: 26px;
593 | line-height: 1.5em;
594 | letter-spacing: 0;
595 | }
596 | .city {
597 | min-height: 315px;
598 | }
599 | .dmy {
600 | margin-bottom: 30px;
601 | }
602 | .date {
603 | font-size: 18px;
604 | }
605 | .temperature p {
606 | padding-bottom: 15px;
607 | }
608 | }
609 |
610 | /*-- //Responsive Code --*/
611 | .cityHead {
612 | display: flex;
613 | align-items: center;
614 | justify-content: center;
615 | }
616 | .search-box {
617 | display: flex;
618 | align-items: center;
619 | justify-content: center;
620 | margin-bottom: 15px;
621 | position: relative;
622 | z-index: 2;
623 | }
624 | .search-box .img-box {
625 | background: rgb(255, 255, 255, 0.2);
626 | border-radius: 50%;
627 | height: 32px;
628 | width: 35px;
629 | display: flex;
630 | align-items: center;
631 | justify-content: center;
632 | padding: 2px;
633 | }
634 | .search-box img {
635 | width: 60%;
636 | cursor: pointer;
637 | }
638 | .search-box .search-bar {
639 | border: none;
640 | padding: 10px 11px;
641 | background: transparent;
642 | color: white;
643 | border-bottom: 1px solid;
644 | font-size: 16px;
645 | }
646 | .search-box .search-bar::placeholder {
647 | color: white;
648 | }
649 | .search-bar:focus {
650 | outline: none;
651 | border-bottom: 1px solid gray;
652 | transition: all 1s ease-in-out;
653 | }
654 | .mb-icon {
655 | height: 100%;
656 | position: absolute;
657 | top: 34%;
658 | left: 36%;
659 | z-index: 1;
660 | display: none;
661 | }
662 | .mb-icon p {
663 | color: white;
664 | width: fit-content;
665 | position: relative;
666 | left: 24%;
667 | top: 2%;
668 | font-size: 25px;
669 | }
670 | .footer-info {
671 | color: white;
672 | }
673 | .footer-info a {
674 | color: floralwhite;
675 | font-weight: bold;
676 | }
677 | .hh_button {
678 | display: inline-block;
679 | text-decoration: none;
680 | background: linear-gradient(to right, #ff8a00, #da1b60);
681 | border: none;
682 | color: white;
683 | padding: 10px 25px;
684 | font-size: 1rem;
685 | border-radius: 3px;
686 | cursor: pointer;
687 | font-family: "Roboto", sans-serif;
688 | position: relative;
689 | margin-top: 30px;
690 | margin: 0px;
691 | position: absolute;
692 | right: 20px;
693 | top: 1.5%;
694 | }
695 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useState } from "react";
2 | import CurrentLocation from "./currentLocation";
3 | import "./App.css";
4 |
5 | function App() {
6 | return (
7 |
8 |
9 |
10 |
11 |
24 |
25 | );
26 | }
27 |
28 | export default App;
29 |
--------------------------------------------------------------------------------
/src/App.test.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { render } from '@testing-library/react';
3 | import App from './App';
4 |
5 | test('renders learn react link', () => {
6 | const { getByText } = render( );
7 | const linkElement = getByText(/learn react/i);
8 | expect(linkElement).toBeInTheDocument();
9 | });
10 |
--------------------------------------------------------------------------------
/src/apiKeys.js:
--------------------------------------------------------------------------------
1 | // Visit https://api.openweathermap.org & then signup to get our API keys for free
2 | module.exports = {
3 | key: "{Your API Key Here}",
4 | base: "https://api.openweathermap.org/data/2.5/",
5 | };
6 |
--------------------------------------------------------------------------------
/src/currentLocation.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import apiKeys from "./apiKeys";
3 | import Clock from "react-live-clock";
4 | import Forcast from "./forcast";
5 | import loader from "./images/WeatherIcons.gif";
6 | import ReactAnimatedWeather from "react-animated-weather";
7 | const dateBuilder = (d) => {
8 | let months = [
9 | "January",
10 | "February",
11 | "March",
12 | "April",
13 | "May",
14 | "June",
15 | "July",
16 | "August",
17 | "September",
18 | "October",
19 | "November",
20 | "December",
21 | ];
22 | let days = [
23 | "Sunday",
24 | "Monday",
25 | "Tuesday",
26 | "Wednesday",
27 | "Thursday",
28 | "Friday",
29 | "Saturday",
30 | ];
31 |
32 | let day = days[d.getDay()];
33 | let date = d.getDate();
34 | let month = months[d.getMonth()];
35 | let year = d.getFullYear();
36 |
37 | return `${day}, ${date} ${month} ${year}`;
38 | };
39 | const defaults = {
40 | color: "white",
41 | size: 112,
42 | animate: true,
43 | };
44 | class Weather extends React.Component {
45 | state = {
46 | lat: undefined,
47 | lon: undefined,
48 | errorMessage: undefined,
49 | temperatureC: undefined,
50 | temperatureF: undefined,
51 | city: undefined,
52 | country: undefined,
53 | humidity: undefined,
54 | description: undefined,
55 | icon: "CLEAR_DAY",
56 | sunrise: undefined,
57 | sunset: undefined,
58 | errorMsg: undefined,
59 | };
60 |
61 | componentDidMount() {
62 | if (navigator.geolocation) {
63 | this.getPosition()
64 | //If user allow location service then will fetch data & send it to get-weather function.
65 | .then((position) => {
66 | this.getWeather(position.coords.latitude, position.coords.longitude);
67 | })
68 | .catch((err) => {
69 | //If user denied location service then standard location weather will le shown on basis of latitude & latitude.
70 | this.getWeather(28.67, 77.22);
71 | alert(
72 | "You have disabled location service. Allow 'This APP' to access your location. Your current location will be used for calculating Real time weather."
73 | );
74 | });
75 | } else {
76 | alert("Geolocation not available");
77 | }
78 |
79 | this.timerID = setInterval(
80 | () => this.getWeather(this.state.lat, this.state.lon),
81 | 600000
82 | );
83 | }
84 |
85 | componentWillUnmount() {
86 | clearInterval(this.timerID);
87 | }
88 |
89 | // tick = () => {
90 | // this.getPosition()
91 | // .then((position) => {
92 | // this.getWeather(position.coords.latitude, position.coords.longitude)
93 | // })
94 | // .catch((err) => {
95 | // this.setState({ errorMessage: err.message });
96 | // });
97 | // }
98 |
99 | getPosition = (options) => {
100 | return new Promise(function (resolve, reject) {
101 | navigator.geolocation.getCurrentPosition(resolve, reject, options);
102 | });
103 | };
104 | getWeather = async (lat, lon) => {
105 | const api_call = await fetch(
106 | `${apiKeys.base}weather?lat=${lat}&lon=${lon}&units=metric&APPID=${apiKeys.key}`
107 | );
108 | const data = await api_call.json();
109 | this.setState({
110 | lat: lat,
111 | lon: lon,
112 | city: data.name,
113 | temperatureC: Math.round(data.main.temp),
114 | temperatureF: Math.round(data.main.temp * 1.8 + 32),
115 | humidity: data.main.humidity,
116 | main: data.weather[0].main,
117 | country: data.sys.country,
118 | // sunrise: this.getTimeFromUnixTimeStamp(data.sys.sunrise),
119 |
120 | // sunset: this.getTimeFromUnixTimeStamp(data.sys.sunset),
121 | });
122 | switch (this.state.main) {
123 | case "Haze":
124 | this.setState({ icon: "CLEAR_DAY" });
125 | break;
126 | case "Clouds":
127 | this.setState({ icon: "CLOUDY" });
128 | break;
129 | case "Rain":
130 | this.setState({ icon: "RAIN" });
131 | break;
132 | case "Snow":
133 | this.setState({ icon: "SNOW" });
134 | break;
135 | case "Dust":
136 | this.setState({ icon: "WIND" });
137 | break;
138 | case "Drizzle":
139 | this.setState({ icon: "SLEET" });
140 | break;
141 | case "Fog":
142 | this.setState({ icon: "FOG" });
143 | break;
144 | case "Smoke":
145 | this.setState({ icon: "FOG" });
146 | break;
147 | case "Tornado":
148 | this.setState({ icon: "WIND" });
149 | break;
150 | default:
151 | this.setState({ icon: "CLEAR_DAY" });
152 | }
153 | };
154 |
155 | render() {
156 | if (this.state.temperatureC) {
157 | return (
158 |
159 |
160 |
161 |
{this.state.city}
162 | {this.state.country}
163 |
164 |
165 | {" "}
166 |
172 |
{this.state.main}
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
{dateBuilder(new Date())}
181 |
182 |
183 |
184 | {this.state.temperatureC}°C
185 |
186 | {/*
/
187 | {this.state.temperatureF} °F */}
188 |
189 |
190 |
191 |
192 |
193 | );
194 | } else {
195 | return (
196 |
197 |
198 |
199 | Detecting your location
200 |
201 |
202 | Your current location wil be displayed on the App & used
203 | for calculating Real time weather.
204 |
205 |
206 | );
207 | }
208 | }
209 | }
210 |
211 | export default Weather;
212 |
--------------------------------------------------------------------------------
/src/forcast.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect, Component } from "react";
2 | import axios from "axios";
3 | import apiKeys from "./apiKeys";
4 | import ReactAnimatedWeather from "react-animated-weather";
5 |
6 | function Forcast(props) {
7 | const [query, setQuery] = useState("");
8 | const [error, setError] = useState("");
9 | const [weather, setWeather] = useState({});
10 |
11 | const search = (city) => {
12 | axios
13 | .get(
14 | `${apiKeys.base}weather?q=${
15 | city != "[object Object]" ? city : query
16 | }&units=metric&APPID=${apiKeys.key}`
17 | )
18 | .then((response) => {
19 | setWeather(response.data);
20 | setQuery("");
21 | })
22 | .catch(function (error) {
23 | console.log(error);
24 | setWeather("");
25 | setQuery("");
26 | setError({ message: "Not Found", query: query });
27 | });
28 | };
29 | function checkTime(i) {
30 | if (i < 10) {
31 | i = "0" + i;
32 | } // add zero in front of numbers < 10
33 | return i;
34 | }
35 |
36 | const defaults = {
37 | color: "white",
38 | size: 112,
39 | animate: true,
40 | };
41 |
42 | useEffect(() => {
43 | search("Delhi");
44 | }, []);
45 |
46 | return (
47 |
48 |
49 |
55 |
56 |
57 |
{props.weather}
58 |
59 |
setQuery(e.target.value)}
64 | value={query}
65 | />
66 |
67 | {" "}
68 |
72 |
73 |
74 |
75 | {typeof weather.main != "undefined" ? (
76 |
77 | {" "}
78 |
79 |
80 | {weather.name}, {weather.sys.country}
81 |
82 |
86 |
87 |
88 | Temperature{" "}
89 |
90 | {Math.round(weather.main.temp)}°c ({weather.weather[0].main})
91 |
92 |
93 |
94 | Humidity{" "}
95 |
96 | {Math.round(weather.main.humidity)}%
97 |
98 |
99 |
100 | Visibility{" "}
101 |
102 | {Math.round(weather.visibility)} mi
103 |
104 |
105 |
106 | Wind Speed{" "}
107 |
108 | {Math.round(weather.wind.speed)} Km/h
109 |
110 |
111 |
112 | ) : (
113 |
114 | {error.query} {error.message}
115 |
116 | )}
117 |
118 |
119 |
120 | );
121 | }
122 | export default Forcast;
123 |
--------------------------------------------------------------------------------
/src/images/WeatherIcons.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/src/images/WeatherIcons.gif
--------------------------------------------------------------------------------
/src/images/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/src/images/background.jpg
--------------------------------------------------------------------------------
/src/images/background1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/src/images/background1.jpg
--------------------------------------------------------------------------------
/src/images/city.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/src/images/city.jpg
--------------------------------------------------------------------------------
/src/images/city1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/src/images/city1.jpg
--------------------------------------------------------------------------------
/src/images/forecast.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gauravghai/weatherApp-Reactjs/7915d8b4dd2fd8b80f55e72098870f38e3607362/src/images/forecast.png
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
4 | 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
5 | sans-serif;
6 | -webkit-font-smoothing: antialiased;
7 | -moz-osx-font-smoothing: grayscale;
8 | }
9 |
10 | code {
11 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
12 | monospace;
13 | }
14 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom';
3 | import './index.css';
4 | import App from './App';
5 | import * as serviceWorker from './serviceWorker';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want your app to work offline and load faster, you can change
15 | // unregister() to register() below. Note this comes with some pitfalls.
16 | // Learn more about service workers: https://bit.ly/CRA-PWA
17 | serviceWorker.unregister();
18 |
--------------------------------------------------------------------------------
/src/logo.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/serviceWorker.js:
--------------------------------------------------------------------------------
1 | // This optional code is used to register a service worker.
2 | // register() is not called by default.
3 |
4 | // This lets the app load faster on subsequent visits in production, and gives
5 | // it offline capabilities. However, it also means that developers (and users)
6 | // will only see deployed updates on subsequent visits to a page, after all the
7 | // existing tabs open on the page have been closed, since previously cached
8 | // resources are updated in the background.
9 |
10 | // To learn more about the benefits of this model and instructions on how to
11 | // opt-in, read https://bit.ly/CRA-PWA
12 |
13 | const isLocalhost = Boolean(
14 | window.location.hostname === 'localhost' ||
15 | // [::1] is the IPv6 localhost address.
16 | window.location.hostname === '[::1]' ||
17 | // 127.0.0.0/8 are considered localhost for IPv4.
18 | window.location.hostname.match(
19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
20 | )
21 | );
22 |
23 | export function register(config) {
24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
25 | // The URL constructor is available in all browsers that support SW.
26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
27 | if (publicUrl.origin !== window.location.origin) {
28 | // Our service worker won't work if PUBLIC_URL is on a different origin
29 | // from what our page is served on. This might happen if a CDN is used to
30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374
31 | return;
32 | }
33 |
34 | window.addEventListener('load', () => {
35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
36 |
37 | if (isLocalhost) {
38 | // This is running on localhost. Let's check if a service worker still exists or not.
39 | checkValidServiceWorker(swUrl, config);
40 |
41 | // Add some additional logging to localhost, pointing developers to the
42 | // service worker/PWA documentation.
43 | navigator.serviceWorker.ready.then(() => {
44 | console.log(
45 | 'This web app is being served cache-first by a service ' +
46 | 'worker. To learn more, visit https://bit.ly/CRA-PWA'
47 | );
48 | });
49 | } else {
50 | // Is not localhost. Just register service worker
51 | registerValidSW(swUrl, config);
52 | }
53 | });
54 | }
55 | }
56 |
57 | function registerValidSW(swUrl, config) {
58 | navigator.serviceWorker
59 | .register(swUrl)
60 | .then(registration => {
61 | registration.onupdatefound = () => {
62 | const installingWorker = registration.installing;
63 | if (installingWorker == null) {
64 | return;
65 | }
66 | installingWorker.onstatechange = () => {
67 | if (installingWorker.state === 'installed') {
68 | if (navigator.serviceWorker.controller) {
69 | // At this point, the updated precached content has been fetched,
70 | // but the previous service worker will still serve the older
71 | // content until all client tabs are closed.
72 | console.log(
73 | 'New content is available and will be used when all ' +
74 | 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
75 | );
76 |
77 | // Execute callback
78 | if (config && config.onUpdate) {
79 | config.onUpdate(registration);
80 | }
81 | } else {
82 | // At this point, everything has been precached.
83 | // It's the perfect time to display a
84 | // "Content is cached for offline use." message.
85 | console.log('Content is cached for offline use.');
86 |
87 | // Execute callback
88 | if (config && config.onSuccess) {
89 | config.onSuccess(registration);
90 | }
91 | }
92 | }
93 | };
94 | };
95 | })
96 | .catch(error => {
97 | console.error('Error during service worker registration:', error);
98 | });
99 | }
100 |
101 | function checkValidServiceWorker(swUrl, config) {
102 | // Check if the service worker can be found. If it can't reload the page.
103 | fetch(swUrl, {
104 | headers: { 'Service-Worker': 'script' },
105 | })
106 | .then(response => {
107 | // Ensure service worker exists, and that we really are getting a JS file.
108 | const contentType = response.headers.get('content-type');
109 | if (
110 | response.status === 404 ||
111 | (contentType != null && contentType.indexOf('javascript') === -1)
112 | ) {
113 | // No service worker found. Probably a different app. Reload the page.
114 | navigator.serviceWorker.ready.then(registration => {
115 | registration.unregister().then(() => {
116 | window.location.reload();
117 | });
118 | });
119 | } else {
120 | // Service worker found. Proceed as normal.
121 | registerValidSW(swUrl, config);
122 | }
123 | })
124 | .catch(() => {
125 | console.log(
126 | 'No internet connection found. App is running in offline mode.'
127 | );
128 | });
129 | }
130 |
131 | export function unregister() {
132 | if ('serviceWorker' in navigator) {
133 | navigator.serviceWorker.ready
134 | .then(registration => {
135 | registration.unregister();
136 | })
137 | .catch(error => {
138 | console.error(error.message);
139 | });
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import '@testing-library/jest-dom/extend-expect';
6 |
--------------------------------------------------------------------------------