@@ -2,44 +2,78 @@ import React, { useState, useRef, useEffect } from 'react';
2
2
import useDebounce from '../../hooks/useDebouncer' ;
3
3
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome' ;
4
4
import { faMagnifyingGlass , faXmark } from '@fortawesome/free-solid-svg-icons' ;
5
+ import SearchSkillsContainer from './SearchSkillsContainer' ;
5
6
6
7
function Search ( { onSearch } ) {
7
8
const [ searchValue , setSearchValue ] = useState ( '' ) ;
8
9
const [ prevSearchValue , setPrevSearchValue ] = useState ( '' ) ;
9
10
const [ searchCriteria , setSearchCriteria ] = useState ( 'name' ) ;
10
11
const searchInput = useRef ( null ) ;
11
12
13
+ const [ searchSkills , setSearchSkills ] = useState ( [ ] ) ;
14
+
15
+ const normalizeString = ( str ) =>
16
+ str
17
+ . toLowerCase ( )
18
+ . replace ( / \s * , \s * / g, ' ' )
19
+ . replace ( / \s + / g, ' ' )
20
+ . trim ( ) ;
21
+
12
22
const handleInputChange = ( event ) => {
13
23
setSearchValue ( event . target . value ) ;
14
24
} ;
15
25
16
26
const handleCriteriaChange = ( event ) => {
27
+ if ( event . target . value !== "skill" ) {
28
+ handleClearSkills ( ) ;
29
+ }
17
30
setSearchCriteria ( event . target . value ) ;
31
+
18
32
} ;
19
33
20
34
const debouncedValue = useDebounce ( searchValue , 500 ) ;
21
35
22
36
useEffect ( ( ) => {
23
- if ( debouncedValue !== prevSearchValue ) {
37
+ if ( debouncedValue !== prevSearchValue && searchCriteria !== "skill" ) {
24
38
onSearch ( { value : debouncedValue , criteria : searchCriteria } ) ;
25
39
setPrevSearchValue ( debouncedValue ) ;
26
40
}
27
41
// eslint-disable-next-line react-hooks/exhaustive-deps
28
42
} , [ debouncedValue ] ) ;
29
43
30
44
const handleSearch = ( ) => {
31
- if ( searchValue !== prevSearchValue ) {
45
+ if ( ( searchValue !== prevSearchValue && searchCriteria !== "skill" ) || searchValue . trim ( ) === "" ) {
32
46
onSearch ( { value : searchValue , criteria : searchCriteria } ) ;
33
47
setPrevSearchValue ( searchValue ) ;
34
48
}
35
49
} ;
36
50
37
- const handleSearchOnEnter = ( e ) => {
38
- if ( e . keyCode === 13 ) {
39
- handleSearch ( ) ;
51
+ const handleSearchOnEnter = ( event ) => {
52
+ if ( event . keyCode === 13 ) {
53
+ //if searchCriteia is skill then it will add that skill to searchSkills
54
+ if ( searchCriteria === 'skill' ) {
55
+ let searchvalue = normalizeString ( searchValue ) ;
56
+ searchvalue = searchvalue . trim ( ) ;
57
+ if ( searchvalue . length > 0 ) {
58
+ var set = new Set ( searchSkills ) ;
59
+ set . add ( searchvalue ) ;
60
+ setSearchSkills ( ( prev ) => [ ...set ] ) ;
61
+ }
62
+ setSearchValue ( '' ) ;
63
+ } else {
64
+ handleSearch ( ) ;
65
+ }
40
66
}
41
67
} ;
42
68
69
+ useEffect ( ( ) => {
70
+ //when new skill is added to searchSkill it will filter the data
71
+ if ( searchCriteria === "skill" ) {
72
+ onSearch ( { value : searchSkills , criteria : searchCriteria } ) ;
73
+ setPrevSearchValue ( '' ) ;
74
+ }
75
+ } , [ searchSkills ] ) ;
76
+
43
77
const handleSearchButtonClick = ( ) => {
44
78
handleSearch ( ) ;
45
79
} ;
@@ -53,45 +87,70 @@ function Search({ onSearch }) {
53
87
}
54
88
} ;
55
89
90
+ //Reset the profiles
91
+ const handleClearSkills = ( ) => {
92
+ setSearchSkills ( [ ] ) ;
93
+ setSearchValue ( '' ) ;
94
+ setPrevSearchValue ( '' ) ;
95
+ onSearch ( { value : [ ] , criteria : "skill" } ) ;
96
+ searchInput . current . focus ( ) ;
97
+ } ;
98
+
56
99
useEffect ( ( ) => {
57
100
searchInput . current . focus ( ) ;
58
101
} , [ ] ) ;
59
102
60
103
return (
61
- < div className = "relative flex items-center justify-end space-x-4 pb-6" >
62
- < select
63
- className = "focus:border-primaryFocus focus:bg-primaryLight dark:focus:border-secondaryFocus dark:focus:bg-secondaryLight h-12 rounded-lg border-2 border-borderSecondary bg-primaryColor px-4 py-3 text-base text-secondaryColor outline-none dark:border-borderColor dark:bg-secondaryColor dark:text-white"
64
- value = { searchCriteria }
65
- onChange = { handleCriteriaChange }
66
- >
67
- < option value = "name" > Name</ option >
68
- < option value = "location" > Location</ option >
69
- < option value = "skill" > Skill</ option >
70
- </ select >
71
- < div className = "relative w-full" >
72
- < input
73
- className = "focus:border-primaryFocus focus:bg-primaryLight dark:focus:border-secondaryFocus dark:focus:bg-secondaryLight h-12 w-full rounded-lg border-2 border-borderSecondary bg-primaryColor px-4 py-3 pr-12 font-spaceMono text-base text-secondaryColor outline-none dark:border-borderColor dark:bg-secondaryColor dark:text-white"
74
- ref = { searchInput }
75
- type = "text"
76
- onChange = { handleInputChange }
77
- value = { searchValue }
78
- placeholder = { `Search user by ${ searchCriteria } ` }
79
- onKeyDown = { handleSearchOnEnter }
80
- />
81
- { searchValue ? (
82
- < FontAwesomeIcon
83
- onClick = { handleDeleteButtonClick }
84
- className = "hover:text-primaryFocus dark:hover:text-secondaryFocus absolute right-4 top-1/2 -translate-y-1/2 scale-125 transform cursor-pointer text-xl text-secondaryColor dark:text-white"
85
- icon = { faXmark }
104
+ < div className = "relative pb-6" >
105
+ < div className = "relative flex items-center justify-end space-x-4 " >
106
+ < select
107
+ className = "focus:border-primaryFocus focus:bg-primaryLight dark:focus:border-secondaryFocus dark:focus:bg-secondaryLight h-12 rounded-lg border-2 border-borderSecondary bg-primaryColor px-4 py-3 text-base text-secondaryColor outline-none dark:border-borderColor dark:bg-secondaryColor dark:text-white"
108
+ value = { searchCriteria }
109
+ onChange = { handleCriteriaChange }
110
+ >
111
+ < option value = "name" > Name</ option >
112
+ < option value = "location" > Location</ option >
113
+ < option value = "skill" > Skill</ option >
114
+ </ select >
115
+ < div className = "relative w-full" >
116
+ < input
117
+ className = "focus:border-primaryFocus focus:bg-primaryLight dark:focus:border-secondaryFocus dark:focus:bg-secondaryLight h-12 w-full rounded-lg border-2 border-borderSecondary bg-primaryColor px-4 py-3 pr-12 font-spaceMono text-base text-secondaryColor outline-none dark:border-borderColor dark:bg-secondaryColor dark:text-white"
118
+ ref = { searchInput }
119
+ type = "text"
120
+ onChange = { handleInputChange }
121
+ value = { searchValue }
122
+ placeholder = { `Search user by ${ searchCriteria } ` }
123
+ onKeyDown = { handleSearchOnEnter }
86
124
/>
87
- ) : (
88
- < FontAwesomeIcon
89
- onClick = { handleSearchButtonClick }
90
- className = "hover:text-primaryFocus dark:hover:text-secondaryFocus absolute right-4 top-1/2 -translate-y-1/2 transform cursor-pointer text-xl text-secondaryColor dark:text-white"
91
- icon = { faMagnifyingGlass }
92
- />
93
- ) }
125
+ { searchValue ? (
126
+ < FontAwesomeIcon
127
+ onClick = { handleDeleteButtonClick }
128
+ className = "hover:text-primaryFocus dark:hover:text-secondaryFocus absolute right-4 top-1/2 -translate-y-1/2 scale-125 transform cursor-pointer text-xl text-secondaryColor dark:text-white"
129
+ icon = { faXmark }
130
+ />
131
+ ) : (
132
+ < FontAwesomeIcon
133
+ onClick = { handleSearchButtonClick }
134
+ className = "hover:text-primaryFocus dark:hover:text-secondaryFocus absolute right-4 top-1/2 -translate-y-1/2 transform cursor-pointer text-xl text-secondaryColor dark:text-white"
135
+ icon = { faMagnifyingGlass }
136
+ />
137
+ ) }
138
+ </ div >
94
139
</ div >
140
+
141
+
142
+ { /* This block show the skills the user searched */ }
143
+ { searchCriteria === 'skill' && searchSkills && searchSkills . length > 0 ? (
144
+ < >
145
+ < button
146
+ onClick = { handleClearSkills }
147
+ className = "m-2 cursor-pointer self-end rounded-md bg-white p-2 font-semibold dark:bg-[#1E2A47] dark:text-white"
148
+ >
149
+ Clear All
150
+ </ button >
151
+ < SearchSkillsContainer searchSkills = { searchSkills } setSearchSkills = { setSearchSkills } />
152
+ </ >
153
+ ) : null }
95
154
</ div >
96
155
) ;
97
156
}
0 commit comments