├── 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 | ![](Covid_tracker_sample.PNG) 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 | --------------------------------------------------------------------------------