Skip to content

Commit cc7c439

Browse files
committed
Add search
1 parent 8f3c853 commit cc7c439

File tree

7 files changed

+245
-94
lines changed

7 files changed

+245
-94
lines changed

components/DrawerItem/index.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export default {
4949
background-color: #343332;
5050
box-shadow: 0px 0px 24px rgba(0, 0, 0, 0.5);
5151
transition: .5s ease;
52+
overflow: hidden;
5253
5354
&.is-active {
5455
display: flex;
@@ -72,6 +73,7 @@ export default {
7273
.drawer-item-content {
7374
height: 100%;
7475
color: #f2f2f2;
76+
overflow: auto;
7577
}
7678
}
7779
</style>

components/Search/index.vue

Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<template>
2+
<div
3+
class="search"
4+
:class="{
5+
'open': openSuggestion
6+
}">
7+
<div class="search-container">
8+
<div class="countries-wrapper">
9+
<input
10+
ref="countries"
11+
type="text"
12+
v-model="country"
13+
@keydown.enter="enter"
14+
@keydown.down="down"
15+
@keydown.up="up"
16+
@input="change"
17+
/>
18+
</div>
19+
<div
20+
class="provinces-wrapper"
21+
:class="{
22+
'is-show': provinces && provinces.length
23+
}">
24+
<select ref="provinces">
25+
<option
26+
v-for="(province, index) in provinces"
27+
:key="index"
28+
:label="province"
29+
:value="province" />
30+
</select>
31+
</div>
32+
<button @click="onSearch">Search</button>
33+
</div>
34+
<ul class="dropdown-menu">
35+
<li
36+
v-for="(suggestion, index) in matches"
37+
:key="index"
38+
v-bind:class="{'active': isActive(index)}"
39+
@click="suggestionClick(index)"
40+
>
41+
<span>{{ suggestion }}</span>
42+
</li>
43+
</ul>
44+
</div>
45+
</template>
46+
47+
<script>
48+
export default {
49+
name: 'Search',
50+
props: {
51+
suggestions: {
52+
type: Object,
53+
required: true
54+
},
55+
selection: {
56+
type: String,
57+
required: true
58+
}
59+
},
60+
computed: {
61+
setSelection: {
62+
get() {
63+
return this.selection
64+
},
65+
set(newSelect) {
66+
this.country = newSelect
67+
this.provinces = this.suggestions[newSelect].filter(_ => _)
68+
}
69+
},
70+
matches() {
71+
const countries = Object.keys(this.suggestions)
72+
const lowerCased = this.country.toLowerCase()
73+
return countries.filter(str => {
74+
return str.toLowerCase().indexOf(lowerCased) >= 0
75+
})
76+
},
77+
openSuggestion() {
78+
return (
79+
this.country !== '' && this.matches.length != 0 && this.open === true
80+
)
81+
}
82+
},
83+
data() {
84+
return {
85+
open: false,
86+
current: 0,
87+
country: '',
88+
provinces: ''
89+
}
90+
},
91+
methods: {
92+
enter() {
93+
this.setSelection = this.matches[this.current]
94+
this.open = false
95+
this.$nextTick(_ => {
96+
if (this.$refs.provinces) this.$refs.provinces.focus()
97+
})
98+
},
99+
up() {
100+
if (this.current > 0) this.current--
101+
},
102+
down() {
103+
if (this.current < this.matches.length - 1) this.current++
104+
},
105+
isActive(index) {
106+
return index === this.current
107+
},
108+
change() {
109+
if (!this.open) {
110+
this.open = true
111+
this.current = 0
112+
}
113+
},
114+
suggestionClick(index) {
115+
this.setSelection = this.matches[index]
116+
this.open = false
117+
this.$nextTick(_ => {
118+
if (this.$refs.provinces) this.$refs.provinces.focus()
119+
})
120+
},
121+
onSearch() {
122+
this.$store.dispatch('getCasesByCountry', {
123+
country: this.country,
124+
province: this.$refs.provinces.value
125+
})
126+
}
127+
}
128+
}
129+
</script>
130+
131+
132+
<style lang="scss" scoped>
133+
.search {
134+
position: relative;
135+
136+
&.open {
137+
138+
.dropdown-menu {
139+
display: block;
140+
}
141+
}
142+
143+
.countries-wrapper {
144+
input {
145+
margin: 0;
146+
padding: 0;
147+
border: 0;
148+
border-bottom: 1px solid #ffffff;
149+
color: #ffffff;
150+
background-color: transparent;
151+
outline: none;
152+
}
153+
}
154+
155+
.provinces-wrapper {
156+
display: none;
157+
158+
&.is-show {
159+
display: block;
160+
}
161+
}
162+
163+
.dropdown-menu {
164+
display: none;
165+
width: 100%;
166+
}
167+
}
168+
</style>

pages/index.vue

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,9 @@
4242
<p>FEATURE TO BE ADDED SOON</p>
4343
</DrawerItem>
4444
<DrawerItem title="SEARCH">
45-
<p>FEATURE TO BE ADDED SOON</p>
45+
<Search
46+
:suggestions="countries"
47+
:selection.sync="country" />
4648
</DrawerItem>
4749
</Drawer>
4850
</div>
@@ -59,27 +61,31 @@ import { mapGetters } from 'vuex'
5961
import Map from '~/components/Map'
6062
import Drawer from '~/components/Drawer'
6163
import DrawerItem from '~/components/DrawerItem'
64+
import Search from '~/components/Search'
6265
import AnimatedNumber from 'animated-number-vue'
6366
6467
export default {
6568
components: {
6669
Map,
6770
Drawer,
6871
DrawerItem,
69-
AnimatedNumber
72+
AnimatedNumber,
73+
Search
7074
},
7175
computed: {
7276
...mapGetters([
7377
'data',
74-
'latest'
78+
'latest',
79+
'countries'
7580
])
7681
},
7782
data() {
7883
return {
7984
isOpen: false,
8085
isClosed: true,
8186
duration: 1000,
82-
timer: null
87+
timer: null,
88+
country: ''
8389
}
8490
},
8591
methods: {
@@ -112,10 +118,7 @@ export default {
112118
.covid-map {
113119
transform: translate3d(0, 92vh, 0);
114120
}
115-
116-
.icon {
117-
118-
}
121+
.icon {}
119122
}
120123
}
121124

store/actions.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,21 @@ export default {
55
)
66
.then(res => {
77
if (res.status === 200) {
8-
const { latest } = res.data
8+
const {
9+
confirmed,
10+
latest
11+
} = res.data
912
commit('SET_DATA', res.data)
1013
commit('SET_LATEST', latest)
14+
commit('SET_COUNTRIES', confirmed)
1115
}
1216
})
1317
.catch(err => {
1418
console.log('API error.', err)
1519
})
20+
},
21+
getCasesByCountry({ state, commit }, payload) {
22+
console.log(payload)
23+
// console.log(state.data)
1624
}
1725
}

store/getters.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
export default {
22
data: state => state.data,
33
latest: state => state.latest,
4-
timeline: state => state.timeline
4+
countries: state => state.countries
55
}

0 commit comments

Comments
 (0)