Projekt

Obecné

Profil

Stáhnout (12.7 KB) Statistiky
| Větev: | Tag: | Revize:
1
import {
2
    Box,
3
    Button,
4
    ChevronDownIcon,
5
    ChevronUpIcon,
6
    CloseIcon,
7
    HStack,
8
    Input,
9
    Text,
10
    VStack
11
} from "native-base"
12
import { useDispatch, useSelector } from "react-redux"
13
import { useCallback, useEffect, useState } from "react"
14
import { AppDispatch, RootState } from "../../stores/store"
15
import { Inventory } from "../../types/searchFormTypes"
16
import { search } from "../../stores/actions/listViewThunks"
17
import MultiSelect from "./MultiSelect"
18
import SwitchWithLabel from "./SwitchWithLabel"
19
import { log } from "../../logging/logger"
20
import { setFilterState } from "../../stores/reducers/listViewSlice"
21
import { SearchParams } from "../../api/searchService"
22

    
23
interface SearchFormProps {
24
    inventoryId: string | null
25
}
26

    
27

    
28
const SearchForm = (props: SearchFormProps) => {
29
    const [isFilterOpen, setIsFilterOpen] = useState<boolean>(true)
30

    
31
    const inventories: Inventory[] = useSelector((state: RootState) => state.searchForm.inventories)
32
    const nationalities = useSelector((state: RootState) => state.searchForm.nationalities)
33
    const artists = useSelector((state: RootState) => state.searchForm.artists)
34
    const subjects = useSelector((state: RootState) => state.searchForm.subjects)
35
    const rooms = useSelector((state: RootState) => state.searchForm.rooms)
36
    const techniques = useSelector((state: RootState) => state.searchForm.techniques)
37
    const countries = useSelector((state: RootState) => state.searchForm.countries)
38
    const cities = useSelector((state: RootState) => state.searchForm.cities)
39
    const institutions = useSelector((state: RootState) => state.searchForm.institutions)
40

    
41
    const [selectedInventories, setSelectedInventories] = useState<{ label: string, value: string }[]>([])
42
    const [selectedNationalities, setSelectedNationalities] = useState<{ label: string, value: string }[]>([])
43
    const [selectedArtists, setSelectedArtists] = useState<{ label: string, value: string }[]>([])
44
    const [selectedSubjects, setSelectedSubjects] = useState<{ label: string, value: string }[]>([])
45
    const [selectedRooms, setSelectedRooms] = useState<{ label: string, value: string }[]>([])
46
    const [selectedTechniques, setSelectedTechniques] = useState<{ label: string, value: string }[]>([])
47
    const [selectedCountries, setSelectedCountries] = useState<{ label: string, value: string }[]>([])
48
    const [selectedCities, setSelectedCities] = useState<{ label: string, value: string }[]>([])
49
    const [selectedInstitutions, setSelectedInstitutions] = useState<{ label: string, value: string }[]>([])
50
    const [searchQuery, setSearchQuery] = useState<string>("")
51

    
52
    const [isSchoolOfPrague, setIsSchoolOfPrague] = useState(false)
53
    const [isOriginal, setIsOriginal] = useState(false)
54
    const [isCopy, setIsCopy] = useState(false)
55
    const [isHighQuality, setIsHighQuality] = useState(false)
56
    const [isLowQuality, setIsLowQuality] = useState(false)
57

    
58
    const dispatch = useDispatch<AppDispatch>()
59

    
60
    const searchSubmit = () => {
61
        const filterState: SearchParams = {
62
            inventories: selectedInventories.map(i => i.value),
63
            nationalities: selectedNationalities.map(n => n.value),
64
            artists: selectedArtists.map(a => a.value),
65
            subjects: selectedSubjects.map(s => s.value),
66
            rooms: selectedRooms.map(r => r.value),
67
            techniques: selectedTechniques.map(t => t.value),
68
            countries: selectedCountries.map(c => c.value),
69
            cities: selectedCities.map(c => c.value),
70
            institutions: selectedInstitutions.map(i => i.value),
71
            isSchoolOfPrague,
72
            isOriginal,
73
            isCopy,
74
            isHighQuality,
75
            isLowQuality,
76
            searchQuery: searchQuery,
77
        }
78
        dispatch(setFilterState(filterState))
79
        dispatch(search(filterState))
80
        setIsFilterOpen(false)
81
    }
82

    
83
    const clearForm = () => {
84
        log.debug("SearchForm", "clearForm")
85

    
86
        setSelectedInventories([])
87
        setSelectedNationalities([])
88
        setSelectedArtists([])
89
        setSelectedSubjects([])
90
        setSelectedRooms([])
91
        setSelectedTechniques([])
92
        setSelectedCountries([])
93
        setSelectedCities([])
94
        setSelectedInstitutions([])
95
        setSearchQuery("")
96

    
97
        // reset switches
98
        setIsSchoolOfPrague(false)
99
        setIsOriginal(false)
100
        setIsCopy(false)
101
        setIsHighQuality(false)
102
        setIsLowQuality(false)
103
    }
104

    
105
    const getSearchHeader = useCallback(() => {
106
        if (selectedInventories && selectedInventories.length === 1) {
107
            return `Search: ${ selectedInventories[0].label }`
108
        } else if (selectedRooms && selectedRooms.length === 1) {
109
            return `Search: ${ selectedRooms[0].label }`
110
        } else {
111
            return "Search:"
112
        }
113
    }, [selectedInventories, selectedRooms])
114

    
115
    useEffect(() => {
116
        log.debug("SearchForm", "useEffect", "props.inventoryId", props.inventoryId)
117
        if (props.inventoryId) {
118
            clearForm()
119
            setIsFilterOpen(false)
120
            setSelectedInventories([{ label: props.inventoryId, value: props.inventoryId }])
121
            dispatch(setFilterState({ inventories: [props.inventoryId] }))
122
            dispatch(search({ inventories: [props.inventoryId] }))
123
        }
124
    }, [props.inventoryId])
125

    
126
    return (
127
        <>
128
            <Text
129
                fontSize={ "2xl" }
130
                fontWeight={ "bold" }
131
                color={ "primary.500" }
132
            >
133
                { getSearchHeader() }
134
            </Text>
135
            <Input
136
                placeholder="Search"
137
                size={ "md" }
138
                variant="underlined"
139
                value={searchQuery}
140
                onChangeText={ setSearchQuery }
141
            />
142
            <HStack justifyContent={"space-between"}>
143
                <Button
144
                    onPress={ () => setIsFilterOpen(!isFilterOpen) }
145
                    variant="outline"
146
                    endIcon={
147
                        <>
148
                            { isFilterOpen ?
149
                                (<ChevronUpIcon size={ 4 } color={ "primary.500" }/>)
150
                                : (<ChevronDownIcon size={ 4 } color={ "primary.500" }/>) }
151
                        </>
152
                    }
153
                    flexWrap={ "nowrap" }
154
                    borderColor={ "primary.500" }
155
                    size={ "sm" }
156
                    mt={ 2 }
157
                    p={ 2 }
158

    
159
                >
160
                    Filter
161
                </Button>
162
                { !isFilterOpen && (
163
                    <Button
164
                        borderRadius={ 10 }
165
                        onPress={ () => searchSubmit() }
166
                        colorScheme="primary"
167
                        background={ "primary.500" }
168
                        variant="solid"
169
                        mt={2}
170
                        p={2}
171
                        size={ "md" }
172
                    >
173
                        Search
174
                    </Button>
175
                )}
176
            </HStack>
177
            { isFilterOpen && (
178
                <>
179
                    <MultiSelect
180
                        data={ inventories.map((inventory, index) => {
181
                            return {label: inventory.label, value: inventory.name, index}
182
                        }) }
183
                        label="Inventory (OR)"
184
                        selectedItems={ selectedInventories }
185
                        onSelectedItemsChange={ setSelectedInventories }
186
                    />
187
                    <MultiSelect
188
                        data={ rooms.map((room, index) => {
189
                            return {label: `${ room.id } - ${ room.label }`, value: room.id.toString(), index}
190
                        }) }
191
                        label="Rooms (OR)"
192
                        selectedItems={ selectedRooms }
193
                        onSelectedItemsChange={ setSelectedRooms }
194
                    />
195
                    <MultiSelect
196
                        data={ artists.map((art, index) => {
197
                            return {label: art.display_name, value: art.getty_id, index}
198
                        }) }
199
                        label="Artists/Copyists (OR)"
200
                        selectedItems={ selectedArtists }
201
                        onSelectedItemsChange={ setSelectedArtists }
202
                    />
203
                    <MultiSelect
204
                        data={ nationalities.map((nat, index) => {
205
                            return {label: nat, value: nat, index}
206
                        }) }
207
                        label="Artist`s Origin (OR)"
208
                        selectedItems={ selectedNationalities }
209
                        onSelectedItemsChange={ setSelectedNationalities }
210
                    />
211
                    <MultiSelect
212
                        data={ subjects.map((subj, index) => {
213
                            return {label: subj, value: subj, index}
214
                        }) }
215
                        label="Subject (AND)"
216
                        selectedItems={ selectedSubjects }
217
                        onSelectedItemsChange={ setSelectedSubjects }
218
                    />
219
                    <MultiSelect
220
                        data={ techniques.map((tech, index) => {
221
                            return {label: tech, value: tech, index}
222
                        }) }
223
                        label="Technique (OR)"
224
                        selectedItems={ selectedTechniques }
225
                        onSelectedItemsChange={ setSelectedTechniques }
226
                    />
227
                    <MultiSelect
228
                        data={ institutions.map((institution, index) => {
229
                            return {label: institution, value: institution, index}
230
                        }) }
231
                        label="Institution (OR)"
232
                        selectedItems={ selectedInstitutions }
233
                        onSelectedItemsChange={ setSelectedInstitutions }
234
                    />
235
                    <MultiSelect
236
                        data={ cities.map((city, index) => {
237
                            return {label: city, value: city, index}
238
                        }) }
239
                        label="City (OR)"
240
                        selectedItems={ selectedCities }
241
                        onSelectedItemsChange={ setSelectedCities }
242
                    />
243
                    <MultiSelect
244
                        data={ countries.map((country, index) => {
245
                            return {label: country, value: country, index}
246
                        }) }
247
                        label="Country (OR)"
248
                        selectedItems={ selectedCountries }
249
                        onSelectedItemsChange={ setSelectedCountries }
250
                    />
251
                    <VStack space={ 2 } mt={ 1 }>
252
                        <SwitchWithLabel label={ "School of Prague" } value={ isSchoolOfPrague }
253
                                         onValueChange={ setIsSchoolOfPrague }/>
254
                        <SwitchWithLabel label={ "Original" } value={ isOriginal } onValueChange={ setIsOriginal }/>
255
                        <SwitchWithLabel label={ "Copy" } value={ isCopy } onValueChange={ setIsCopy }/>
256
                        <SwitchWithLabel label={ "High Quality" } value={ isHighQuality }
257
                                         onValueChange={ setIsHighQuality }/>
258
                        <SwitchWithLabel label={ "Low Quality" } value={ isLowQuality }
259
                                         onValueChange={ setIsLowQuality }/>
260
                    </VStack>
261
                    <Box
262
                        flex={ 1 }
263
                        flexDirection="row"
264
                        justifyContent={ "flex-end" }
265
                        pt={ 2 }
266
                    >
267
                        <Button
268
                            borderRadius={ 10 }
269
                            startIcon={
270
                                <CloseIcon size="xs"/>
271
                            }
272
                            onPress={ clearForm }
273
                            variant="outline"
274
                            color="primary.500"
275
                            borderColor="primary.500"
276
                            mr={ 2 }
277
                            size={ "sm" }
278
                        >
279
                            Reset
280
                        </Button>
281
                        <Button
282
                            borderRadius={ 10 }
283
                            onPress={ () => searchSubmit() }
284
                            colorScheme="primary"
285
                            background={ "primary.500" }
286
                            variant="solid"
287
                            size={ "sm" }
288
                        >
289
                            Search
290
                        </Button>
291
                    </Box>
292
                </>
293
            ) }
294

    
295
        </>
296
    )
297
}
298

    
299
export default SearchForm
(2-2/3)