Projekt

Obecné

Profil

Stáhnout (13 KB) Statistiky
| Větev: | Tag: | Revize:
1 e49b1f44 Schwobik
import {
2
    Box,
3 4da7b143 Schwobik
    Button,
4
    ChevronDownIcon,
5
    ChevronUpIcon,
6
    CloseIcon,
7
    HStack,
8
    Input,
9
    Text,
10 e49b1f44 Schwobik
    VStack
11
} from "native-base"
12 9c55d3bb Schwobik
import { useDispatch, useSelector } from "react-redux"
13 4da7b143 Schwobik
import { useCallback, useEffect, useState } from "react"
14 9c55d3bb Schwobik
import { AppDispatch, RootState } from "../../stores/store"
15
import { Inventory } from "../../types/searchFormTypes"
16
import { search } from "../../stores/actions/listViewThunks"
17 e49b1f44 Schwobik
import MultiSelect from "./MultiSelect"
18
import SwitchWithLabel from "./SwitchWithLabel"
19
import { log } from "../../logging/logger"
20 ab632fe5 Michal Schwob
import {resetInventories, setFilterState} from "../../stores/reducers/listViewSlice"
21 ca44ce3d Schwobik
import { SearchParams } from "../../api/searchService"
22 9c55d3bb Schwobik
23 e49b1f44 Schwobik
interface SearchFormProps {
24 4da7b143 Schwobik
    inventoryId: string | null
25 e49b1f44 Schwobik
}
26 9c55d3bb Schwobik
27 e49b1f44 Schwobik
28
const SearchForm = (props: SearchFormProps) => {
29 4da7b143 Schwobik
    const [isFilterOpen, setIsFilterOpen] = useState<boolean>(true)
30 ab632fe5 Michal Schwob
    const loading = useSelector((state: RootState) => state.listView.loading)
31 4da7b143 Schwobik
32 9c55d3bb Schwobik
    const inventories: Inventory[] = useSelector((state: RootState) => state.searchForm.inventories)
33
    const nationalities = useSelector((state: RootState) => state.searchForm.nationalities)
34
    const artists = useSelector((state: RootState) => state.searchForm.artists)
35
    const subjects = useSelector((state: RootState) => state.searchForm.subjects)
36
    const rooms = useSelector((state: RootState) => state.searchForm.rooms)
37 e49b1f44 Schwobik
    const techniques = useSelector((state: RootState) => state.searchForm.techniques)
38 9c55d3bb Schwobik
    const countries = useSelector((state: RootState) => state.searchForm.countries)
39
    const cities = useSelector((state: RootState) => state.searchForm.cities)
40
    const institutions = useSelector((state: RootState) => state.searchForm.institutions)
41
42 e49b1f44 Schwobik
    const [selectedInventories, setSelectedInventories] = useState<{ label: string, value: string }[]>([])
43
    const [selectedNationalities, setSelectedNationalities] = useState<{ label: string, value: string }[]>([])
44
    const [selectedArtists, setSelectedArtists] = useState<{ label: string, value: string }[]>([])
45
    const [selectedSubjects, setSelectedSubjects] = useState<{ label: string, value: string }[]>([])
46
    const [selectedRooms, setSelectedRooms] = useState<{ label: string, value: string }[]>([])
47
    const [selectedTechniques, setSelectedTechniques] = useState<{ label: string, value: string }[]>([])
48
    const [selectedCountries, setSelectedCountries] = useState<{ label: string, value: string }[]>([])
49
    const [selectedCities, setSelectedCities] = useState<{ label: string, value: string }[]>([])
50
    const [selectedInstitutions, setSelectedInstitutions] = useState<{ label: string, value: string }[]>([])
51 1980ed09 Schwobik
    const [searchQuery, setSearchQuery] = useState<string>("")
52 9c55d3bb Schwobik
53 e49b1f44 Schwobik
    const [isSchoolOfPrague, setIsSchoolOfPrague] = useState(false)
54
    const [isOriginal, setIsOriginal] = useState(false)
55
    const [isCopy, setIsCopy] = useState(false)
56
    const [isHighQuality, setIsHighQuality] = useState(false)
57
    const [isLowQuality, setIsLowQuality] = useState(false)
58 9c55d3bb Schwobik
59
    const dispatch = useDispatch<AppDispatch>()
60
61 e49b1f44 Schwobik
    const searchSubmit = () => {
62 ca44ce3d Schwobik
        const filterState: SearchParams = {
63 e49b1f44 Schwobik
            inventories: selectedInventories.map(i => i.value),
64
            nationalities: selectedNationalities.map(n => n.value),
65
            artists: selectedArtists.map(a => a.value),
66
            subjects: selectedSubjects.map(s => s.value),
67
            rooms: selectedRooms.map(r => r.value),
68
            techniques: selectedTechniques.map(t => t.value),
69
            countries: selectedCountries.map(c => c.value),
70
            cities: selectedCities.map(c => c.value),
71
            institutions: selectedInstitutions.map(i => i.value),
72
            isSchoolOfPrague,
73
            isOriginal,
74
            isCopy,
75
            isHighQuality,
76 1980ed09 Schwobik
            isLowQuality,
77
            searchQuery: searchQuery,
78 ca44ce3d Schwobik
        }
79 ab632fe5 Michal Schwob
        dispatch(resetInventories())
80 ca44ce3d Schwobik
        dispatch(setFilterState(filterState))
81
        dispatch(search(filterState))
82 4da7b143 Schwobik
        setIsFilterOpen(false)
83 e49b1f44 Schwobik
    }
84 9c55d3bb Schwobik
85 e49b1f44 Schwobik
    const clearForm = () => {
86
        log.debug("SearchForm", "clearForm")
87 9c55d3bb Schwobik
88 e49b1f44 Schwobik
        setSelectedInventories([])
89
        setSelectedNationalities([])
90
        setSelectedArtists([])
91
        setSelectedSubjects([])
92
        setSelectedRooms([])
93
        setSelectedTechniques([])
94
        setSelectedCountries([])
95
        setSelectedCities([])
96
        setSelectedInstitutions([])
97 1980ed09 Schwobik
        setSearchQuery("")
98 5f3c7202 Michal Schwob
99
        // reset switches
100
        setIsSchoolOfPrague(false)
101
        setIsOriginal(false)
102
        setIsCopy(false)
103
        setIsHighQuality(false)
104
        setIsLowQuality(false)
105 1980ed09 Schwobik
    }
106
107 4da7b143 Schwobik
    const getSearchHeader = useCallback(() => {
108
        if (selectedInventories && selectedInventories.length === 1) {
109
            return `Search: ${ selectedInventories[0].label }`
110
        } else if (selectedRooms && selectedRooms.length === 1) {
111
            return `Search: ${ selectedRooms[0].label }`
112 1980ed09 Schwobik
        } else {
113
            return "Search:"
114
        }
115 cbf81c55 Schwobik
    }, [selectedInventories, selectedRooms])
116 4da7b143 Schwobik
117
    useEffect(() => {
118
        log.debug("SearchForm", "useEffect", "props.inventoryId", props.inventoryId)
119
        if (props.inventoryId) {
120
            clearForm()
121
            setIsFilterOpen(false)
122
            setSelectedInventories([{ label: props.inventoryId, value: props.inventoryId }])
123
            dispatch(setFilterState({ inventories: [props.inventoryId] }))
124
            dispatch(search({ inventories: [props.inventoryId] }))
125
        }
126
    }, [props.inventoryId])
127 9c55d3bb Schwobik
128
    return (
129 e49b1f44 Schwobik
        <>
130 1980ed09 Schwobik
            <Text
131
                fontSize={ "2xl" }
132
                fontWeight={ "bold" }
133
                color={ "primary.500" }
134
            >
135
                { getSearchHeader() }
136
            </Text>
137
            <Input
138
                placeholder="Search"
139
                size={ "md" }
140
                variant="underlined"
141
                value={searchQuery}
142
                onChangeText={ setSearchQuery }
143
            />
144
            <HStack justifyContent={"space-between"}>
145
                <Button
146 4da7b143 Schwobik
                    onPress={ () => setIsFilterOpen(!isFilterOpen) }
147 006d5d56 Michal Schwob
                    variant={"solid"}
148
                    colorScheme={ "secondary" }
149 1980ed09 Schwobik
                    endIcon={
150
                        <>
151 4da7b143 Schwobik
                            { isFilterOpen ?
152 1980ed09 Schwobik
                                (<ChevronUpIcon size={ 4 } color={ "primary.500" }/>)
153
                                : (<ChevronDownIcon size={ 4 } color={ "primary.500" }/>) }
154
                        </>
155
                    }
156
                    flexWrap={ "nowrap" }
157
                    borderColor={ "primary.500" }
158
                    size={ "sm" }
159
                    mt={ 2 }
160
                    p={ 2 }
161
162
                >
163 006d5d56 Michal Schwob
                    <Text color={"primary.500"}>
164 1980ed09 Schwobik
                    Filter
165 006d5d56 Michal Schwob
                    </Text>
166 1980ed09 Schwobik
                </Button>
167 4da7b143 Schwobik
                { !isFilterOpen && (
168 1980ed09 Schwobik
                    <Button
169 ab632fe5 Michal Schwob
                        isLoading={ loading }
170 1980ed09 Schwobik
                        borderRadius={ 10 }
171
                        onPress={ () => searchSubmit() }
172
                        colorScheme="primary"
173
                        variant="solid"
174
                        mt={2}
175
                        p={2}
176
                        size={ "md" }
177
                    >
178
                        Search
179
                    </Button>
180
                )}
181
            </HStack>
182 4da7b143 Schwobik
            { isFilterOpen && (
183 e49b1f44 Schwobik
                <>
184
                    <MultiSelect
185
                        data={ inventories.map((inventory, index) => {
186
                            return {label: inventory.label, value: inventory.name, index}
187
                        }) }
188
                        label="Inventory (OR)"
189
                        selectedItems={ selectedInventories }
190
                        onSelectedItemsChange={ setSelectedInventories }
191
                    />
192
                    <MultiSelect
193
                        data={ rooms.map((room, index) => {
194
                            return {label: `${ room.id } - ${ room.label }`, value: room.id.toString(), index}
195
                        }) }
196
                        label="Rooms (OR)"
197
                        selectedItems={ selectedRooms }
198
                        onSelectedItemsChange={ setSelectedRooms }
199
                    />
200
                    <MultiSelect
201
                        data={ artists.map((art, index) => {
202
                            return {label: art.display_name, value: art.getty_id, index}
203
                        }) }
204
                        label="Artists/Copyists (OR)"
205
                        selectedItems={ selectedArtists }
206
                        onSelectedItemsChange={ setSelectedArtists }
207
                    />
208
                    <MultiSelect
209
                        data={ nationalities.map((nat, index) => {
210
                            return {label: nat, value: nat, index}
211
                        }) }
212
                        label="Artist`s Origin (OR)"
213
                        selectedItems={ selectedNationalities }
214
                        onSelectedItemsChange={ setSelectedNationalities }
215
                    />
216
                    <MultiSelect
217
                        data={ subjects.map((subj, index) => {
218
                            return {label: subj, value: subj, index}
219
                        }) }
220
                        label="Subject (AND)"
221
                        selectedItems={ selectedSubjects }
222
                        onSelectedItemsChange={ setSelectedSubjects }
223
                    />
224
                    <MultiSelect
225
                        data={ techniques.map((tech, index) => {
226
                            return {label: tech, value: tech, index}
227
                        }) }
228
                        label="Technique (OR)"
229
                        selectedItems={ selectedTechniques }
230
                        onSelectedItemsChange={ setSelectedTechniques }
231
                    />
232
                    <MultiSelect
233
                        data={ institutions.map((institution, index) => {
234
                            return {label: institution, value: institution, index}
235
                        }) }
236
                        label="Institution (OR)"
237
                        selectedItems={ selectedInstitutions }
238
                        onSelectedItemsChange={ setSelectedInstitutions }
239
                    />
240
                    <MultiSelect
241
                        data={ cities.map((city, index) => {
242
                            return {label: city, value: city, index}
243
                        }) }
244
                        label="City (OR)"
245
                        selectedItems={ selectedCities }
246
                        onSelectedItemsChange={ setSelectedCities }
247
                    />
248
                    <MultiSelect
249
                        data={ countries.map((country, index) => {
250
                            return {label: country, value: country, index}
251
                        }) }
252
                        label="Country (OR)"
253
                        selectedItems={ selectedCountries }
254
                        onSelectedItemsChange={ setSelectedCountries }
255
                    />
256
                    <VStack space={ 2 } mt={ 1 }>
257
                        <SwitchWithLabel label={ "School of Prague" } value={ isSchoolOfPrague }
258
                                         onValueChange={ setIsSchoolOfPrague }/>
259
                        <SwitchWithLabel label={ "Original" } value={ isOriginal } onValueChange={ setIsOriginal }/>
260
                        <SwitchWithLabel label={ "Copy" } value={ isCopy } onValueChange={ setIsCopy }/>
261
                        <SwitchWithLabel label={ "High Quality" } value={ isHighQuality }
262
                                         onValueChange={ setIsHighQuality }/>
263
                        <SwitchWithLabel label={ "Low Quality" } value={ isLowQuality }
264
                                         onValueChange={ setIsLowQuality }/>
265
                    </VStack>
266
                    <Box
267
                        flex={ 1 }
268
                        flexDirection="row"
269
                        justifyContent={ "flex-end" }
270
                        pt={ 2 }
271 9c55d3bb Schwobik
                    >
272 e49b1f44 Schwobik
                        <Button
273
                            borderRadius={ 10 }
274
                            startIcon={
275 006d5d56 Michal Schwob
                                <CloseIcon size="xs" color={"primary.500"}/>
276 e49b1f44 Schwobik
                            }
277
                            onPress={ clearForm }
278 006d5d56 Michal Schwob
                            colorScheme={"secondary"}
279
                            variant="solid"
280 e49b1f44 Schwobik
                            mr={ 2 }
281
                            size={ "sm" }
282
                        >
283 006d5d56 Michal Schwob
                            <Text color={"primary.500"}>Reset</Text>
284 e49b1f44 Schwobik
                        </Button>
285
                        <Button
286 ab632fe5 Michal Schwob
                            isLoading={ loading }
287 e49b1f44 Schwobik
                            borderRadius={ 10 }
288
                            onPress={ () => searchSubmit() }
289
                            colorScheme="primary"
290
                            background={ "primary.500" }
291
                            variant="solid"
292
                            size={ "sm" }
293
                        >
294 006d5d56 Michal Schwob
                            <Text color={"white"}>Search</Text>
295 e49b1f44 Schwobik
                        </Button>
296
                    </Box>
297
                </>
298
            ) }
299 1980ed09 Schwobik
300 e49b1f44 Schwobik
        </>
301 9c55d3bb Schwobik
    )
302
}
303
304
export default SearchForm