├── public
├── favicon.ico
├── logo192.png
├── logo512.png
├── robots.txt
├── manifest.json
└── index.html
├── Covid_tracker_sample.PNG
├── src
├── Table.css
├── index.css
├── reportWebVitals.js
├── Table.js
├── index.js
├── Map.css
├── InfoBox.css
├── App.css
├── Map.js
├── InfoBox.js
├── util.js
├── LineGraph.js
└── App.js
├── .gitignore
├── README.md
├── package.json
├── .firebase
└── hosting.YnVpbGQ.cache
└── .eslintcache
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShinAKS/covid-19-tracker/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShinAKS/covid-19-tracker/HEAD/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShinAKS/covid-19-tracker/HEAD/public/logo512.png
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | # https://www.robotstxt.org/robotstxt.html
2 | User-agent: *
3 | Disallow:
4 |
--------------------------------------------------------------------------------
/Covid_tracker_sample.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ShinAKS/covid-19-tracker/HEAD/Covid_tracker_sample.PNG
--------------------------------------------------------------------------------
/src/Table.css:
--------------------------------------------------------------------------------
1 | .table {
2 | margin-top: 20px;
3 | overflow: scroll;
4 | height: 400px;
5 | color: #6a5d5d;
6 | background-color: #fff;
7 | }
8 |
9 | .table tr {
10 | display: flex;
11 | justify-content: space-between;
12 | }
13 |
14 | .table td {
15 | padding: 0.5rem;
16 | }
17 | .table tr:nth-of-type(odd) {
18 | background-color: #f3f2f8;
19 | }
20 |
--------------------------------------------------------------------------------
/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/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/Table.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import "./Table.css";
3 | import numeral from "numeral";
4 |
5 | function Table({ countries }) {
6 | return (
7 |
8 | {countries.map(({ country, cases }) => (
9 |
10 | | {country} |
11 |
12 | {numeral(cases).format("000,000")}
13 | |
14 |
15 | ))}
16 |
17 | );
18 | }
19 |
20 | export default Table;
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2 |
3 | # dependencies
4 | /node_modules
5 | /.pnp
6 | .pnp.js
7 |
8 | # testing
9 | /coverage
10 |
11 | # production
12 | /build
13 |
14 | # misc
15 | .DS_Store
16 | .env.local
17 | .env.development.local
18 | .env.test.local
19 | .env.production.local
20 |
21 | npm-debug.log*
22 | yarn-debug.log*
23 | yarn-error.log*
24 |
25 |
26 | #firebase config
27 |
28 | firebase.json
29 | .firebaserc
30 | .firebase
31 |
--------------------------------------------------------------------------------
/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 reportWebVitals from './reportWebVitals';
6 |
7 | ReactDOM.render(
8 |
9 |
10 | ,
11 | document.getElementById('root')
12 | );
13 |
14 | // If you want to start measuring performance in your app, pass a function
15 | // to log results (for example: reportWebVitals(console.log))
16 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
17 | reportWebVitals();
18 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/src/Map.css:
--------------------------------------------------------------------------------
1 | .map {
2 | height: 500px;
3 | background-color: white;
4 | padding: 1rem;
5 | border-radius: 20px;
6 | margin-top: 16px;
7 | box-shadow: 0 0 8px -4px rgba(0, 0, 0, 0.5);
8 | }
9 |
10 | .info-flag img {
11 | width: 100px;
12 | border-radius: 5px;
13 | }
14 |
15 | .info-flag {
16 | height: 80px;
17 | width: 100%;
18 | background-size: cover;
19 | border-radius: 8px;
20 | }
21 |
22 | .info-confirmed,
23 | .info-deaths,
24 | .info-recovered {
25 | font-size: 16px;
26 | margin-top: 5px;
27 | }
28 |
29 | .info-name {
30 | font-size: 20px;
31 | font-weight: bold;
32 | color: #555;
33 | }
34 |
--------------------------------------------------------------------------------
/src/InfoBox.css:
--------------------------------------------------------------------------------
1 | @import url("https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css");
2 |
3 | .infoBox {
4 | flex: 1;
5 | cursor: pointer;
6 | }
7 |
8 | .infoBox:not(:last-child) {
9 | margin-right: 15px;
10 | }
11 |
12 | .infoBox__cases {
13 | color: #cc1034;
14 | font-weight: 600;
15 | font-size: 1.75rem;
16 | margin-bottom: 0.5rem;
17 | }
18 |
19 | .infoBox--selected {
20 | border-top: 10px solid greenyellow;
21 | }
22 |
23 | .infoBox--red {
24 | border-color: red;
25 | }
26 |
27 | .infoBox__cases--green {
28 | color: lightgreen;
29 | }
30 |
31 | .infoBox--grey {
32 | border-color: grey;
33 | }
34 |
35 | .infoBox__cases--grey {
36 | color: grey;
37 | }
38 |
39 | .infoBox__total {
40 | color: #6c757d;
41 | font-weight: 700 !important;
42 | font-size: 0.8rem !important;
43 | margin-top: 15px !important;
44 | }
45 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | * {
2 | margin: 0;
3 | }
4 |
5 | body {
6 | background-color: #f5f6fa;
7 | }
8 |
9 | .app {
10 | display: flex;
11 | justify-content: space-evenly;
12 | padding: 20px;
13 | }
14 |
15 | .app__header {
16 | display: flex;
17 | justify-content: space-between;
18 | align-items: center;
19 | margin-bottom: 20px;
20 | }
21 |
22 | .app__stats {
23 | display: flex;
24 | justify-content: space-between;
25 | }
26 |
27 | .app__left {
28 | flex: 0.9;
29 | }
30 |
31 | .app__right {
32 | display: flex;
33 | flex-direction: column;
34 | }
35 |
36 | .app__graphTitle {
37 | margin-top: 20px;
38 | margin-bottom: 20px;
39 | }
40 |
41 | .app__right .MuiCardContent-root {
42 | display: flex;
43 | flex-direction: column;
44 | flex-grow: 1;
45 | }
46 |
47 | .app__graph {
48 | flex-grow: 1;
49 | }
50 |
51 | @media (max-width: 990px) {
52 | .app {
53 | flex-direction: column;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/Map.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { MapContainer, TileLayer, useMap } from "react-leaflet";
3 | import "./Map.css";
4 | import { showDataOnMap } from "./util";
5 |
6 | function Map({ countries, casesType, center, zoom }) {
7 | function ChangeView({ center, zoom }) {
8 | const map = useMap();
9 | map.setView(center, zoom);
10 | return null;
11 | }
12 |
13 | return (
14 |
21 |
22 |
26 | {showDataOnMap(countries, casesType)}
27 |
28 | );
29 | }
30 |
31 | export default Map;
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Covid-19 Tracker App
2 |
3 | This Project is a beginner friendly project I built using React. Some key Aspects:
4 |
5 | - Shows Live Cases, Recoveries, Deaths (clickable tabs)
6 | - Shows Worldwide cases and Country Based cases
7 | - Line Chart shows fluctuations over days, hover around to see exact figures
8 | - Clickable Markers on Map show Country stats
9 |
10 | Deployed live on https://covid-19-tracker-6b428.web.app/ . Check out!
11 |
12 | 
13 |
14 | # Getting Started with Create React App
15 |
16 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app).
17 |
18 | ## Available Scripts
19 |
20 | In the project directory, you can run:
21 |
22 | ### `npm start`
23 |
24 | Runs the app in the development mode.\
25 | Open [http://localhost:3000](http://localhost:3000) to view it in the browser.
26 |
27 | The page will reload if you make edits.\
28 | You will also see any lint errors in the console.
29 |
--------------------------------------------------------------------------------
/src/InfoBox.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Card, CardContent, Typography } from "@material-ui/core";
3 | import "./InfoBox.css";
4 | function InfoBox({ title, isRed, isGrey, active, cases, total, ...props }) {
5 | return (
6 |
12 |
13 | {/* Title */}
14 |
15 | {title}
16 |
17 |
18 | {/* Number of Cases */}
19 |
24 | {props.isloading ? : cases}
25 |
26 |
27 | {/* Total Cases */}
28 |
29 | {total} Total
30 |
31 |
32 |
33 | );
34 | }
35 |
36 | export default InfoBox;
37 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "covid-19-tracker",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@material-ui/core": "^4.11.2",
7 | "@testing-library/jest-dom": "^5.11.6",
8 | "@testing-library/react": "^11.2.2",
9 | "@testing-library/user-event": "^12.6.0",
10 | "chart.js": "^2.9.4",
11 | "firebase-tools": "^9.1.0",
12 | "leaflet": "^1.7.1",
13 | "numeral": "^2.0.6",
14 | "react": "^17.0.1",
15 | "react-chartjs-2": "^2.11.1",
16 | "react-dom": "^17.0.1",
17 | "react-leaflet": "^3.0.5",
18 | "react-scripts": "4.0.1",
19 | "web-vitals": "^0.2.4"
20 | },
21 | "scripts": {
22 | "start": "react-scripts start",
23 | "build": "react-scripts build",
24 | "test": "react-scripts test",
25 | "eject": "react-scripts eject"
26 | },
27 | "eslintConfig": {
28 | "extends": [
29 | "react-app",
30 | "react-app/jest"
31 | ]
32 | },
33 | "browserslist": {
34 | "production": [
35 | ">0.2%",
36 | "not dead",
37 | "not op_mini all"
38 | ],
39 | "development": [
40 | "last 1 chrome version",
41 | "last 1 firefox version",
42 | "last 1 safari version"
43 | ]
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 |
13 |
17 |
18 |
27 | React App
28 |
29 |
30 |
31 |
32 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/.firebase/hosting.YnVpbGQ.cache:
--------------------------------------------------------------------------------
1 | favicon.ico,499162500000,eae62e993eb980ec8a25058c39d5a51feab118bd2100c4deebb2a9c158ec11f9
2 | logo192.png,499162500000,3ee59515172ee198f3be375979df15ac5345183e656720a381b8872b2a39dc8b
3 | logo512.png,499162500000,ee7e2f3fdb8209c4b6fd7bef6ba50d1b9dba30a25bb5c3126df057e1cb6f5331
4 | manifest.json,499162500000,aff3449bdc238776f5d6d967f19ec491b36aed5fb7f23ccff6500736fd58494a
5 | robots.txt,499162500000,bfe106a3fb878dc83461c86818bf74fc1bdc7f28538ba613cd3e775516ce8b49
6 | static/css/main.7ff08ab0.chunk.css,1609431605193,1128d7c674abfc1a0d20ce839b93f62367a1b46459442b87fead4f5bc0a0224a
7 | static/css/main.7ff08ab0.chunk.css.map,1609431605224,a212bb60827c66875ee1bf833e88457d366cabcd9b22f5ac5b72d61294ba0f39
8 | static/js/2.00ab2c94.chunk.js.LICENSE.txt,1609431605224,95f57834b6b957f611d57eb1c093d827c740a91b4d0d8a998256a0381faf2c40
9 | static/css/2.b4ebbe46.chunk.css,1609431605224,9fc39d3613cefe3d187df9929b58765b42dab9c7212a00f713f07dcea3efbb2b
10 | static/css/2.b4ebbe46.chunk.css.map,1609431605224,89b47f588f6050fc7840aecdcb505b7abd65a2c5ad92f8a671c1dfe1641eca53
11 | static/js/3.5ab18096.chunk.js,1609431605224,8f22e7ad709e0382f44a081a76da1912bcfe72380761b76ef2642f9a1aff670c
12 | static/js/3.5ab18096.chunk.js.map,1609431605225,17b5f069069c97e2f311a53ac2f3babb1e4370652a100f04d48dc3370a277c71
13 | static/js/main.bfb68229.chunk.js,1609431605193,42422450e13eaaeb25631473a29565f54f54abd10624c33717394dfaad9ba48a
14 | static/js/runtime-main.5af8325c.js,1609431605224,0932d9e702a2353e0f10c0ef03fccb3537a8e691630e5d95a221da93b8a0d263
15 | static/js/runtime-main.5af8325c.js.map,1609431605225,f8ec6457b28622d81d0391e32e7bfb99da7802ebc47e877f25e4c163fde1fb56
16 | asset-manifest.json,1609431605192,017f003f0de6c37b0b15d7cd3b47fe8c4aa51203504d824698e83dbef7dda14c
17 | index.html,1609431605192,57514d56b604b98449e9c1b5cc598b93639b591d5c4af1f9de69c0596ca1126d
18 | static/js/main.bfb68229.chunk.js.map,1609431605224,6cb035c3a1397cd5a222ba1bfdc19492cb42517207c66ec88544e20242a0146a
19 | static/js/2.00ab2c94.chunk.js,1609431605224,a83603b3ff83d0e7353c93ff04365d0ccfc3df82166761a237b4a484bdb05ed1
20 | static/js/2.00ab2c94.chunk.js.map,1609431605226,17ad4d1400c462137adc6ff4583adee350238c23b6aedc4b51fb7ddb03a66263
21 |
--------------------------------------------------------------------------------
/src/util.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import numeral from "numeral";
3 | import { Circle, Popup } from "react-leaflet";
4 |
5 | const casesTypeColors = {
6 | cases: {
7 | hex: "#CC1034",
8 | // rgb: "rgb(204,16,52)",
9 | // half_op: "rgba(204,16,52,0.5)",
10 | mulitiplier: 800,
11 | },
12 |
13 | recovered: {
14 | hex: "#7DD71D",
15 | // rgb: "rgb(125,215,29)",
16 | // half_op: "rgba(125,215,29,0.5)",
17 | mulitiplier: 1200,
18 | },
19 |
20 | deaths: {
21 | hex: "#C0C0C0",
22 | // rgb: "rgb(251,68,67)",
23 | // half_op: "rgba(251,68,67,0.5)",
24 | mulitiplier: 2000,
25 | },
26 | };
27 |
28 | export const sortData = (data) => {
29 | const sortedData = [...data];
30 |
31 | sortedData.sort((a, b) => b.cases - a.cases);
32 |
33 | return sortedData;
34 | };
35 |
36 | export const prettyPrintStat = (stat) =>
37 | stat ? `+${numeral(stat).format("0.0a")}` : "+0";
38 |
39 | //Draw circles on the map
40 | export const showDataOnMap = (data, casesType) =>
41 | data.map((country) => (
42 |
54 |
55 |
56 |
60 |
{country.country}
61 |
62 | Cases: {numeral(country.cases).format("0,0")}
63 |
64 |
65 | Recovered: {numeral(country.recovered).format("0,0")}
66 |
67 |
68 | Deaths: {numeral(country.deaths).format("0,0")}
69 |
70 |
71 |
72 |
73 | ));
74 |
--------------------------------------------------------------------------------
/.eslintcache:
--------------------------------------------------------------------------------
1 | [{"E:\\Acads\\covid-19-tracker\\src\\index.js":"1","E:\\Acads\\covid-19-tracker\\src\\App.js":"2","E:\\Acads\\covid-19-tracker\\src\\reportWebVitals.js":"3","E:\\Acads\\covid-19-tracker\\src\\InfoBox.js":"4","E:\\Acads\\covid-19-tracker\\src\\Map.js":"5","E:\\Acads\\covid-19-tracker\\src\\Table.js":"6","E:\\Acads\\covid-19-tracker\\src\\util.js":"7","E:\\Acads\\covid-19-tracker\\src\\LineGraph.js":"8"},{"size":500,"mtime":499162500000,"results":"9","hashOfConfig":"10"},{"size":4844,"mtime":1612121016081,"results":"11","hashOfConfig":"10"},{"size":362,"mtime":499162500000,"results":"12","hashOfConfig":"10"},{"size":1068,"mtime":1612121207217,"results":"13","hashOfConfig":"10"},{"size":842,"mtime":1609415043842,"results":"14","hashOfConfig":"10"},{"size":421,"mtime":1609414635369,"results":"15","hashOfConfig":"10"},{"size":1957,"mtime":1609430555352,"results":"16","hashOfConfig":"10"},{"size":2338,"mtime":1609418331081,"results":"17","hashOfConfig":"10"},{"filePath":"18","messages":"19","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"u0vcd3",{"filePath":"20","messages":"21","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"22","messages":"23","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"24","messages":"25","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"26","messages":"27","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"28","messages":"29","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"30","messages":"31","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},{"filePath":"32","messages":"33","errorCount":0,"warningCount":0,"fixableErrorCount":0,"fixableWarningCount":0},"E:\\Acads\\covid-19-tracker\\src\\index.js",[],"E:\\Acads\\covid-19-tracker\\src\\App.js",[],"E:\\Acads\\covid-19-tracker\\src\\reportWebVitals.js",[],"E:\\Acads\\covid-19-tracker\\src\\InfoBox.js",[],"E:\\Acads\\covid-19-tracker\\src\\Map.js",[],"E:\\Acads\\covid-19-tracker\\src\\Table.js",[],"E:\\Acads\\covid-19-tracker\\src\\util.js",[],"E:\\Acads\\covid-19-tracker\\src\\LineGraph.js",[]]
--------------------------------------------------------------------------------
/src/LineGraph.js:
--------------------------------------------------------------------------------
1 | import React, { useState, useEffect } from "react";
2 | import { Line } from "react-chartjs-2";
3 | import numeral from "numeral";
4 |
5 | const options = {
6 | legend: {
7 | display: false,
8 | },
9 | elements: {
10 | point: {
11 | radius: 0,
12 | },
13 | },
14 | maintainAspectRatio: false,
15 | tooltips: {
16 | mode: "index",
17 | intersect: false,
18 | callbacks: {
19 | label: function (tooltipItem, data) {
20 | return numeral(tooltipItem.value).format("+0,0");
21 | },
22 | },
23 | },
24 | scales: {
25 | xAxes: [
26 | {
27 | type: "time",
28 | time: {
29 | format: "MM/DD/YY",
30 | tooltipFormat: "ll",
31 | },
32 | },
33 | ],
34 | yAxes: [
35 | {
36 | gridLines: {
37 | display: false,
38 | },
39 | ticks: {
40 | // Include a dollar sign in the ticks
41 | callback: function (value, index, values) {
42 | return numeral(value).format("0a");
43 | },
44 | },
45 | },
46 | ],
47 | },
48 | };
49 |
50 | const buildChartData = (data, casesType) => {
51 | let chartData = [];
52 | let lastDataPoint;
53 | for (let date in data.cases) {
54 | if (lastDataPoint) {
55 | let newDataPoint = {
56 | x: date,
57 | y: data[casesType][date] - lastDataPoint,
58 | };
59 | chartData.push(newDataPoint);
60 | }
61 | lastDataPoint = data[casesType][date];
62 | }
63 | return chartData;
64 | };
65 |
66 | function LineGraph({ casesType, ...props }) {
67 | const [data, setData] = useState({});
68 |
69 | useEffect(() => {
70 | const fetchData = async () => {
71 | await fetch("https://disease.sh/v3/covid-19/historical/all?lastdays=120")
72 | .then((response) => {
73 | return response.json();
74 | })
75 | .then((data) => {
76 | let chartData = buildChartData(data, casesType);
77 | setData(chartData);
78 | console.log(chartData);
79 | // buildChart(chartData);
80 | });
81 | };
82 |
83 | fetchData();
84 | }, [casesType]);
85 |
86 | return (
87 |
88 | {data?.length > 0 && (
89 |
101 | )}
102 |
103 | );
104 | }
105 |
106 | export default LineGraph;
107 |
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useState } from "react";
2 | import "./App.css";
3 | import {
4 | MenuItem,
5 | FormControl,
6 | Select,
7 | CardContent,
8 | Card,
9 | } from "@material-ui/core";
10 | import InfoBox from "./InfoBox";
11 | import Map from "./Map";
12 | import Table from "./Table";
13 | import { sortData, prettyPrintStat } from "./util";
14 | import LineGraph from "./LineGraph";
15 | import "leaflet/dist/leaflet.css";
16 | import "./InfoBox.css";
17 |
18 | function App() {
19 | const [countries, setCountries] = useState([]);
20 | const [country, setCountry] = useState("worldwide");
21 | const [countryInfo, setCountryInfo] = useState({});
22 | const [tableData, setTableData] = useState([]);
23 | const [mapCenter, setMapCenter] = useState([34.80746, -40.4796]);
24 | const [zoom, setZoom] = useState(3);
25 | const [mapCountries, setMapCountries] = useState([]);
26 | const [casesType, setCasesType] = useState("cases");
27 | const [isLoading, setLoading] = useState(false);
28 |
29 | useEffect(() => {
30 | fetch("https://disease.sh/v3/covid-19/all")
31 | .then((response) => response.json())
32 | .then((data) => {
33 | setCountryInfo(data);
34 | });
35 | }, []);
36 |
37 | useEffect(() => {
38 | const getCountriesData = async () => {
39 | await fetch("https://disease.sh/v3/covid-19/countries")
40 | .then((response) => response.json())
41 | .then((data) => {
42 | const countries = data.map((country) => ({
43 | name: country.country,
44 | value: country.countryInfo.iso2,
45 | }));
46 |
47 | const sortedData = sortData(data);
48 | setTableData(sortedData);
49 | setMapCountries(data);
50 | setCountries(countries);
51 | });
52 | };
53 |
54 | getCountriesData();
55 | }, []);
56 |
57 | const onCountryChange = async (event) => {
58 | setLoading(true);
59 | const countryCode = event.target.value;
60 |
61 | setCountry(countryCode);
62 |
63 | const url =
64 | countryCode === "worldwide"
65 | ? "https://disease.sh/v3/covid-19/all"
66 | : `https://disease.sh/v3/covid-19/countries/${countryCode}`;
67 |
68 | //https://disease.sh/v3/covid-19/all
69 | //https://disease.sh/v3/covid-19/countries/[countryCode]
70 |
71 | await fetch(url)
72 | .then((response) => response.json())
73 | .then((data) => {
74 | setCountry(countryCode);
75 | setCountryInfo(data);
76 | setLoading(false);
77 | // console.log([data.countryInfo.lat, data.countryInfo.long]);
78 | countryCode === "worldwide"
79 | ? setMapCenter([34.80746, -40.4796])
80 | : setMapCenter([data.countryInfo.lat, data.countryInfo.long]);
81 | setZoom(4);
82 | });
83 |
84 | console.log(countryInfo);
85 | };
86 |
87 | return (
88 |
89 |
90 |
91 |
Covid-19 tracker
92 |
93 |
103 |
104 |
105 |
106 |
107 | setCasesType("cases")}
112 | title="Coronavirus Cases"
113 | total={prettyPrintStat(countryInfo.cases)}
114 | cases={prettyPrintStat(countryInfo.todayCases)}
115 | isloading={isLoading}
116 | />
117 | setCasesType("recovered")}
121 | title="Recovered"
122 | total={prettyPrintStat(countryInfo.recovered)}
123 | cases={prettyPrintStat(countryInfo.todayRecovered)}
124 | isloading={isLoading}
125 | />
126 | setCasesType("deaths")}
131 | title="Deaths"
132 | total={prettyPrintStat(countryInfo.deaths)}
133 | cases={prettyPrintStat(countryInfo.todayDeaths)}
134 | isloading={isLoading}
135 | />
136 |
137 | {/* Map */}
138 |
144 |
145 |
146 |
147 | Live Cases by Country
148 |
149 | WorldWide new {casesType}
150 |
151 |
152 | {/* Table */}
153 | {/* Graph */}
154 |
155 |
156 | );
157 | }
158 |
159 | export default App;
160 |
--------------------------------------------------------------------------------