Skip to content

Commit 2fc19de

Browse files
authored
Merge pull request #105 from jordanopensource/feature/implement-search-functionality
Feature/Implement search functionality
2 parents ccd5d49 + 2caea0d commit 2fc19de

File tree

8 files changed

+233
-32
lines changed

8 files changed

+233
-32
lines changed

components/Contributors.vue

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import { mapState } from 'vuex'
3232
import UserCard from './UserCard.vue'
3333
import PaginationBar from './PaginationBar.vue'
3434
export default {
35-
name: 'Contributors',
35+
name: 'ContributorsList',
3636
components: {
3737
UserCard,
3838
PaginationBar,
@@ -46,14 +46,26 @@ export default {
4646
currentPage: 'currentPage',
4747
period: 'period',
4848
show: 'show',
49+
userSearchTerm: 'userSearchTerm',
4950
}),
5051
},
5152
methods: {
5253
async fetchCurrentPage(page) {
53-
const response = await this.$axios.get(
54-
`v1/users?page=${this.currentPage}&sort_by=${this.sortBy}&period=${this.period}&contributors=${this.show}`
55-
)
56-
this.$store.commit('setUsers', response.data.users)
54+
if (this.userSearchTerm) {
55+
const response = await this.$axios.get(
56+
`v1/users?page=${this.currentPage}&sort_by=${this.sortBy}&period=${this.period}&contributors=${this.show}&search=${this.userSearchTerm}`,
57+
)
58+
59+
this.$store.commit('setUsers', response.data.users)
60+
this.$store.commit('setPageCount', response.data.totalPages)
61+
} else {
62+
const response = await this.$axios.get(
63+
`v1/users?page=${this.currentPage}&sort_by=${this.sortBy}&period=${this.period}&contributors=${this.show}`,
64+
)
65+
66+
this.$store.commit('setUsers', response.data.users)
67+
this.$store.commit('setPageCount', response.data.totalPages)
68+
}
5769
},
5870
},
5971
}

components/InputsSection.vue

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
<template>
22
<div :class="isOpen ? '' : 'hidden overflow-hidden lg:block'">
3+
<div class="mx-8 pt-6">
4+
<SearchInput placeholder="Search Users..." @on-search="onSearch" />
5+
</div>
36
<div class="sort-section">
47
<h6 class="text-xs font-bold pb-2">Period:</h6>
58
<div class="flex lg:flex-col">
@@ -92,24 +95,65 @@ export default {
9295
getPeriod: 'getPeriod',
9396
getShow: 'getShow',
9497
getSortBy: 'getSortBy',
98+
getUserSearchTerm: 'getUserSearchTerm',
9599
}),
96100
},
97101
methods: {
98102
async onSortByChanged(sortBy) {
103+
this.$store.commit('setCurrentPage', 1)
99104
this.$store.commit('setSortBy', sortBy)
100-
const response = await this.$axios.get(
101-
`v1/users?sort_by=${sortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${this.getShow}`
102-
)
103-
this.$store.commit('setUsers', response.data.users)
105+
106+
if (this.getUserSearchTerm) {
107+
const response = await this.$axios.get(
108+
`v1/users?sort_by=${sortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${this.getShow}&search=${this.getUserSearchTerm}`,
109+
)
110+
this.$store.commit('setUsers', response.data.users)
111+
this.$store.commit('setPageCount', response.data.totalPages)
112+
} else {
113+
const response = await this.$axios.get(
114+
`v1/users?sort_by=${sortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${this.getShow}`,
115+
)
116+
117+
this.$store.commit('setUsers', response.data.users)
118+
this.$store.commit('setPageCount', response.data.totalPages)
119+
}
104120
},
105121
async onShowChanged(show) {
106122
this.$store.commit('setCurrentPage', 1)
107-
const response = await this.$axios.get(
108-
`v1/users?sort_by=${this.getSortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${show}`
109-
)
110123
this.$store.commit('setShow', show)
111-
this.$store.commit('setUsers', response.data.users)
112-
this.$store.commit('setPageCount', response.data.totalPages)
124+
if (this.getUserSearchTerm) {
125+
const response = await this.$axios.get(
126+
`v1/users?sort_by=${this.getSortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${show}&search=${this.getUserSearchTerm}`,
127+
)
128+
129+
this.$store.commit('setUsers', response.data.users)
130+
this.$store.commit('setPageCount', response.data.totalPages)
131+
} else {
132+
const response = await this.$axios.get(
133+
`v1/users?sort_by=${this.getSortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${show}`,
134+
)
135+
136+
this.$store.commit('setUsers', response.data.users)
137+
this.$store.commit('setPageCount', response.data.totalPages)
138+
}
139+
},
140+
async onSearch(searchTerm) {
141+
this.$store.commit('setCurrentPage', 1)
142+
if (searchTerm) {
143+
const response = await this.$axios.get(
144+
`v1/users?sort_by=${this.getSortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${this.getShow}&search=${searchTerm}`,
145+
)
146+
this.$store.commit('setUserSearchTerm', searchTerm)
147+
this.$store.commit('setUsers', response.data.users)
148+
this.$store.commit('setPageCount', response.data.totalPages)
149+
} else {
150+
const response = await this.$axios.get(
151+
`v1/users?sort_by=${this.getSortBy}&page=${this.getCurrentPage}&period=${this.getPeriod}&contributors=${this.getShow}`,
152+
)
153+
this.$store.commit('setUserSearchTerm', '')
154+
this.$store.commit('setUsers', response.data.users)
155+
this.$store.commit('setPageCount', response.data.totalPages)
156+
}
113157
},
114158
},
115159
}

