├── .gitignore
├── kopid.png
├── package-lock.json
├── package.json
├── postcss.config.js
├── public
├── favicon.ico
├── img
│ └── background.jpg
├── index.html
├── manifest.json
└── robots.txt
├── readme.md
├── src
├── App.js
├── components
│ ├── DataApi.jsx
│ ├── Homepage.jsx
│ ├── images
│ │ ├── layout 2x2.png
│ │ ├── layout 3x3.png
│ │ └── layout default.png
│ └── layouts
│ │ ├── DefaultLayout.jsx
│ │ ├── LayoutThreeColumn.jsx
│ │ ├── LayoutTwoColumn.jsx
│ │ └── index.js
├── index.css
└── index.js
└── tailwind.config.js
/.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 |
--------------------------------------------------------------------------------
/kopid.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adeyusuf211/project-kopid/9eb9a62cc7ca1c64d8edae8b323666dc0e165362/kopid.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kopid",
3 | "version": "0.1.0",
4 | "private": true,
5 | "dependencies": {
6 | "@testing-library/jest-dom": "^5.16.4",
7 | "@testing-library/react": "^13.3.0",
8 | "@testing-library/user-event": "^13.5.0",
9 | "react": "^18.2.0",
10 | "react-dom": "^18.2.0",
11 | "react-scripts": "5.0.1",
12 | "web-vitals": "^2.1.4"
13 | },
14 | "scripts": {
15 | "start": "react-scripts start",
16 | "build": "react-scripts build",
17 | "test": "react-scripts test",
18 | "eject": "react-scripts eject"
19 | },
20 | "eslintConfig": {
21 | "extends": [
22 | "react-app",
23 | "react-app/jest"
24 | ]
25 | },
26 | "browserslist": {
27 | "production": [
28 | ">0.2%",
29 | "not dead",
30 | "not op_mini all"
31 | ],
32 | "development": [
33 | "last 1 chrome version",
34 | "last 1 firefox version",
35 | "last 1 safari version"
36 | ]
37 | },
38 | "devDependencies": {
39 | "autoprefixer": "^10.4.7",
40 | "postcss": "^8.4.14",
41 | "tailwindcss": "^3.1.5"
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: {
3 | tailwindcss: {},
4 | autoprefixer: {},
5 | },
6 | }
7 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adeyusuf211/project-kopid/9eb9a62cc7ca1c64d8edae8b323666dc0e165362/public/favicon.ico
--------------------------------------------------------------------------------
/public/img/background.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adeyusuf211/project-kopid/9eb9a62cc7ca1c64d8edae8b323666dc0e165362/public/img/background.jpg
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
12 | Kopid | Covid 19 Data
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/readme.md:
--------------------------------------------------------------------------------
1 | KOPID - COVID 19 TRACKER
2 |
3 | Ini adalah sebuah website yang menyediakan berbagai data covid 19 dari seluruh dunia yang dibuat dengan menggunakan teknologi HTML, CSS, ReactJS dan TailwindCSS
4 |
5 | 
--------------------------------------------------------------------------------
/src/App.js:
--------------------------------------------------------------------------------
1 | import Homepage from "./components/Homepage";
2 |
3 | function App() {
4 | return (
5 |
6 |
7 |
8 |
Kopid
9 |
10 | Track a Covid Data Now.
11 |
12 |
13 |
14 |
15 |
16 |
17 |
37 |
38 | );
39 | }
40 |
41 | export default App;
42 |
--------------------------------------------------------------------------------
/src/components/DataApi.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { DefaultLayout, LayoutTwoColumn, LayoutThreeColumn } from "./layouts";
3 |
4 | const DataApi = ({data, text, layout}) => {
5 | return (
6 |
7 | {layout === "layout2" ? (
8 |
9 | ) : layout === "layout3" ? (
10 |
11 | ) : (
12 |
13 | )}
14 |
15 | );
16 | };
17 |
18 | export default DataApi;
19 |
--------------------------------------------------------------------------------
/src/components/Homepage.jsx:
--------------------------------------------------------------------------------
1 | import React, {useState} from "react";
2 | import DataApi from "./DataApi";
3 | import LayoutDefault from './images/layout default.png'
4 | import Layout2x2 from './images/layout 2x2.png'
5 | import Layout3x3 from './images/layout 3x3.png'
6 |
7 | const Homepage = () => {
8 | const [data, setData] = useState("");
9 | const [text, setText] = useState("");
10 | const [search, setSearch] = useState("World");
11 | const [click, setClick] = useState(false);
12 | const [layout, setLayout] = useState("default");
13 |
14 | const handleChange = (e) => {
15 | const finalText = e.target.value;
16 | setText(finalText.toLowerCase());
17 | };
18 |
19 | const handleClick = () => {
20 | setClick(true);
21 |
22 | fetch(`https://disease.sh/v3/covid-19/countries/${text}`)
23 | .then((res) => {
24 | if(res.ok) {
25 | return res.json();
26 | }
27 | throw new Error(setSearch(`${text} cant found`))
28 | })
29 | .then((hasil) => {
30 | const dataCountry = hasil.country.toLowerCase();
31 | if(dataCountry) {
32 | setData(hasil)
33 | }
34 | })
35 | .catch((error) => console.log(error));
36 |
37 | text === "" ? setSearch("World") : setSearch(text);
38 | };
39 |
40 | if(text === "") {
41 | fetch(`https://disease.sh/v3/covid-19/all`)
42 | .then((res) => {
43 | if(res.ok) {
44 | return res.json()
45 | }
46 | throw new Error(`Can't found`)
47 | })
48 | .then((hasil) => setData(hasil))
49 | .catch((error) => console.log(error));
50 | }
51 |
52 | const changeLayout = (str) =>
53 | str === "layout2" ? setLayout("layout2")
54 | : str === "layout3" ? setLayout("layout3")
55 | : setLayout("default");
56 |
57 | return (
58 |
59 |
60 |
61 |
69 |
75 |
76 |
Data: {search}
77 |
78 |

changeLayout("default")}
81 | />
82 |

changeLayout("layout2")}
86 | />
87 |

