Skip to content

Commit bfd19b8

Browse files
authored
Merge pull request #17 from SundeepChand/feat/search
Implement Search
2 parents ad1e4f4 + e840ded commit bfd19b8

File tree

5 files changed

+354
-28
lines changed

5 files changed

+354
-28
lines changed

src/assets/scss/components/index.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,4 @@
1818
@import 'editableLabel';
1919
@import 'footer';
2020
@import 'alerts';
21+
@import 'search';
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
.search-input {
2+
border: 0;
3+
border-bottom: 2px solid $dark-color;
4+
border-radius: 0;
5+
justify-content: space-between;
6+
outline: none;
7+
padding: 0px 10px;
8+
padding-left: 0px;
9+
position: relative;
10+
width: 290px;
11+
12+
.dropdown-container {
13+
.btn {
14+
height: 30px;
15+
}
16+
17+
.eos-icons {
18+
padding: 0px;
19+
}
20+
}
21+
22+
.filter-title {
23+
display: none;
24+
}
25+
26+
input {
27+
border: 0px;
28+
outline: none;
29+
padding: 0px;
30+
width: 147px;
31+
}
32+
}
33+
34+
.user-suggest-dropdown {
35+
background-color: $eos-white;
36+
border-radius: 10px 0px 10px 10px;
37+
height: auto;
38+
max-height: 160px;
39+
overflow-y: scroll;
40+
position: absolute;
41+
top: 110%;
42+
width: 197px;
43+
z-index: 4;
44+
45+
.avatar {
46+
height: 2em;
47+
width: 2em;
48+
}
49+
50+
.dropdown-list {
51+
width: 100%;
52+
}
53+
54+
.user-row {
55+
border-bottom: 1px solid $border-gray;
56+
padding: 8px;
57+
width: 92%;
58+
59+
&:hover {
60+
background-color: $gray-bg;
61+
cursor: pointer;
62+
}
63+
}
64+
}
65+
66+
.close-btn-div {
67+
width: 15px;
68+
}
69+
70+
.close-btn {
71+
cursor: pointer;
72+
}

src/assets/scss/pages/home.scss

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,22 @@ $subheader-font-size: 18px;
1212
}
1313
}
1414

15-
.options-bar {
15+
.search-bar {
1616
align-items: center;
1717
background-color: $eos-white;
1818
border-radius: 10px;
19+
justify-content: space-between;
1920
margin: 16px 0px 16px 0px;
2021
padding: 8px 20px;
2122
}
2223

24+
.options-bar {
25+
align-items: center;
26+
background-color: $eos-white;
27+
border-radius: 10px;
28+
padding: 8px 20px;
29+
}
30+
2331
.link-default {
2432
padding-left: 0.5em;
2533
}
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import React, { useEffect, useRef, useState } from 'react'
2+
import axios from 'axios'
3+
import { trackPromise, usePromiseTracker } from 'react-promise-tracker'
4+
import { apiURL } from '../config.json'
5+
import LoadingIndicator from '../modules/LoadingIndicator'
6+
7+
const UsersSuggestionDropdown = ({
8+
isOpen,
9+
userTerm,
10+
setUserTerm,
11+
setUserQuery,
12+
setUsersSuggestionOpen
13+
}) => {
14+
const [usersToSuggest, setUsersToSuggest] = useState([])
15+
16+
const { promiseInProgress } = usePromiseTracker({
17+
area: 'user-suggest-dropdown'
18+
})
19+
20+
const dropDown = useRef(null)
21+
22+
const cancelToken = useRef()
23+
24+
useEffect(() => {
25+
const handleClickOutside = (event) => {
26+
if (dropDown.current && !dropDown.current.contains(event.target)) {
27+
setUsersSuggestionOpen(false)
28+
}
29+
}
30+
document.addEventListener('mousedown', handleClickOutside)
31+
32+
return () => {
33+
document.removeEventListener('mousedown', handleClickOutside)
34+
}
35+
}, [setUsersSuggestionOpen])
36+
37+
useEffect(() => {
38+
if (userTerm.length <= 0) {
39+
setUsersSuggestionOpen(false)
40+
return
41+
}
42+
43+
if (typeof cancelToken.current !== typeof undefined) {
44+
cancelToken.current.cancel()
45+
}
46+
47+
cancelToken.current = axios.CancelToken.source()
48+
49+
const fetchUsers = async () => {
50+
const response = await axios.post(
51+
`${apiURL}/graphql`,
52+
{
53+
query: `query {
54+
users (where: {
55+
username_contains: "${userTerm}"
56+
}) {
57+
id
58+
username
59+
profilePicture {
60+
url
61+
}
62+
}
63+
}`
64+
},
65+
{ cancelToken: cancelToken.current.token }
66+
)
67+
setUsersToSuggest(response.data.data?.users ?? [])
68+
}
69+
if (userTerm.length > 0) {
70+
trackPromise(fetchUsers(), 'user-suggest-dropdown')
71+
} else {
72+
setUsersToSuggest([])
73+
}
74+
}, [userTerm, setUsersSuggestionOpen])
75+
76+
if (!isOpen) {
77+
return null
78+
}
79+
return (
80+
<div
81+
ref={dropDown}
82+
className='flex flex-center dropdown user-suggest-dropdown'
83+
>
84+
{promiseInProgress ? (
85+
<LoadingIndicator />
86+
) : usersToSuggest.length > 0 ? (
87+
<ul className='dropdown-list'>
88+
{usersToSuggest.map((user) => (
89+
<li
90+
key={user.id}
91+
onClick={() => {
92+
setUserTerm(user.username)
93+
setUserQuery(user.username)
94+
setUsersSuggestionOpen(false)
95+
}}
96+
className='user-data'
97+
>
98+
<div className='user-row flex flex-space-between flex-align-center'>
99+
<img
100+
className='avatar'
101+
src={
102+
user?.profilePicture?.url ??
103+
`https://avatars.dicebear.com/api/jdenticon/${user.username}.svg`
104+
}
105+
alt='Default User Avatar'
106+
></img>
107+
<span>{user.username}</span>
108+
</div>
109+
</li>
110+
))}
111+
</ul>
112+
) : (
113+
<p>No users found</p>
114+
)}
115+
</div>
116+
)
117+
}
118+
119+
export default UsersSuggestionDropdown

0 commit comments

Comments
 (0)