Projekt

Obecné

Profil

Stáhnout (12.2 KB) Statistiky
| Větev: | Tag: | Revize:
1
import React, { useEffect, useState } from "react"
2
import { useDispatch, useSelector } from "react-redux"
3
import { AppDispatch, RootState } from "../stores/store"
4
import LoadingBox from "../components/loading/LoadingBox"
5
import { log } from "../logging/logger"
6
import { DrawerScreenProps } from "@react-navigation/drawer"
7
import { RootStackParamList } from "./Navigation"
8
import { Box, CloseIcon, Select, useToast, Button, Flex, Text, VStack, ScrollView, HStack, Divider } from "native-base"
9
import { ErrorToast } from "../components/toast/ErrorToast"
10
import { Floor, Place, Room } from "../types/plan"
11
import { getFloorList, getPlanFloorImage, getPlanInventories, getPlanItems } from "../stores/actions/planThunks"
12
import ListView from "../components/listView/ListView"
13
import CastlePlanView from "../components/plan/CastlePlanView"
14

    
15
import { Dimensions } from 'react-native';
16

    
17
const PlanViewPage = ({ route, navigation }: DrawerScreenProps<RootStackParamList, 'Plan'>) => {
18

    
19
  const dispatch = useDispatch<AppDispatch>()
20

    
21
  // Route: set selected room / place from 
22
  useEffect(() => {
23
    console.log("dispatching get floor list")
24
    dispatch(getFloorList())
25
  }, [])
26

    
27
  const DEFAULT_FLOOR = "first_floor"
28

    
29
  const [castlePlanShown, setCastlePlanShown] = useState<boolean>(true)
30

    
31
  const [selectedFloor, setSelectedFloor] = useState<Floor | undefined>(undefined)
32
  const [selectedRoom, setSelectedRoom] = useState<Room | undefined>(undefined)
33
  const [selectedPlace, setSelectedPlace] = useState<Place | undefined>(undefined)
34

    
35
  const [isInteractingWithCastlePlan, setIsInteractingWithCastlePlan] = useState(false)
36

    
37

    
38
  const { floorListLoading, floorList, totalItemsCount, lastError } = useSelector((state: RootState) => state.planViewState)
39

    
40
  const inventories = useSelector((state: RootState) => state.planViewState.itemInventories)
41
  const inventoriesLoading = useSelector((state: RootState) => state.planViewState.itemInventoriesLoading)
42

    
43
  const numberOfResults = useSelector((state: RootState) => state.planViewState.totalItemsCount)
44

    
45
  const data = useSelector((state: RootState) => state.planViewState.itemList)
46
  const dataLoading = useSelector((state: RootState) => state.planViewState.itemListLoading)
47
  const pagination = useSelector((state: RootState) => state.planViewState.itemListPagination)
48

    
49
  const floorMapImage = useSelector((state: RootState) => state.planViewState.mapImage)
50
  const floorMapImageLoading = useSelector((state: RootState) => state.planViewState.mapImageLoading)
51

    
52
  const toast = useToast();
53

    
54
  useEffect(() => {
55
    if (floorList && !selectedFloor) {
56

    
57
      if (route.params && route.params.roomId) {
58

    
59
        selectRoom(route.params?.roomId)
60

    
61
        if (route.params.placeId) {
62
          selectPlace(route.params.placeId)
63
        }
64

    
65
        // if (!itemListLoading) {
66
        //   searchSubmit(currentPage, route.params.roomId, route.params.placeId)
67
        // }
68
      }
69
      else {
70
        selectFloor(DEFAULT_FLOOR)
71
      }
72
    }
73
  }, [floorList, route.params?.roomId, route.params?.placeId])
74

    
75
  useEffect(() => {
76
    if (floorList) {
77
      if (!inventoriesLoading) {
78
        dispatch(getPlanInventories({ room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
79
      }
80
    }
81
  }, [selectedPlace, selectedRoom])
82

    
83
  useEffect(() => {
84
    if (selectedFloor) {
85
      console.log("Dispatching getFloorImage " + selectedFloor.id)
86
      dispatch(getPlanFloorImage(selectedFloor.id))
87
    }
88
  }, [selectedFloor])
89

    
90

    
91
  useEffect(() => {
92
    if (lastError) {
93
      toast.closeAll()
94
      toast.show({
95
        render: ({
96
          id
97
        }) => {
98
          return <ErrorToast headerText={"Error"} text={lastError} onClose={() => toast.close(id)} />;
99
        },
100
        duration: 3000
101
      });
102
    }
103
  }, [lastError])
104

    
105

    
106
  const searchSubmit = (roomId: number, placeId?: number) => {
107
    log.debug("PlanView", "searchSubmit")
108

    
109
    console.log("searching " + roomId + ", " + placeId)
110

    
111
    dispatch(getPlanInventories({ room: roomId, place: placeId }))
112
  }
113

    
114
  const selectFloor = (floorId: string) => {
115
    if (floorId == selectedFloor?.id) {
116
      return;
117
    }
118

    
119
    for (let i = 0; i < floorList.length; i++) {
120
      let floor = floorList[i]
121
      if (floor.id == floorId) {
122
        setSelectedFloor(floor)
123
        setSelectedRoom(undefined)
124
        setSelectedPlace(undefined)
125
        return;
126
      }
127
    }
128
  }
129

    
130
  const selectRoom = (roomId: number) => {
131
    if (roomId == selectedRoom?.id) {
132
      return;
133
    }
134

    
135
    for (let i = 0; i < floorList.length; i++) {
136
      let floor = floorList[i]
137

    
138
      for (let j = 0; j < floor.roomList.length; j++) {
139
        let room = floor.roomList[j]
140
        if (room.id == roomId) {
141
          setSelectedFloor(floor)
142
          setSelectedRoom(room)
143
          setSelectedPlace(undefined)
144
          return;
145
        }
146
      }
147
    }
148
  }
149

    
150
  const selectPlace = (placeId: number) => {
151
    if (placeId == selectedPlace?.id) {
152
      return;
153
    }
154

    
155
    for (let i = 0; selectedRoom?.places && i < selectedRoom?.places?.length; i++) {
156
      let place = selectedRoom?.places[i]
157
      if (place.id == placeId) {
158
        setSelectedPlace(place)
159
        return;
160
      }
161
    }
162
  }
163

    
164

    
165
  const clearForm = () => {
166
    log.debug("PlanView", "clearForm")
167
    setSelectedPlace(undefined)
168
    setSelectedRoom(undefined)
169
    selectFloor(DEFAULT_FLOOR)
170
  }
171

    
172
  const onBackPressed = () => {
173
    log.debug("back pressed")
174
    navigation.goBack();
175
  }
176

    
177
  return (
178
    <Box flex={1}>
179
      <Box h={Dimensions.get('window').height - 55}>
180
        <ScrollView flex={1} w={"100%"} nestedScrollEnabled={!isInteractingWithCastlePlan}>
181
          <VStack space={1}>
182

    
183
            {/* Selection */}
184

    
185
            {
186
              floorListLoading ?
187
                <LoadingBox text="Floor list loading"></LoadingBox>
188
                :
189
                <>
190
                  {/* Floor */}
191
                  <Select
192
                    mt={2.5}
193
                    ml={2.5}
194
                    mr={2.5}
195

    
196
                    placeholder={"Floor"}
197
                    selectedValue={selectedFloor?.id}
198
                    onValueChange={selectFloor}
199
                    variant="rounded"
200
                  >
201
                    {floorList.map((floor, index) => {
202
                      return (
203
                        <Select.Item value={floor.id} label={floor.label} />
204
                      );
205
                    })}
206
                  </Select>
207

    
208
                  {/* Room */}
209

    
210
                  < Select
211
                    mt={2.5}
212
                    ml={2.5}
213
                    mr={2.5}
214

    
215
                    isDisabled={(selectedFloor && selectedFloor.roomList && selectedFloor.roomList.length) ? false : true}
216

    
217
                    placeholder={"Room"}
218
                    selectedValue={selectedRoom?.id.toString()}
219
                    onValueChange={(value: string) => selectRoom(parseInt(value))}
220
                    variant="rounded"
221
                  >
222
                    {selectedFloor?.roomList?.map((room, index) => {
223
                      if (room.room_list) {
224
                        return (
225
                          <Select.Item value={room.id.toString()} label={room.label} />
226
                        );
227
                      }
228
                    })}
229
                  </Select>
230

    
231
                  {/* Place */}
232
                  <Select
233
                    mt={2.5}
234
                    ml={2.5}
235
                    mr={2.5}
236

    
237
                    isDisabled={(selectedRoom && selectedRoom.places && selectedRoom.places.length > 0) ? false : true}
238
                    placeholder={"Place"}
239
                    selectedValue={selectedPlace?.id.toString()}
240
                    onValueChange={(value: string) => selectPlace(parseInt(value))}
241
                    variant="rounded"
242
                  >
243
                    {selectedRoom?.places?.map((place, index) => {
244
                      return (
245
                        <Select.Item value={place.id.toString()} label={place.label} />
246
                      );
247
                    })}
248
                  </Select>
249

    
250
                  {/* Filter */}
251
                  <Flex direction="row" alignItems="center" justify="flex-end"
252
                    mt={2.5}
253
                    ml={2.5}
254
                    mr={3}
255
                  >
256
                    <Button
257
                      startIcon={
258
                        <CloseIcon size="xs" />
259
                      }
260
                      onPress={clearForm}
261
                      variant="subtle"
262
                      color="secondary.500"
263
                      mr={2}
264
                      borderRadius={10}
265
                      size={"sm"}
266
                    >
267
                      Reset
268
                    </Button>
269
                    <Button
270
                      onPress={() => {
271
                        if (selectedRoom && !selectedPlace) {
272
                          searchSubmit(selectedRoom.id)
273
                        }
274
                        else if (selectedRoom && selectedPlace) {
275
                          searchSubmit(selectedRoom.id, selectedPlace.id)
276
                        }
277

    
278
                      }}
279
                      backgroundColor={"#654B07"}
280
                      variant="subtle"
281
                      borderRadius={10}
282
                      size={"sm"}
283
                    >
284
                      <Text color="white" fontSize={11}>
285
                        Search
286
                      </Text>
287
                    </Button>
288
                  </Flex>
289
                </>
290
            }
291

    
292
            {/* Plan */}
293
            {castlePlanShown && selectedFloor && !floorListLoading && (
294
              floorMapImageLoading ?
295
                <LoadingBox text="Loading castle plan" />
296
                :
297
                floorMapImage &&
298
                <Box
299
                  mt={2.5}
300
                  ml={2.5}
301
                  mr={2.5}
302
                  height={Dimensions.get("window").height - 350}
303
                  onTouchStart={() => setIsInteractingWithCastlePlan(true)}
304
                  onTouchEnd={() => setIsInteractingWithCastlePlan(true)}>
305
                  <CastlePlanView mapImage={floorMapImage} selectedRoom={selectedRoom} roomList={selectedFloor.roomList} height={Dimensions.get("window").height - 350}
306
                    setSelectedRoom={(room: Room) => {
307
                      selectRoom(room.id)
308
                    }}
309
                    fullScreenMode={false}
310
                  />
311
                </Box>
312
            )
313
            }
314

    
315
            {/* Item List */}
316
            <>
317
              {!castlePlanShown && (
318
                inventoriesLoading ?
319
                  <LoadingBox text="Loading available inventories..." />
320
                  :
321
                  <Box mt={5} ml={2.5} mr={2.5}>
322
                    <ListView
323

    
324
                      navigation={navigation}
325
                      hideHeaderText
326

    
327
                      inventories={inventories}
328
                      numOfResults={numberOfResults}
329

    
330
                      data={data}
331
                      loadedPages={pagination ?? {}}
332
                      inventoriesDataLoading={dataLoading ?? {}}
333
                      handleLoadMoreItems={(inventoryName: string, cursor: number) => {
334
                        dispatch(getPlanItems({ cursor: cursor, inventory: inventoryName, room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
335
                      }}
336
                    />
337
                  </Box>
338
              )
339
              }
340
            </>
341

    
342
          </VStack>
343
        </ScrollView>
344
        {/* item notes switch tab */}
345
        <HStack alignItems="center">
346
          <Button
347
            variant={"unstyled"}
348
            w="50%"
349
            onPress={() => { setCastlePlanShown(true) }}
350
          >
351
            <VStack alignItems={"center"}>
352
              <Text bold={castlePlanShown} mb={castlePlanShown ? undefined : 2}>
353
                Castle
354
              </Text>
355
              {castlePlanShown && <Divider borderWidth={1} width={60} mt={2} />}
356
            </VStack>
357
          </Button>
358
          <Button
359
            variant={"unstyled"}
360
            w="50%"
361
            onPress={() => { setCastlePlanShown(false) }}
362
          >
363
            <VStack alignItems={"center"}>
364
              <Text bold={!castlePlanShown} mb={!castlePlanShown ? undefined : 2}>
365
                Results
366
              </Text>
367
              {!castlePlanShown && <Divider borderWidth={1} width={60} mt={2} />}
368
            </VStack>
369
          </Button>
370
        </HStack>
371
      </Box>
372
    </Box>
373
  );
374
}
375

    
376
export default PlanViewPage;
(7-7/8)