1- import React from ' react' ;
2- import Select from ' react-select' ;
3- import each from ' lodash/each'
1+ import React from " react" ;
2+ import Select from " react-select" ;
3+ import each from " lodash/each" ;
44
5- import Card from ' ./ProjectsCards' ;
6- import projectList from ' ./listOfProjects' ;
5+ import Card from " ./ProjectsCards" ;
6+ import projectList from " ./listOfProjects" ;
77
8- import ' ./css/cards-container.css' ;
9- import ' ./css/search.css' ;
8+ import " ./css/cards-container.css" ;
9+ import " ./css/search.css" ;
1010
1111export default class CardsContainer extends React . Component {
1212 constructor ( props ) {
1313 super ( props ) ;
1414
1515 this . state = {
1616 value : [ ] ,
17- filterList : this . sortArrayRandom ( projectList )
18- }
17+ filterList : this . sortArrayRandom ( projectList ) ,
18+ } ;
1919
2020 this . setTags = new Set ( ) ;
2121 this . filterOptions = [ ] ;
2222 this . valueList = [ ] ;
2323
2424 for ( let i = 0 ; i < projectList . length ; i ++ ) {
25-
2625 if ( projectList [ i ] . tags ) {
27-
28- projectList [ i ] . tags . forEach ( tag => {
29-
30- projectList [ i ] . tags . sort ( )
31- this . setTags . add ( tag . toLowerCase ( ) )
32- } )
26+ projectList [ i ] . tags . forEach ( ( tag ) => {
27+ projectList [ i ] . tags . sort ( ) ;
28+ this . setTags . add ( tag . toLowerCase ( ) ) ;
29+ } ) ;
3330 }
3431 }
3532
36- this . setTags . forEach ( v => this . filterOptions . push ( { value : v , label : v } ) ) ;
33+ this . setTags . forEach ( ( v ) =>
34+ this . filterOptions . push ( { value : v , label : v } )
35+ ) ;
3736 this . handleSelectChange = this . handleSelectChange . bind ( this ) ;
3837 this . handleChange = this . handleChange . bind ( this ) ;
3938 }
4039
41- handleSelectChange ( value ) {
42-
43- this . value = value ;
44- this . setState ( { value } ) ;
45- this . handleFilterListUpdate ( value ) ;
40+ handleSelectChange ( selectedOptions ) {
41+ const valueArray = Array . isArray ( selectedOptions )
42+ ? selectedOptions
43+ : [ selectedOptions ] ;
44+ this . setState ( { value : valueArray } ) ;
45+ this . handleFilterListUpdate ( valueArray ) ;
4646 }
4747
4848 handleFilterListUpdate ( value ) {
49+ let updatedList = [ ...projectList ] ;
4950
50- let updatedList = [ ] ;
51-
52- // If no filters
53- if ( ( ! value || value . length === 0 ) && ( ! this . inputValue || this . inputValue . length === 0 ) ) {
51+ if (
52+ ( ! value || value . length === 0 ) &&
53+ ( ! this . inputValue || this . inputValue . length === 0 )
54+ ) {
5455 return this . setState ( { filterList : this . sortArrayRandom ( projectList ) } ) ;
5556 }
5657
5758 // If tags filter applied
58- if ( value && value . length > 0 ) {
59- const valueList = [ ] ;
60-
61- value . map ( v => {
62- return valueList . push ( v . value )
63- } ) ;
64-
65- each ( projectList , ( project ) => {
66-
67- if ( ! project . tags ) return ;
68-
69- let lowerCaseTags = project . tags . map ( v => v . toLowerCase ( ) )
70- if ( valueList . every ( v => lowerCaseTags . includes ( v ) ) ) {
71-
72- updatedList . push ( project ) ;
73- }
74- } )
59+ if ( value . length > 0 ) {
60+ const valueList = value . map ( ( v ) => v . value . toLowerCase ( ) ) ;
61+
62+ updatedList = updatedList . filter (
63+ ( project ) =>
64+ project . tags &&
65+ project . tags . some ( ( tag ) => valueList . includes ( tag . toLowerCase ( ) ) )
66+ ) ;
7567 }
7668
7769 // If search input value is not empty
78- if ( this . inputValue && this . inputValue . length > 0 ) {
79-
80- const searchedList = [ ]
81- each ( ( ( updatedList . length > 0 ) ? updatedList : projectList ) , ( project ) => {
82-
83- if ( project . name . toLowerCase ( ) . includes ( this . inputValue )
84- || project . description . toLowerCase ( ) . includes ( this . inputValue )
85- || project . tags . toString ( ) . toLowerCase ( ) . includes ( this . inputValue ) ) {
86-
87- searchedList . push ( project )
88- }
89- } ) ;
90-
91- updatedList = searchedList ;
70+ if ( this . inputValue && this . inputValue . trim ( ) . length > 0 ) {
71+ const searchTerm = this . inputValue . toLowerCase ( ) ;
72+
73+ updatedList = updatedList . filter (
74+ ( project ) =>
75+ project . name . toLowerCase ( ) . includes ( searchTerm ) ||
76+ project . description . toLowerCase ( ) . includes ( searchTerm ) ||
77+ ( project . tags &&
78+ project . tags . some ( ( tag ) => tag . toLowerCase ( ) . includes ( searchTerm ) ) )
79+ ) ;
9280 }
9381
9482 this . setState ( { filterList : updatedList } ) ;
9583 }
9684
9785 // Search input handler
9886 handleChange ( event ) {
99-
10087 this . inputValue = event . currentTarget . value ;
10188
10289 this . inputValue = this . inputValue . trim ( ) ;
10390 this . inputValue = this . inputValue . toLowerCase ( ) ;
10491
105- this . handleFilterListUpdate ( this . value )
92+ this . handleFilterListUpdate ( this . value ) ;
10693 }
10794
108- sortArrayRandom ( array ) {
109- if ( Array . isArray ( array ) ) {
110- return array . sort ( ( ) => 0.5 - Math . random ( ) )
95+ sortArrayRandom ( array ) {
96+ if ( Array . isArray ( array ) ) {
97+ return array . sort ( ( ) => 0.5 - Math . random ( ) ) ;
11198 }
112- return array
99+ return array ;
113100 }
114101
115102 render ( ) {
116-
117103 return (
118104 < div >
119- < div id = 'container' >
120- < div className = 'inputContainer' >
121- < input id = 'search' type = 'text' name = 'search' placeholder = 'Search...' onChange = { this . handleChange } aria-label = 'Search' />
105+ < div id = "container" >
106+ < div className = "inputContainer" >
107+ < input
108+ id = "search"
109+ type = "text"
110+ name = "search"
111+ placeholder = "Search..."
112+ onChange = { this . handleChange }
113+ aria-label = "Search"
114+ />
122115 </ div >
123- < div id = "tag-selector-container" className = ' inputContainer' >
116+ < div id = "tag-selector-container" className = " inputContainer" >
124117 < Select
125- name = ' tag-selector'
118+ name = " tag-selector"
126119 value = { this . state . value }
127120 onChange = { this . handleSelectChange }
128121 options = { this . filterOptions }
129- multi = { true }
130- placeholder = { < div className = 'filter-placeholder-text' > Filter</ div > }
131- aria-labelledby = 'tag-selector-container'
122+ isMulti = { true }
123+ placeholder = {
124+ < div className = "filter-placeholder-text" > Filter</ div >
125+ }
126+ aria-labelledby = "tag-selector-container"
132127 />
133128 </ div >
134129 </ div >
135- < section id = ' project-list' className = ' containerLayout' >
130+ < section id = " project-list" className = " containerLayout" >
136131 { this . state . filterList . map ( ( item , key ) => {
137132 return (
138133 < Card
@@ -142,7 +137,7 @@ export default class CardsContainer extends React.Component {
142137 projectLink = { item . projectLink }
143138 description = { item . description }
144139 tags = { item . tags }
145- className = ' testing-testing'
140+ className = " testing-testing"
146141 />
147142 ) ;
148143 } ) }
0 commit comments