Projekt

Obecné

Profil

Stáhnout (11.9 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
import { login } from "../stores/actions/userThunks"
17

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

    
20
  const dispatch = useDispatch<AppDispatch>()
21

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

    
28
  const DEFAULT_FLOOR = "first_floor"
29

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

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

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

    
38

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

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

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

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

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

    
53
  const toast = useToast();
54

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

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

    
60
        selectRoom(route.params?.roomId)
61

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

    
66
        
67
        dispatch(getPlanInventories({ room: route.params.roomId, place: route.params.placeId }))
68

    
69
      }
70
      else {
71
        selectFloor(DEFAULT_FLOOR)
72
      }
73
    }
74
  }, [floorList, route.params?.roomId, route.params?.placeId])
75

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

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

    
91

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

    
106

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

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

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

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

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

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

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

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

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

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

    
165

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

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

    
178
  return (
179
    <Box flex={1} mb={2}>
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={"primary.500"}
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 - 450}
303
                onTouchStart={() => setIsInteractingWithCastlePlan(true)}
304
                onTouchEnd={() => setIsInteractingWithCastlePlan(true)}>
305
                <CastlePlanView mapImage={floorMapImage} selectedRoom={selectedRoom} roomList={selectedFloor.roomList} height={Dimensions.get("window").height - 450}
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 color="primary" bold={castlePlanShown} mb={castlePlanShown ? undefined : 2}>
353
              Castle
354
            </Text>
355
            {castlePlanShown && <Divider color="primary" 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 color="primary" bold={!castlePlanShown} mb={!castlePlanShown ? undefined : 2}>
365
              Results
366
            </Text>
367
            {!castlePlanShown && <Divider color="primary" borderWidth={1} width={60} mt={2} />}
368
          </VStack>
369
        </Button>
370
      </HStack>
371
    </Box>
372
  );
373
}
374

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