-
Notifications
You must be signed in to change notification settings - Fork 0
/
Form.js
123 lines (108 loc) · 3.35 KB
/
Form.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import React, { useState, useEffect } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { BiSearch } from 'react-icons/bi'
import { clearSearch, filterRestaurants, clearAll } from '../../actions/session'
import Dropdown from '../Dropdown/Dropdown'
import './Form.css'
const Form = () => {
const dispatch = useDispatch()
const restaurants = useSelector((store) => store.restaurants)
const session = useSelector((store) => store.session)
const [searchValue, setSearchValue] = useState('')
useEffect(() => {
searchValue === '' && dispatch(clearSearch())
}, [searchValue])
const handleChange = (e) => {
setSearchValue(e.target.value)
}
const searchHandler = () => {
const filteredRestaurants = restaurants.reduce((filtered, restaurant) => {
if (
restaurant.name.toUpperCase().includes(searchValue.toUpperCase()) ||
restaurant.city.toUpperCase().includes(searchValue.toUpperCase()) ||
restaurant.genre.toUpperCase().includes(searchValue.toUpperCase())
) {
filtered.push(restaurant.id)
}
return filtered
}, [])
dispatch(filterRestaurants(filteredRestaurants))
}
const handleKeyDown = (e) => {
e.key === 'Enter' && searchHandler()
}
const clearHandler = () => {
setSearchValue('')
dispatch(clearAll())
}
const restaurantsToFilter = session.searchApplied
? restaurants.filter((restaurant) =>
session.filteredRestaurants.includes(restaurant.id),
)
: restaurants
const stateFilterOptions = restaurantsToFilter.reduce(
(options, restaurant) => {
!options.includes(restaurant.state) && options.push(restaurant.state)
return options
},
[],
)
const genreFilterOptions = restaurantsToFilter.reduce(
(options, restaurant) => {
restaurant.genreArray.forEach(
(genre) => !options.includes(genre) && options.push(genre),
)
return options
},
[],
)
const attireFilterOptions = restaurantsToFilter.reduce(
(options, restaurant) => {
!options.includes(restaurant.attire) && options.push(restaurant.attire)
return options
},
[],
)
return (
<section className='search-filter-form-container'>
<section className='search-input-wrapper'>
<input
name='Search by restaurant name | city | genre'
type='text'
placeholder='Search by restaurant name | city | genre'
onChange={handleChange}
onKeyDown={handleKeyDown}
value={searchValue}
className='search-input'
data-testid='search-input'
/>
<button onClick={searchHandler} className='search-button'>
<BiSearch />
</button>
</section>
<section className='filters-wrapper'>
<Dropdown
possibleOptions={stateFilterOptions}
title='Filter by State'
type='state'
/>
<Dropdown
possibleOptions={genreFilterOptions}
title='Filter by Genre'
type='genre'
/>
<Dropdown
possibleOptions={attireFilterOptions}
title='Filter by Attire'
type='attire'
/>
</section>
<section>
<button onClick={clearHandler} className='clear-all-filter-button'>
clear all filters
</button>
</section>
</section>
)
}
export default Form