-
Notifications
You must be signed in to change notification settings - Fork 0
/
index copy.html
408 lines (401 loc) · 21.4 KB
/
index copy.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
<html>
<head>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/[email protected]/dist/alpine.min.js" defer></script>
<link href="https://unpkg.com/tailwindcss@^1.0/dist/tailwind.min.css" rel="stylesheet">
<link href="https://fonts.googleapis.com/css2?family=Audiowide&family=Nova+Square&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.8.1/css/all.css" integrity="sha384-50oBUHEmvpQ+1lW4y57PTFmhCaXp0ML5d60M1M7uH2+nqUivzIebhndOJK28anvf" crossorigin="anonymous">
<!--
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
-->
<script src="https://cdn.jsdelivr.net/npm/apexcharts"></script>
</head>
<style>
.page-background {
background-color: #000;
/* background-image: url("data:image/svg+xml,%3Csvg width='180' height='180' viewBox='0 0 180 180' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M82.42 180h-1.415L0 98.995v-2.827L6.167 90 0 83.833V81.004L81.005 0h2.827L90 6.167 96.167 0H98.996L180 81.005v2.827L173.833 90 180 96.167V98.996L98.995 180h-2.827L90 173.833 83.833 180H82.42zm0-1.414L1.413 97.58 8.994 90l-7.58-7.58L82.42 1.413 90 8.994l7.58-7.58 81.006 81.005-7.58 7.58 7.58 7.58-81.005 81.006-7.58-7.58-7.58 7.58zM175.196 0h-25.832c1.033 2.924 2.616 5.59 4.625 7.868C152.145 9.682 151 12.208 151 15c0 5.523 4.477 10 10 10 1.657 0 3 1.343 3 3v4h16V0h-4.803c.51.883.803 1.907.803 3 0 3.314-2.686 6-6 6s-6-2.686-6-6c0-1.093.292-2.117.803-3h10.394-13.685C161.18.938 161 1.948 161 3v4c-4.418 0-8 3.582-8 8s3.582 8 8 8c2.76 0 5 2.24 5 5v2h4v-4h2v4h4v-4h2v4h2V0h-4.803zm-15.783 0c-.27.954-.414 1.96-.414 3v2.2c-1.25.254-2.414.74-3.447 1.412-1.716-1.93-3.098-4.164-4.054-6.612h7.914zM180 17h-3l2.143-10H180v10zm-30.635 163c-.884-2.502-1.365-5.195-1.365-8 0-13.255 10.748-24 23.99-24H180v32h-30.635zm12.147 0c.5-1.416 1.345-2.67 2.434-3.66l-1.345-1.48c-1.498 1.364-2.62 3.136-3.186 5.14H151.5c-.97-2.48-1.5-5.177-1.5-8 0-12.15 9.84-22 22-22h8v30h-18.488zm13.685 0c-1.037-1.793-2.976-3-5.197-3-2.22 0-4.16 1.207-5.197 3h10.394zM0 148h8.01C21.26 148 32 158.742 32 172c0 2.805-.48 5.498-1.366 8H0v-32zm0 2h8c12.15 0 22 9.847 22 22 0 2.822-.53 5.52-1.5 8h-7.914c-.567-2.004-1.688-3.776-3.187-5.14l-1.346 1.48c1.09.99 1.933 2.244 2.434 3.66H0v-30zm15.197 30c-1.037-1.793-2.976-3-5.197-3-2.22 0-4.16 1.207-5.197 3h10.394zM0 32h16v-4c0-1.657 1.343-3 3-3 5.523 0 10-4.477 10-10 0-2.794-1.145-5.32-2.992-7.134C28.018 5.586 29.6 2.924 30.634 0H0v32zm0-2h2v-4h2v4h4v-4h2v4h4v-2c0-2.76 2.24-5 5-5 4.418 0 8-3.582 8-8s-3.582-8-8-8V3c0-1.052-.18-2.062-.512-3H0v30zM28.5 0c-.954 2.448-2.335 4.683-4.05 6.613-1.035-.672-2.2-1.16-3.45-1.413V3c0-1.04-.144-2.046-.414-3H28.5zM0 17h3L.857 7H0v10zM15.197 0c.51.883.803 1.907.803 3 0 3.314-2.686 6-6 6S4 6.314 4 3c0-1.093.292-2.117.803-3h10.394zM109 115c-1.657 0-3 1.343-3 3v4H74v-4c0-1.657-1.343-3-3-3-5.523 0-10-4.477-10-10 0-2.793 1.145-5.318 2.99-7.132C60.262 93.638 58 88.084 58 82c0-13.255 10.748-24 23.99-24h16.02C111.26 58 122 68.742 122 82c0 6.082-2.263 11.636-5.992 15.866C117.855 99.68 119 102.206 119 105c0 5.523-4.477 10-10 10zm0-2c-2.76 0-5 2.24-5 5v2h-4v-4h-2v4h-4v-4h-2v4h-4v-4h-2v4h-4v-4h-2v4h-4v-2c0-2.76-2.24-5-5-5-4.418 0-8-3.582-8-8s3.582-8 8-8v-4c0-2.64 1.136-5.013 2.946-6.66L72.6 84.86C70.39 86.874 69 89.775 69 93v2.2c-1.25.254-2.414.74-3.447 1.412C62.098 92.727 60 87.61 60 82c0-12.15 9.84-22 22-22h16c12.15 0 22 9.847 22 22 0 5.61-2.097 10.728-5.55 14.613-1.035-.672-2.2-1.16-3.45-1.413V93c0-3.226-1.39-6.127-3.6-8.14l-1.346 1.48C107.864 87.987 109 90.36 109 93v4c4.418 0 8 3.582 8 8s-3.582 8-8 8zM90.857 97L93 107h-6l2.143-10h1.714zM80 99c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6zm20 0c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6z' fill='%23249c0f' fill-opacity='0.4' fill-rule='evenodd'/%3E%3C/svg%3E"); */
/*
background-image: url("data:image/svg+xml,%3Csvg width='52' height='26' viewBox='0 0 52 26' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cg fill='%23737673' fill-opacity='0.4'%3E%3Cpath d='M10 10c0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6h2c0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4 3.314 0 6 2.686 6 6 0 2.21 1.79 4 4 4v2c-3.314 0-6-2.686-6-6 0-2.21-1.79-4-4-4-3.314 0-6-2.686-6-6zm25.464-1.95l8.486 8.486-1.414 1.414-8.486-8.486 1.414-1.414z' /%3E%3C/g%3E%3C/g%3E%3C/svg%3E");
*/
}
</style>
<body>
<div x-data="covidDash()" x-init="loadCountryDetails()" class="page-background">
<div class="flex justify-around">
<div class="flex flex-col w-3/5">
<div class="flex items-center">
<div class="w-40 p-2">
<img src="./images/covid.png" />
</div>
<template x-if="covidWorld">
<div class="rounded overflow-hidden shadow-2xl h-auto p-4 m-2 border border-gray-600 bg-gray-800 w-full relative" style="font-family: 'Nova Square';">
<div class="text-xl text-gray-700">covid-19 counter</div>
<i class="fas fa-globe fa-2x w-8 h-8 inline absolute top-0 right-0 mt-1 mr-2 p-1 text-gray-700"></i>
<div class="flex items-center justify-between mt-4">
<div class="flex items-center text-2xl mr-4">
<i class="fas fa-exclamation-triangle text-red-700 mr-1"></i>
<div class="text-red-700 font-black" x-text="formatNumber(covidWorld.casesActive)"></div>
</div>
<div class="flex items-center text-xl mr-4">
<i class="fas fa-heartbeat text-green-500 mr-1"></i>
<div class="text-green-500 font-black" x-text="formatNumber(covidWorld.casesRecovered)"></div>
</div>
<div class="flex items-center text-sm mr-4">
<i class="fas fa-skull-crossbones text-black mr-1"></i>
<div class="text-black font-black" x-text="formatNumber(covidWorld.casesDeceased)"></div>
</div>
<div class="flex items-center text-md mr-4">
<i class="fas fa-thermometer-half text-gray-600 mr-1"></i>
<div class="text-gray-600 text-right font-black" x-text="formatNumber(covidWorld.casesTotal)"></div>
</div>
</div>
</div>
</template>
</div>
<div class="flex-grow-0 flex-shrink-0 rounded overflow-hidden shadow-2xl h-auto p-4 m-2 border border-gray-600 bg-gray-800 relative" style="font-family: 'Nova Square';">
<template x-if="selectedCountry">
<div class="text-4xl text-white" x-text="selectedCountry.name"></div>
<img class="w-20 inline absolute top-0 right-0 mt-1 mr-1 bg-gray-900 rounded-full p-2" :src="selectedCountry.flag" onload="loadChartEl()"/>
<div class="flex justify-around mt-8">
<div class="flex flex-col items-center text-4xl mr-4 bg-red-900 p-4 rounded-lg border border-white w-2/3" style="font-family: 'Audiowide';">
<div class="flex flex-row items-center">
<i class="fas fa-exclamation-triangle text-red-600 mr-2"></i>
<div class="text-white font-black" x-text="formatNumber(selectedCountry.casesActive)"></div>
<div class="text-red-700 text-sm ml-2" x-text="formatNumber(selectedCountry.newCases)"></div>
<div class="text-red-700 text-sm ml-1" style="font-family: Nova Square;">new</div>
</div>
<div class="text-red-600 text-xl ml-2" style="font-family: 'Nova Square';">active cases</div>
<div id="chart"></div>
</div>
<div class="flex flex-col w-1/3">
<div class="flex flex-col items-center text-3xl bg-gray-700 p-4 rounded-lg border border-white mb-2" style="font-family: 'Audiowide';">
<div class="flex flex-row items-center">
<i class="fas fa-thermometer-half text-gray-900 mr-2"></i>
<div class="text-gray-300 font-black" x-text="formatNumber(selectedCountry.casesTotal)"></div>
</div>
<div class="text-gray-900 text-lg ml-2" style="font-family: 'Nova Square';">reported cases</div>
<div class="flex justify-center mt-2">
<div class="text-gray-400 text-sm" style="font-family: 'Audiowide';" x-text="formatNumber(selectedCountry.casesPerMillion)"></div>
<div class="text-gray-800 text-xs ml-1" style="font-family: 'Nova Square';">cases per million</div>
</div>
<div class="text-gray-400 text-xs" style="font-family: 'Audiowide';" x-text="percentageNumber(selectedCountry.casesPerMillion,selectedCountry.casesTotal,1)"></div>
</div>
<div class="flex flex-col items-center text-2xl bg-green-900 p-4 rounded-lg border border-white mb-2" style="font-family: 'Audiowide';">
<div class="flex flex-row items-center">
<i class="fas fa-heartbeat text-green-500 mr-2"></i>
<div class="text-white font-black" x-text="formatNumber(selectedCountry.casesRecovered)"></div>
</div>
<div class="text-gray-400 text-xs ml-4" x-text="percentageNumber(selectedCountry.casesRecovered,selectedCountry.casesTotal,1)"></div>
<div class="text-green-500 text-base ml-2" style="font-family: 'Nova Square';">recovered cases</div>
</div>
<div class="flex flex-col items-center text-2xl bg-black p-4 rounded-lg border border-white mb-2" style="font-family: 'Audiowide';">
<div class="flex flex-row items-center">
<i class="fas fa-skull-crossbones text-gray-700 mr-2"></i>
<div class="text-gray-500 font-black" x-text="formatNumber(selectedCountry.casesDeceased)"></div>
<div class="text-red-700 text-xs ml-2" x-text="formatNumber(selectedCountry.newDeceased)"></div>
<div class="text-red-700 text-xs ml-1" style="font-family: Nova Square;">new</div>
</div>
<div class="text-gray-400 text-xs ml-4" x-text="percentageNumber(selectedCountry.casesDeceased,selectedCountry.casesTotal,1)"></div>
<div class="text-gray-700 text-base ml-2" style="font-family: 'Nova Square';">deceased</div>
</div>
</div>
</div>
</template>
</div>
</div>
<div class="flex-grow-0 flex-shrink-0 h-screen w-2/5 overflow-scroll">
<div x-show.transition.in.duration.500ms.opacity.out.duration.500ms.opacity="!loadingCovidCountries">
<template x-for="(country,index) in covidCountries" :key="index">
<div class="rounded overflow-hidden shadow-xl h-20 p-2 m-2 border border-gray-700 bg-gray-800 relative cursor-pointer" style="font-family: 'Audiowide';" @click="selectCountry(index)">
<img class="w-8 inline absolute top-0 right-0 mt-1 mr-1 bg-gray-900 rounded-full p-1" :src="country.flag" />
<div class="text-md text-gray-400" style="font-family: Nova Square;" x-text="country.name"></div>
<div class="flex items-center justify-between">
<div class="flex items-center text-2xl mr-4">
<i class="fas fa-exclamation-triangle text-red-700 mr-1"></i>
<div class="text-red-700 font-black" x-text="formatNumber(country.casesActive)"></div>
</div>
<div class="flex items-center text-xl mr-4">
<i class="fas fa-heartbeat text-green-500 mr-1"></i>
<div class="text-green-500 font-black" x-text="formatNumber(country.casesRecovered)"></div>
</div>
<div class="flex items-center text-sm mr-4">
<i class="fas fa-skull-crossbones text-black mr-1"></i>
<div class="text-black font-black" x-text="formatNumber(country.casesDeceased)"></div>
</div>
<div class="flex items-center text-md mr-4">
<i class="fas fa-thermometer-half text-gray-600 mr-1"></i>
<div class="text-gray-600 text-right font-black" x-text="formatNumber(country.casesTotal)"></div>
</div>
</div>
</div>
</template>
</div>
</div>
</div>
</div>
</body>
<script type="text/javascript">
function loadChartEl() {
new ApexCharts(document.querySelector("#chart"), {
chart: {
id: 'active99',
type: 'line',
toolbar: {
show: false
},
foreColor: '#fff'
},
series: [{
data: [32, 44, 31, 41, 22]
}],
xaxis: {
type: 'datetime',
labels: {
show: false
}
},
yaxis: {
labels: {
show: false
}
},
stroke: {
width: 1,
curve: 'smooth'
}
}).render()
}
function covidDash() {
return {
selectedCountry: null,
loadingCountries: false,
countries: [],
covidCountries: [],
loadingCovidCountries: false,
covidWorld: null,
async userCountry() {
await fetch(`http://ip-api.com/json`)
.then(res => res.json())
.then(data => {
const userCountry = this.covidCountries.findIndex(country =>
country.name === data.country
)
if (userCountry >= 0) { this.selectCountry(userCountry) }
})
},
async loadCountryDetails() {
const countryMapping = [
{
countryName: 'Iran (Islamic Republic of)',
covidName: 'Iran'
},
{
countryName: 'Korea (Republic of)',
covidName: 'S. Korea'
},
{
countryName: 'Russian Federation',
covidName: 'Russia'
},
{
countryName: 'Czech Republic',
covidName: 'Czechia'
},
{
countryName: 'Macedonia (the former Yugoslav Republic of)',
covidName: 'North Macedonia'
},
{
countryName: 'Viet Nam',
covidName: 'Vietnam'
},
{
countryName: 'Guernsey',
covidName: 'Channel Islands'
},
{
countryName: 'Palestine, State of',
covidName: 'Palestine'
},
{
countryName: 'Faroe Islands',
covidName: 'Faeroe Islands'
},
{
countryName: 'Brunei Darussalam',
covidName: 'Brunei'
},
{
countryName: 'Saint Martin (French part)',
covidName: 'Saint Martin'
},
{
countryName: 'Syrian Arab Republic',
covidName: 'Syria'
},
{
countryName: 'Swaziland',
covidName: 'Eswatini'
},
{
countryName: 'Holy See',
covidName: 'Vatican City'
},
{
countryName: 'Saint Vincent and the Grenadines',
covidName: 'St. Vincent Grenadines'
},
{
countryName: 'Saint Barthélemy',
covidName: 'St. Barth'
},
{
countryName: 'Turks and Caicos Islands',
covidName: 'Turks and Caicos'
},
{
countryName: 'Curaçao',
covidName: 'Caribbean Netherlands'
},
{
countryName: 'Central African Republic',
covidName: 'CAR'
},
]
// setInterval(async () => {
await this.fetchCountries()
await this.countries.forEach(country => {
let match = countryMapping.find(countryDetails =>
countryDetails.countryName === country.name
)
if (match) { country.alt.push(match.covidName) }
})
await this.fetchCovidWorld()
await this.fetchCovidCountries()
await this.covidCountries.forEach(country => {
let match = this.countries.find(countryDetails =>
countryDetails.name === country.name || countryDetails.nativeName === country.name || countryDetails.alt.indexOf(country.name) >= 0
)
if (match) { country.flag = match.flag } else { country.flag = './images/flags/none.png' }
})
// }, 60000)
await this.userCountry()
},
async fetchCountries() {
this.loadingCountries = true
await fetch(`https://restcountries.eu/rest/v2/all?fields=name;nativeName;alpha2Code;altSpellings`)
.then(res => res.json())
.then(data => {
const countries = data.map(country => {
return ({
name: country.name,
nativeName: country.nativeName,
code: country.alpha2Code,
alt: country.altSpellings,
flag: `./images/flags2/${country.alpha2Code}.svg`
})
})
this.countries = countries
this.loadingCountries = false
})
},
async fetchCovidWorld() {
await fetch(`https://coronavirus-monitor.p.rapidapi.com/coronavirus/worldstat.php`, {
headers: {
'Content-Type': 'application/json',
'x-rapidapi-host': 'coronavirus-monitor.p.rapidapi.com',
'x-rapidapi-key': '308ad4105dmsh3512d157c97c11bp1413ffjsn966455f9b1d4'
}
})
.then(res => res.json())
.then(data => {
this.covidWorld = {
casesActive: Number(data.total_cases.split(',').join('')) - Number(data.total_recovered.split(',').join('')) - Number(data.total_deaths.split(',').join('')),
casesRecovered: Number(data.total_recovered.split(',').join('')),
casesDeceased: Number(data.total_deaths.split(',').join('')),
casesTotal: Number(data.total_cases.split(',').join('')),
newCases: Number(data.new_cases.split(',').join('')),
newDeceased: Number(data.new_deaths.split(',').join(''))
}
})
},
async fetchCovidCountries() {
this.loadingCovidCountries = true
await fetch(`https://coronavirus-monitor.p.rapidapi.com/coronavirus/cases_by_country.php`, {
headers: {
'Content-Type': 'application/json',
'x-rapidapi-host': 'coronavirus-monitor.p.rapidapi.com',
'x-rapidapi-key': '308ad4105dmsh3512d157c97c11bp1413ffjsn966455f9b1d4'
}
})
.then(res => res.json())
.then(data => {
const countries = data.countries_stat.map (country => {
return ({
name: country.country_name,
casesActive: Number(country.active_cases.split(',').join('')),
casesRecovered: Number(country.total_recovered.split(',').join('')),
casesDeceased: Number(country.deaths.split(',').join('')),
casesTotal: Number(country.cases.split(',').join('')),
casesPerMillion: Number(country.total_cases_per_1m_population.split(',').join('')),
newCases: Number(country.new_cases.split(',').join('')),
newDeceased: Number(country.new_deaths.split(',').join(''))
})
})
countries.sort((a,b) => {
return b.casesActive-a.casesActive
})
this.covidCountries = countries
this.loadingCovidCountries = false
})
},
async selectCountry(index) {
this.selectedCountry = this.covidCountries[index]
const countryName = this.covidCountries[index].name
let history = []
let chart = []
await fetch(`https://coronavirus-monitor.p.rapidapi.com/coronavirus/cases_by_particular_country.php?country=${countryName}`, {
headers: {
'Content-Type': 'application/json',
'x-rapidapi-host': 'coronavirus-monitor.p.rapidapi.com',
'x-rapidapi-key': '308ad4105dmsh3512d157c97c11bp1413ffjsn966455f9b1d4'
}
})
.then(res => res.json())
.then(data => {
for (let stat of data.stat_by_country) {
history.push({
date: stat.record_date,
casesTotal: stat.total_cases,
casesActive: stat.active_cases,
casesRecovered: stat.total_recovered,
casesDeceased: stat.total_deaths,
newCases: stat.new_cases,
newDeceased: stat.new_deaths
})
chart.push({
x: stat.record_date,
y: Number(stat.total_cases.split(',').join(''))
})
}
})
this.selectedCountry.history = history
this.selectedCountry.chart = chart
await this.renderHistoryChart()
},
formatNumber(value) {
return value ? value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ' ') : '0'
},
percentageNumber(value, divider, decimals) {
return '(' + parseFloat(value/divider*100).toFixed(decimals) + '%)'
},
renderHistoryChart() {
const data = this.selectedCountry.chart
ApexCharts.exec('active99','updateSeries', [{
data
}], true)
}
}
}
</script>
</html>