changeLayout("layout3")}
91 | />
92 |
93 |
94 |
95 |
96 | );
97 | }
98 |
99 | export default Homepage;
--------------------------------------------------------------------------------
/src/components/images/layout 2x2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adeyusuf211/project-kopid/9eb9a62cc7ca1c64d8edae8b323666dc0e165362/src/components/images/layout 2x2.png
--------------------------------------------------------------------------------
/src/components/images/layout 3x3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adeyusuf211/project-kopid/9eb9a62cc7ca1c64d8edae8b323666dc0e165362/src/components/images/layout 3x3.png
--------------------------------------------------------------------------------
/src/components/images/layout default.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/adeyusuf211/project-kopid/9eb9a62cc7ca1c64d8edae8b323666dc0e165362/src/components/images/layout default.png
--------------------------------------------------------------------------------
/src/components/layouts/DefaultLayout.jsx:
--------------------------------------------------------------------------------
1 | const DefaultLayout = ({data, text}) => {
2 | return (
3 |
4 | {data.countryInfo ? (
5 |
6 |

7 |
8 | ) : (
9 | ""
10 | )}
11 | {data.country ? (
12 |
13 |
{data.country.toUpperCase()}
14 |
15 | ) : (
16 |
17 |
WORLD
18 |
19 | )}
20 |
21 |
22 |
Population
23 |
24 | {text !== ""
25 | ? data.population.toLocaleString("id-ID")
26 | : data.population}
27 |
28 |
29 |
30 |
Total Cases / Population (%)
31 |
32 | {(
33 | (parseFloat(data.cases) / parseFloat(data.population)) *
34 | parseFloat(100)
35 | ).toFixed(2)}
36 | %
37 |
38 |
39 |
40 |
41 |
42 |
Cases
43 |
44 | {text !== "" ? data.cases.toLocaleString("id-ID") : data.cases}
45 |
46 |
47 |
48 |
Recovered
49 |
50 | {text !== ""
51 | ? data.recovered.toLocaleString("id-ID")
52 | : data.recovered}
53 |
54 |
55 |
56 |
Deaths
57 |
58 | {text !== "" ? data.deaths.toLocaleString("id-ID") : data.deaths}
59 |
60 |
61 |
62 |
63 |
64 |
Active
65 |
66 | {text !== "" ? data.active.toLocaleString("id-ID") : data.active}
67 |
68 |
69 |
70 |
Critical
71 |
72 | {text !== ""
73 | ? data.critical.toLocaleString("id-ID")
74 | : data.critical}
75 |
76 |
77 |
78 |
79 |
80 |
Recovered (%)
81 |
82 | {(
83 | (parseFloat(data.recovered) / parseFloat(data.cases)) *
84 | parseFloat(100)
85 | ).toFixed(2)}
86 | %
87 |
88 |
89 |
90 |
Deaths (%)
91 |
92 | {(
93 | (parseFloat(data.deaths) / parseFloat(data.cases)) *
94 | parseFloat(100)
95 | ).toFixed(2)}
96 | %
97 |
98 |
99 |
100 |
Active (%)
101 |
102 | {(
103 | (parseFloat(data.active) / parseFloat(data.cases)) *
104 | parseFloat(100)
105 | ).toFixed(2)}
106 | %
107 |
108 |
109 |
110 |
111 |
112 |
Today Cases
113 |
114 | {text !== ""
115 | ? data.todayCases.toLocaleString("id-ID")
116 | : data.todayCases}
117 |
118 |
119 |
120 |
Today Deaths
121 |
122 | {text !== ""
123 | ? data.todayDeaths.toLocaleString("id-ID")
124 | : data.todayDeaths}
125 |
126 |
127 |
128 |
Today Recovered
129 |
130 | {text !== ""
131 | ? data.todayRecovered.toLocaleString("id-ID")
132 | : data.todayRecovered}
133 |
134 |
135 |
136 |
137 |
138 |
Tests
139 |
140 | {text !== "" ? data.tests.toLocaleString("id-ID") : data.tests}
141 |
142 |
143 |
144 |
Tests Per One Milion
145 |
146 | {text !== ""
147 | ? data.testsPerOneMillion.toLocaleString("id-ID")
148 | : data.testsPerOneMillion}
149 |
150 |
151 |
152 |
Cases Per One Milion
153 |
154 | {text !== ""
155 | ? data.casesPerOneMillion.toLocaleString("id-ID")
156 | : data.casesPerOneMillion}
157 |
158 |
159 |
160 |
161 |
162 |
Critical Per One Milion
163 |
164 | {text !== ""
165 | ? data.criticalPerOneMillion.toLocaleString("id-ID")
166 | : data.criticalPerOneMillion}
167 |
168 |
169 |
170 |
Deaths Per One Milion
171 |
172 | {text !== ""
173 | ? data.deathsPerOneMillion.toLocaleString("id-ID")
174 | : data.deathsPerOneMillion}
175 |
176 |
177 |
178 |
179 | );
180 | }
181 |
182 | export default DefaultLayout;
--------------------------------------------------------------------------------
/src/components/layouts/LayoutThreeColumn.jsx:
--------------------------------------------------------------------------------
1 | const LayoutThreeColumn = ({text, data}) => {
2 | return (
3 |
4 | {data.countryInfo ? (
5 |
6 |

11 |
12 | ) : (
13 | ""
14 | )}
15 | {data.country ? (
16 |
17 |
{data.country.toUpperCase()}
18 |
19 | ) : (
20 |
21 |
WORLD
22 |
23 | )}
24 |
25 |
26 |
Population
27 |
28 | {text !== ""
29 | ? data.population.toLocaleString("id-ID")
30 | : data.population}
31 |
32 |
33 |
34 |
Total Cases / Population (%)
35 |
36 | {(
37 | (parseFloat(data.cases) / parseFloat(data.population)) *
38 | parseFloat(100)
39 | ).toFixed(2)}
40 | %
41 |
42 |
43 |
44 |
Cases
45 |
46 | {text !== "" ? data.cases.toLocaleString("id-ID") : data.cases}
47 |
48 |
49 |
50 |
51 |
52 |
Recovered
53 |
54 | {text !== ""
55 | ? data.recovered.toLocaleString("id-ID")
56 | : data.recovered}
57 |
58 |
59 |
60 |
Deaths
61 |
62 | {text !== "" ? data.deaths.toLocaleString("id-ID") : data.deaths}
63 |
64 |
65 |
66 |
Active
67 |
68 | {text !== "" ? data.active.toLocaleString("id-ID") : data.active}
69 |
70 |
71 |
72 |
73 |
74 |
Critical
75 |
76 | {text !== ""
77 | ? data.critical.toLocaleString("id-ID")
78 | : data.critical}
79 |
80 |
81 |
82 |
Recovered (%)
83 |
84 | {(
85 | (parseFloat(data.recovered) / parseFloat(data.cases)) *
86 | parseFloat(100)
87 | ).toFixed(2)}
88 | %
89 |
90 |
91 |
92 |
Deaths (%)
93 |
94 | {(
95 | (parseFloat(data.deaths) / parseFloat(data.cases)) *
96 | parseFloat(100)
97 | ).toFixed(2)}
98 | %
99 |
100 |
101 |
102 |
103 |
104 |
Active (%)
105 |
106 | {(
107 | (parseFloat(data.active) / parseFloat(data.cases)) *
108 | parseFloat(100)
109 | ).toFixed(2)}
110 | %
111 |
112 |
113 |
114 |
Today Cases
115 |
116 | {text !== ""
117 | ? data.todayCases.toLocaleString("id-ID")
118 | : data.todayCases}
119 |
120 |
121 |
122 |
Today Deaths
123 |
124 | {text !== ""
125 | ? data.todayDeaths.toLocaleString("id-ID")
126 | : data.todayDeaths}
127 |
128 |
129 |
130 |
131 |
132 |
Today Recovered
133 |
134 | {text !== ""
135 | ? data.todayRecovered.toLocaleString("id-ID")
136 | : data.todayRecovered}
137 |
138 |
139 |
140 |
Tests
141 |
142 | {text !== "" ? data.tests.toLocaleString("id-ID") : data.tests}
143 |
144 |
145 |
146 |
Tests Per One Milion
147 |
148 | {text !== ""
149 | ? data.testsPerOneMillion.toLocaleString("id-ID")
150 | : data.testsPerOneMillion}
151 |
152 |
153 |
154 |
155 |
156 |
Cases Per One Milion
157 |
158 | {text !== ""
159 | ? data.casesPerOneMillion.toLocaleString("id-ID")
160 | : data.casesPerOneMillion}
161 |
162 |
163 |
164 |
Critical Per One Milion
165 |
166 | {text !== ""
167 | ? data.criticalPerOneMillion.toLocaleString("id-ID")
168 | : data.criticalPerOneMillion}
169 |
170 |
171 |
172 |
Deaths Per One Milion
173 |
174 | {text !== ""
175 | ? data.deathsPerOneMillion.toLocaleString("id-ID")
176 | : data.deathsPerOneMillion}
177 |
178 |
179 |
180 |
181 | );
182 | }
183 |
184 | export default LayoutThreeColumn;
--------------------------------------------------------------------------------
/src/components/layouts/LayoutTwoColumn.jsx:
--------------------------------------------------------------------------------
1 | const LayoutTwoColumn = ({data, text}) => {
2 | return (
3 |
4 | {data.countryInfo ? (
5 |
6 |

11 |
12 | ) : (
13 | ""
14 | )}
15 | {data.country ? (
16 |
17 |
{data.country.toUpperCase()}
18 |
19 | ) : (
20 |
21 |
WORLD
22 |
23 | )}
24 |
25 |
26 |
Population
27 |
28 | {text !== ""
29 | ? data.population.toLocaleString("id-ID")
30 | : data.population}
31 |
32 |
33 |
34 |
Total Cases / Population (%)
35 |
36 | {(
37 | (parseFloat(data.cases) / parseFloat(data.population)) *
38 | parseFloat(100)
39 | ).toFixed(2)}
40 | %
41 |
42 |
43 |
44 |
45 |
46 |
Cases
47 |
48 | {text !== "" ? data.cases.toLocaleString("id-ID") : data.cases}
49 |
50 |
51 |
52 |
Recovered
53 |
54 | {text !== ""
55 | ? data.recovered.toLocaleString("id-ID")
56 | : data.recovered}
57 |
58 |
59 |
60 |
61 |
62 |
Deaths
63 |
64 | {text !== "" ? data.deaths.toLocaleString("id-ID") : data.deaths}
65 |
66 |
67 |
68 |
Active
69 |
70 | {text !== "" ? data.active.toLocaleString("id-ID") : data.active}
71 |
72 |
73 |
74 |
75 |
76 |
Critical
77 |
78 | {text !== ""
79 | ? data.critical.toLocaleString("id-ID")
80 | : data.critical}
81 |
82 |
83 |
84 |
Recovered (%)
85 |
86 | {(
87 | (parseFloat(data.recovered) / parseFloat(data.cases)) *
88 | parseFloat(100)
89 | ).toFixed(2)}
90 | %
91 |
92 |
93 |
94 |
95 |
96 |
Deaths (%)
97 |
98 | {(
99 | (parseFloat(data.deaths) / parseFloat(data.cases)) *
100 | parseFloat(100)
101 | ).toFixed(2)}
102 | %
103 |
104 |
105 |
106 |
Active (%)
107 |
108 | {(
109 | (parseFloat(data.active) / parseFloat(data.cases)) *
110 | parseFloat(100)
111 | ).toFixed(2)}
112 | %
113 |
114 |
115 |
116 |
117 |
118 |
Today Cases
119 |
120 | {text !== ""
121 | ? data.todayCases.toLocaleString("id-ID")
122 | : data.todayCases}
123 |
124 |
125 |
126 |
Today Deaths
127 |
128 | {text !== ""
129 | ? data.todayDeaths.toLocaleString("id-ID")
130 | : data.todayDeaths}
131 |
132 |
133 |
134 |
135 |
136 |
Today Recovered
137 |
138 | {text !== ""
139 | ? data.todayRecovered.toLocaleString("id-ID")
140 | : data.todayRecovered}
141 |
142 |
143 |
144 |
Tests
145 |
146 | {text !== "" ? data.tests.toLocaleString("id-ID") : data.tests}
147 |
148 |
149 |
150 |
151 |
152 |
Tests Per One Milion
153 |
154 | {text !== ""
155 | ? data.testsPerOneMillion.toLocaleString("id-ID")
156 | : data.testsPerOneMillion}
157 |
158 |
159 |
160 |
Cases Per One Milion
161 |
162 | {text !== ""
163 | ? data.casesPerOneMillion.toLocaleString("id-ID")
164 | : data.casesPerOneMillion}
165 |
166 |
167 |
168 |
169 |
170 |
Critical Per One Milion
171 |
172 | {text !== ""
173 | ? data.criticalPerOneMillion.toLocaleString("id-ID")
174 | : data.criticalPerOneMillion}
175 |
176 |
177 |
178 |
Deaths Per One Milion
179 |
180 | {text !== ""
181 | ? data.deathsPerOneMillion.toLocaleString("id-ID")
182 | : data.deathsPerOneMillion}
183 |
184 |
185 |
186 |
187 | );
188 | }
189 |
190 | export default LayoutTwoColumn;
--------------------------------------------------------------------------------
/src/components/layouts/index.js:
--------------------------------------------------------------------------------
1 | export {default as DefaultLayout} from './DefaultLayout';
2 | export {default as LayoutTwoColumn} from './LayoutTwoColumn';
3 | export {default as LayoutThreeColumn} from './LayoutThreeColumn';
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | @tailwind base;
2 | @tailwind components;
3 | @tailwind utilities;
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import ReactDOM from 'react-dom/client';
3 | import './index.css';
4 | import App from './App';
5 |
6 | const root = ReactDOM.createRoot(document.getElementById('root'));
7 | root.render(
8 |
9 |
10 |
11 | );
12 |
--------------------------------------------------------------------------------
/tailwind.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | content: ["./src/**/*.{js,jsx,ts,tsx}"],
3 | theme: {
4 | extend: {},
5 | },
6 | plugins: [],
7 | };
8 |
--------------------------------------------------------------------------------