├── .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 | ![kopid](kopid.png) -------------------------------------------------------------------------------- /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 |
18 |

19 | Created By{" "} 20 | 21 | Ade Yusuf 22 | 23 |

24 |

25 | Github:{" "} 26 | 27 | @adeyusuf211/project-kopid 28 | 29 |

30 |

31 | Resource:{" "} 32 | 33 | Diseash.sh 34 | 35 |

36 |
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 | {data.country} 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 | {data.country} 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 | {data.country} 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 | --------------------------------------------------------------------------------