components/Organizations.vue

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@
2323
/>
2424
</div>
2525
</div>
26-
<PaginationBar @fetch-current-page="fetchCurrentPage" />
26+
<div v-if="organizations?.length <= 0" class="flex justify-center py-14">
27+
<p class="">Sorry, no organizations were found</p>
28+
</div>
29+
<PaginationBar v-else @fetch-current-page="fetchCurrentPage" />
2730
</div>
2831
</template>
2932

@@ -32,7 +35,7 @@ import { mapState } from 'vuex'
3235
import OrganizationCard from './OrganizationCard.vue'
3336
import PaginationBar from './PaginationBar.vue'
3437
export default {
35-
name: 'Organizations',
38+
name: 'OrganizationsList',
3639
components: {
3740
OrganizationCard,
3841
PaginationBar,
@@ -44,14 +47,24 @@ export default {
4447
...mapState({
4548
sortBy: 'orgs_sortBy',
4649
currentPage: 'currentPage',
50+
orgSearchTerm: 'orgSearchTerm',
4751
}),
4852
},
4953
methods: {
5054
async fetchCurrentPage(page) {
51-
const response = await this.$axios.get(
52-
`/v1/orgs?page=${this.currentPage}&sort_by=${this.sortBy}`
53-
)
54-
this.$store.commit('setOrgs', response.data.orgs)
55+
if (this.orgSearchTerm) {
56+
const response = await this.$axios.get(
57+
`/v1/orgs?page=${this.currentPage}&sort_by=${this.sortBy}&search=${this.orgSearchTerm}`,
58+
)
59+
this.$store.commit('setOrgs', response.data.orgs)
60+
this.$store.commit('setPageCount', response.data.totalPages)
61+
} else {
62+
const response = await this.$axios.get(
63+
`/v1/orgs?page=${this.currentPage}&sort_by=${this.sortBy}`,
64+
)
65+
this.$store.commit('setOrgs', response.data.orgs)
66+
this.$store.commit('setPageCount', response.data.totalPages)
67+
}
5568
},
5669
},
5770
}

components/OrganizationsInput.vue

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
<template>
22
<div :class="isOpen ? '' : 'hidden overflow-hidden lg:block'">
33
<div class="sort-section has-border">
4+
<div class="mb-5">
5+
<SearchInput
6+
placeholder="Search Organizations..."
7+
@on-search="onSearch"
8+
/>
9+
</div>
410
<h6 class="text-xs font-bold pb-2">Sort by:</h6>
511
<div class="flex lg:flex-col">
612
<RadioButton
@@ -45,15 +51,48 @@ export default {
4551
computed: {
4652
...mapGetters({
4753
getCurrentPage: 'getCurrentPage',
54+
getOrgsSortBy: 'getOrgsSortBy',
55+
getOrgSearchTerm: 'getOrgSearchTerm',
4856
}),
4957
},
5058
methods: {
5159
async onSortByChanged(sortBy) {
5260
this.$store.commit('setOrgsSortBy', sortBy)
53-
const response = await this.$axios.get(
54-
`v1/orgs?sort_by=${sortBy}&page=${this.getCurrentPage}`
55-
)
56-
this.$store.commit('setOrgs', response.data.orgs)
61+
62+
if (this.getOrgSearchTerm) {
63+
const response = await this.$axios.get(
64+
`v1/orgs?sort_by=${sortBy}&page=${this.getCurrentPage}&search=${this.getOrgSearchTerm}`,
65+
)
66+
67+
this.$store.commit('setOrgs', response.data.orgs)
68+
this.$store.commit('setPageCount', response.data.totalPages)
69+
} else {
70+
const response = await this.$axios.get(
71+
`v1/orgs?sort_by=${sortBy}&page=${this.getCurrentPage}`,
72+
)
73+
74+
this.$store.commit('setOrgs', response.data.orgs)
75+
this.$store.commit('setPageCount', response.data.totalPages)
76+
}
77+
},
78+
79+
async onSearch(searchTerm) {
80+
this.$store.commit('setCurrentPage', 1)
81+
if (searchTerm) {
82+
this.$store.commit('setOrgSearchTerm', searchTerm)
83+
const response = await this.$axios.get(
84+
`v1/orgs?sort_by=${this.getOrgsSortBy}&page=${this.getCurrentPage}&search=${searchTerm}`,
85+
)
86+
this.$store.commit('setOrgs', response.data.orgs)
87+
this.$store.commit('setPageCount', response.data.totalPages)
88+
} else {
89+
this.$store.commit('setOrgSearchTerm', '')
90+
const response = await this.$axios.get(
91+
`v1/orgs?sort_by=${this.getOrgsSortBy}&page=${this.getCurrentPage}`,
92+
)
93+
this.$store.commit('setOrgs', response.data.orgs)
94+
this.$store.commit('setPageCount', response.data.totalPages)
95+
}
5796
},
5897
},
5998
}

components/PeriodDropdown.vue

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ export default {
3535
{
3636
day: 'numeric',
3737
month: 'long',
38-
}
38+
},
3939
),
4040
firstDayOfTheLastMonth: 0,
4141
lastDayOfTheLastMonth: new Date(
4242
new Date().getFullYear(),
4343
new Date().getMonth(),
44-
0
44+
0,
4545
).toLocaleString('en-GB', {
4646
day: 'numeric',
4747
month: 'long',
@@ -50,7 +50,7 @@ export default {
5050
firstDayOfLastYear: new Date(
5151
new Date().getFullYear() - 1,
5252
0,
53-
1
53+
1,
5454
).toLocaleString('en-GB', {
5555
day: 'numeric',
5656
month: 'long',
@@ -59,7 +59,7 @@ export default {
5959
lastDayOfLastYear: new Date(
6060
new Date().getFullYear() - 1,
6161
11,
62-
31
62+
31,
6363
).toLocaleString('en-GB', {
6464
day: 'numeric',
6565
month: 'long',
@@ -80,6 +80,9 @@ export default {
8080
getShow() {
8181
return this.$store.getters.getShow
8282
},
83+
getUserSearchTerm() {
84+
return this.$store.getters.getUserSearchTerm
85+
},
8386
},
8487
mounted() {
8588
const today = new Date()
@@ -100,10 +103,23 @@ export default {
100103
methods: {
101104
async onChange(e) {
102105
this.$store.commit('setPeriod', e.target.value)
103-
const response = await this.$axios.get(
104-
`/v1/users?page=${this.currentPage}&sort_by=${this.sortBy}&period=${this.period}&contributors=${this.getShow}`
105-
)
106-
this.$store.commit('setUsers', response.data.users)
106+
this.$store.commit('setCurrentPage', 1)
107+
108+
if (this.getUserSearchTerm) {
109+
const response = await this.$axios.get(
110+
`/v1/users?page=${this.currentPage}&sort_by=${this.sortBy}&period=${this.period}&contributors=${this.getShow}&search=${this.getUserSearchTerm}`,
111+
)
112+
113+
this.$store.commit('setUsers', response.data.users)
114+
this.$store.commit('setPageCount', response.data.totalPages)
115+
} else {
116+
const response = await this.$axios.get(
117+
`/v1/users?page=${this.currentPage}&sort_by=${this.sortBy}&period=${this.period}&contributors=${this.getShow}`,
118+
)
119+
120+
this.$store.commit('setUsers', response.data.users)
121+
this.$store.commit('setPageCount', response.data.totalPages)
122+
}
107123
},
108124
},
109125
}

components/SearchInput.vue

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<template>
2+
<div class="max-w-md mx-auto">
3+
<div
4+
class="relative flex items-center w-full h-12 rounded-lg focus-within:shadow-lg bg-white overflow-hidden"
5+
>
6+
<div class="grid place-items-center h-full w-12 text-gray-300">
7+
<svg
8+
xmlns="http://www.w3.org/2000/svg"
9+
class="h-6 w-6"
10+
fill="none"
11+
viewBox="0 0 24 24"
12+
stroke="currentColor"
13+
>
14+
<path
15+
stroke-linecap="round"
16+
stroke-linejoin="round"
17+
stroke-width="2"
18+
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
19+
/>
20+
</svg>
21+
</div>
22+
23+
<input
24+
id="search"
25+
class="peer h-full w-full outline-none text-sm text-gray-700 pr-2"
26+
type="text"
27+
:placeholder="placeholder"
28+
@input="onChange"
29+
/>
30+
</div>
31+
</div>
32+
</template>
33+
34+
<script>
35+
import { debounce } from '~/utils/debounce'
36+
export default {
37+
name: 'SearchInput',
38+
props: {
39+
placeholder: { type: String, default: 'Search something..' },
40+
},
41+
created() {
42+
this.onChange = debounce((event) => {
43+
const searchTerm = event.target.value
44+
this.$emit('on-search', searchTerm)
45+
}, 400)
46+
},
47+
}
48+
</script>
49+
50+
<style lang="postcss" scoped>
51+
* {
52+
font-family: 'IBM Sans';
53+
color: #1a1f21;
54+
}
55+
</style>

store/index.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ export const state = () => ({
1111
period: 'last_30_days',
1212
chartPeriod: 'last_year',
1313
show: 'all',
14+
orgSearchTerm: '',
15+
userSearchTerm: '',
1416
})
1517

1618
export const getters = {
@@ -21,6 +23,8 @@ export const getters = {
2123
getPeriod: (state) => state.period,
2224
getChartPeriod: (state) => state.chartPeriod,
2325
getShow: (state) => state.show,
26+
getOrgSearchTerm: (state) => state.orgSearchTerm,
27+
getUserSearchTerm: (state) => state.userSearchTerm,
2428
}
2529

2630
export const mutations = {
@@ -60,4 +64,10 @@ export const mutations = {
6064
setShow(state, show) {
6165
state.show = show
6266
},
67+
setOrgSearchTerm(state, searchTerm) {
68+
state.orgSearchTerm = searchTerm
69+
},
70+
setUserSearchTerm(state, searchTerm) {
71+
state.userSearchTerm = searchTerm
72+
},
6373
}

0 commit comments

Comments
 (0)