Projekt

Obecné

Profil

Stáhnout (13.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 { RootDrawerParamList } from "./Navigation"
8
import { Box, CloseIcon, Select, useToast, Button, Flex, Text, Center, VStack, ScrollView, View, 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 { login } from "../stores/actions/userThunks"
13
import { getPlanItemsRequest } from "../api/planservice"
14
import ItemPreview from "../components/listView/ItemPreview"
15
import PlanView from "../components/plan/CastlePlanView"
16
import { BASE_API_URL } from "../api/constants"
17
import ListView from "../components/listView/ListView"
18
import SearchForm from "../components/search/SearchForm"
19
import { loadItemsByInventory } from "../stores/actions/listViewThunks"
20
import CastlePlanView from "../components/plan/CastlePlanView"
21

    
22
import { Dimensions } from 'react-native';
23

    
24
const PlanViewPage = ({ route, navigation }: DrawerScreenProps<RootDrawerParamList, 'Plan'>) => {
25

    
26
  const dispatch = useDispatch<AppDispatch>()
27

    
28
  // Route: set selected room / place from 
29
  useEffect(() => {
30
    console.log("dispatching get floor list")
31
    // dispatch(login({username: "Viktorie", password: "Golem123."}))
32
    dispatch(getFloorList())
33
  }, [])
34

    
35
  const DEFAULT_FLOOR = "first_floor"
36

    
37
  const [castlePlanShown, setCastlePlanShown] = useState<boolean>(true)
38

    
39
  const [selectedFloor, setSelectedFloor] = useState<Floor | undefined>(undefined)
40
  const [selectedRoom, setSelectedRoom] = useState<Room | undefined>(undefined)
41
  const [selectedPlace, setSelectedPlace] = useState<Place | undefined>(undefined)
42

    
43
  const [isInteractingWithCastlePlan, setIsInteractingWithCastlePlan] = useState(false);
44

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

    
47
  const inventories = useSelector((state: RootState) => state.planViewState.itemInventories)
48
  const inventoriesLoading = useSelector((state: RootState) => state.planViewState.itemInventoriesLoading)
49

    
50
  const numberOfResults = useSelector((state: RootState) => state.planViewState.totalItemsCount)
51

    
52
  const data = useSelector((state: RootState) => state.planViewState.itemList)
53
  const dataLoading = useSelector((state: RootState) => state.planViewState.itemListLoading)
54
  const pagination = useSelector((state: RootState) => state.planViewState.itemListPagination)
55

    
56
  const floorMapImage = useSelector((state: RootState) => state.planViewState.mapImage)
57
  const floorMapImageLoading = useSelector((state: RootState) => state.planViewState.mapImageLoading)
58

    
59
  // todo
60
  const castlePlanFullScreenMode = false
61

    
62
  const toast = useToast();
63

    
64
  useEffect(() => {
65
    if (floorList && !selectedFloor) {
66

    
67
      if (route.params && route.params.roomId) {
68

    
69
        selectRoom(route.params.roomId)
70

    
71
        if (route.params.placeId) {
72
          selectPlace(route.params.placeId)
73
        }
74

    
75
        // if (!itemListLoading) {
76
        //   searchSubmit(currentPage, route.params.roomId, route.params.placeId)
77
        // }
78
      }
79
      else {
80
        selectFloor(DEFAULT_FLOOR)
81
      }
82
    }
83
  }, [floorList, route.params.roomId, route.params.placeId])
84

    
85
  useEffect(() => {
86
    if (floorList) {
87
      if (!inventoriesLoading) {
88
        dispatch(getPlanInventories({ room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
89
      }
90
    }
91
  }, [selectedPlace, selectedRoom])
92

    
93
  useEffect(() => {
94
    if (selectedFloor) {
95
      console.log("Dispatching getFloorImage " + selectedFloor.id)
96
      dispatch(getPlanFloorImage(selectedFloor.id))
97
    }
98
  }, [selectedFloor])
99

    
100

    
101
  useEffect(() => {
102
    if (lastError) {
103
      toast.closeAll()
104
      toast.show({
105
        render: ({
106
          id
107
        }) => {
108
          return <ErrorToast headerText={"Error"} text={lastError} onClose={() => toast.close(id)} />;
109
        },
110
        duration: 3000
111
      });
112
    }
113
  }, [lastError])
114

    
115

    
116
  const searchSubmit = (roomId: number, placeId?: number) => {
117
    log.debug("PlanView", "searchSubmit")
118

    
119
    console.log("searching " + roomId + ", " + placeId)
120

    
121
    dispatch(getPlanInventories({ room: roomId, place: placeId }))
122
  }
123

    
124
  const selectFloor = (floorId: string) => {
125
    if (floorId == selectedFloor?.id) {
126
      return;
127
    }
128

    
129
    for (let i = 0; i < floorList.length; i++) {
130
      let floor = floorList[i]
131
      if (floor.id == floorId) {
132
        setSelectedFloor(floor)
133
        setSelectedRoom(undefined)
134
        setSelectedPlace(undefined)
135
        return;
136
      }
137
    }
138
  }
139

    
140
  const selectRoom = (roomId: number) => {
141
    if (roomId == selectedRoom?.id) {
142
      return;
143
    }
144

    
145
    for (let i = 0; i < floorList.length; i++) {
146
      let floor = floorList[i]
147

    
148
      for (let j = 0; j < floor.roomList.length; j++) {
149
        let room = floor.roomList[j]
150
        if (room.id == roomId) {
151
          setSelectedFloor(floor)
152
          setSelectedRoom(room)
153
          setSelectedPlace(undefined)
154
          return;
155
        }
156
      }
157
    }
158
  }
159

    
160
  const selectPlace = (placeId: number) => {
161
    if (placeId == selectedPlace?.id) {
162
      return;
163
    }
164

    
165
    for (let i = 0; selectedRoom?.places && i < selectedRoom?.places?.length; i++) {
166
      let place = selectedRoom?.places[i]
167
      if (place.id == placeId) {
168
        setSelectedPlace(place)
169
        return;
170
      }
171
    }
172
  }
173

    
174

    
175
  const clearForm = () => {
176
    log.debug("PlanView", "clearForm")
177
    setSelectedPlace(undefined)
178
    setSelectedRoom(undefined)
179
    selectFloor(DEFAULT_FLOOR)
180
  }
181

    
182
  const onBackPressed = () => {
183
    log.debug("back pressed")
184
    navigation.goBack();
185
  }
186

    
187
  return (
188
    <Box flex={1}>
189
      {!castlePlanFullScreenMode || !castlePlanShown ? (
190
        <Box h={Dimensions.get('window').height - 55}>
191
          <ScrollView flex={1} w={"100%"} nestedScrollEnabled={!isInteractingWithCastlePlan}>
192
            <VStack space={1}>
193

    
194
              {/* Selection */}
195

    
196
              {
197
                floorListLoading ?
198
                  <LoadingBox text="Floor list loading"></LoadingBox>
199
                  :
200
                  <>
201
                    {/* Floor */}
202
                    <Select
203
                      mt={2.5}
204
                      ml={2.5}
205
                      mr={2.5}
206

    
207
                      placeholder={"Floor"}
208
                      selectedValue={selectedFloor?.id}
209
                      onValueChange={selectFloor}
210
                      variant="rounded"
211
                    >
212
                      {floorList.map((floor, index) => {
213
                        return (
214
                          <Select.Item value={floor.id} label={floor.label} />
215
                        );
216
                      })}
217
                    </Select>
218

    
219
                    {/* Room */}
220

    
221
                    < Select
222
                      mt={2.5}
223
                      ml={2.5}
224
                      mr={2.5}
225

    
226
                      isDisabled={(selectedFloor && selectedFloor.roomList && selectedFloor.roomList.length) ? false : true}
227

    
228
                      placeholder={"Room"}
229
                      selectedValue={selectedRoom?.id.toString()}
230
                      onValueChange={(value: string) => selectRoom(parseInt(value))}
231
                      variant="rounded"
232
                    >
233
                      {selectedFloor?.roomList?.map((room, index) => {
234
                        if (room.room_list) {
235
                          return (
236
                            <Select.Item value={room.id.toString()} label={room.label} />
237
                          );
238
                        }
239
                      })}
240
                    </Select>
241

    
242
                    {/* Place */}
243
                    <Select
244
                      mt={2.5}
245
                      ml={2.5}
246
                      mr={2.5}
247

    
248
                      isDisabled={(selectedRoom && selectedRoom.places && selectedRoom.places.length > 0) ? false : true}
249
                      placeholder={"Place"}
250
                      selectedValue={selectedPlace?.id.toString()}
251
                      onValueChange={(value: string) => selectPlace(parseInt(value))}
252
                      variant="rounded"
253
                    >
254
                      {selectedRoom?.places?.map((place, index) => {
255
                        return (
256
                          <Select.Item value={place.id.toString()} label={place.label} />
257
                        );
258
                      })}
259
                    </Select>
260

    
261
                    {/* Filter */}
262
                    <Flex direction="row" alignItems="center" justify="flex-end"
263
                      mt={2.5}
264
                      ml={2.5}
265
                      mr={3}
266
                    >
267
                      <Button
268
                        startIcon={
269
                          <CloseIcon size="xs" />
270
                        }
271
                        onPress={clearForm}
272
                        variant="subtle"
273
                        color="secondary.500"
274
                        mr={2}
275
                        borderRadius={10}
276
                        size={"sm"}
277
                      >
278
                        Reset
279
                      </Button>
280
                      <Button
281
                        onPress={() => {
282
                          if (selectedRoom && !selectedPlace) {
283
                            searchSubmit(selectedRoom.id)
284
                          }
285
                          else if (selectedRoom && selectedPlace) {
286
                            searchSubmit(selectedRoom.id, selectedPlace.id)
287
                          }
288

    
289
                        }}
290
                        backgroundColor={"#654B07"}
291
                        variant="subtle"
292
                        borderRadius={10}
293
                        size={"sm"}
294
                      >
295
                        <Text color="white" fontSize={11}>
296
                          Search
297
                        </Text>
298
                      </Button>
299
                    </Flex>
300
                  </>
301
              }
302

    
303
              {/* Plan */}
304
              {castlePlanShown && selectedFloor && !floorListLoading && (
305
                floorMapImageLoading ?
306
                  <LoadingBox text="Loading castle plan" />
307
                  :
308
                  floorMapImage &&
309
                  <Box
310
                    mt={2.5}
311
                    ml={2.5}
312
                    mr={2.5}
313
                    onTouchStart={() => setIsInteractingWithCastlePlan(true)}
314
                    onTouchEnd={() => setIsInteractingWithCastlePlan(true)}>
315
                    <CastlePlanView mapImage={floorMapImage} selectedRoom={selectedRoom} roomList={selectedFloor.roomList} height={Dimensions.get("window").height - 350} />
316
                  </Box>
317
              )
318
              }
319

    
320
              {/* Item List */}
321
              <>
322
                {!castlePlanShown && (
323
                  inventoriesLoading ?
324
                    <LoadingBox text="Loading available inventories..." />
325
                    :
326
                    <Box mt={2.5} ml={2.5} mr={2.5}>
327
                      <ListView
328

    
329
                        navigation={navigation}
330
                        hideHeaderText
331

    
332
                        inventories={inventories}
333
                        numOfResults={numberOfResults}
334

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

    
342
                      />
343
                    </Box>
344
                )
345
                }
346
              </>
347

    
348
            </VStack>
349
          </ScrollView>
350
          {/* item notes switch tab */}
351
          <HStack alignItems="center">
352
            <Button
353
              variant={"unstyled"}
354
              w="50%"
355
              onPress={() => { setCastlePlanShown(true) }}
356
            >
357
              <VStack alignItems={"center"}>
358
                <Text bold={castlePlanShown} mb={castlePlanShown ? undefined : 2}>
359
                  Castle
360
                </Text>
361
                {castlePlanShown && <Divider borderWidth={1} width={60} mt={2} />}
362
              </VStack>
363
            </Button>
364
            <Button
365
              variant={"unstyled"}
366
              w="50%"
367
              onPress={() => { setCastlePlanShown(false) }}
368
            >
369
              <VStack alignItems={"center"}>
370
                <Text bold={!castlePlanShown} mb={!castlePlanShown ? undefined : 2}>
371
                  Results
372
                </Text>
373
                {!castlePlanShown && <Divider borderWidth={1} width={60} mt={2} />}
374
              </VStack>
375
            </Button>
376
          </HStack>
377
        </Box>
378
      )
379
        :
380
        floorMapImageLoading ?
381
          <LoadingBox text="Loading castle plan" />
382
          :
383
          floorMapImage && selectedFloor &&
384
          <Box>
385
            <CastlePlanView fullScreenMode mapImage={floorMapImage} selectedRoom={selectedRoom} roomList={selectedFloor.roomList} />
386
          </Box>
387
      }
388
    </Box>
389
  );
390
}
391

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