Projekt

Obecné

Profil

Stáhnout (12.6 KB) Statistiky
| Větev: | Tag: | Revize:
1 90af86f9 Fantič
import React, { useEffect, useState } from "react"
2 c2c8470e Fantič
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 7a3ad946 Fantič
import { Box, CloseIcon, Select, useToast, Button, Flex, Text, Center, VStack, ScrollView, View, HStack, Divider } from "native-base"
9 c2c8470e Fantič
import { ErrorToast } from "../components/toast/ErrorToast"
10 9641b62f Fantič
import { Floor, Place, Room } from "../types/plan"
11 aac857cf Fantič
import { getFloorList, getPlanFloorImage, getPlanInventories, getPlanItems } from "../stores/actions/planThunks"
12 f8083631 Fantič
import { login } from "../stores/actions/userThunks"
13 160b7073 Fantič
import { getPlanItemsRequest } from "../api/planservice"
14
import ItemPreview from "../components/listView/ItemPreview"
15
import { BASE_API_URL } from "../api/constants"
16 a6999074 Fantič
import ListView from "../components/listView/ListView"
17
import SearchForm from "../components/search/SearchForm"
18
import { loadItemsByInventory } from "../stores/actions/listViewThunks"
19 aac857cf Fantič
import CastlePlanView from "../components/plan/CastlePlanView"
20 c2c8470e Fantič
21 7a3ad946 Fantič
import { Dimensions } from 'react-native';
22
23 c2c8470e Fantič
const PlanViewPage = ({ route, navigation }: DrawerScreenProps<RootDrawerParamList, 'Plan'>) => {
24
25 a6999074 Fantič
  const dispatch = useDispatch<AppDispatch>()
26 c2c8470e Fantič
27 160b7073 Fantič
  // Route: set selected room / place from 
28
  useEffect(() => {
29
    console.log("dispatching get floor list")
30
    // dispatch(login({username: "Viktorie", password: "Golem123."}))
31
    dispatch(getFloorList())
32
  }, [])
33 eb8efa3f Fantič
34 9641b62f Fantič
  const DEFAULT_FLOOR = "first_floor"
35 c2c8470e Fantič
36 7a3ad946 Fantič
  const [castlePlanShown, setCastlePlanShown] = useState<boolean>(true)
37
38 9641b62f Fantič
  const [selectedFloor, setSelectedFloor] = useState<Floor | undefined>(undefined)
39
  const [selectedRoom, setSelectedRoom] = useState<Room | undefined>(undefined)
40
  const [selectedPlace, setSelectedPlace] = useState<Place | undefined>(undefined)
41 c2c8470e Fantič
42 d26c4168 Fantič
  const [isInteractingWithCastlePlan, setIsInteractingWithCastlePlan] = useState(false)
43
44 28ab969f Fantič
45 a6999074 Fantič
  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 c2c8470e Fantič
50 a6999074 Fantič
  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 c2c8470e Fantič
56 aac857cf Fantič
  const floorMapImage = useSelector((state: RootState) => state.planViewState.mapImage)
57
  const floorMapImageLoading = useSelector((state: RootState) => state.planViewState.mapImageLoading)
58
59 c2c8470e Fantič
  const toast = useToast();
60
61 9641b62f Fantič
  useEffect(() => {
62
    if (floorList && !selectedFloor) {
63 a6999074 Fantič
64 f8083631 Fantič
      if (route.params && route.params.roomId) {
65
66
        selectRoom(route.params.roomId)
67 160b7073 Fantič
68 f8083631 Fantič
        if (route.params.placeId) {
69
          selectPlace(route.params.placeId)
70
        }
71 160b7073 Fantič
72 a6999074 Fantič
        // if (!itemListLoading) {
73
        //   searchSubmit(currentPage, route.params.roomId, route.params.placeId)
74
        // }
75 f8083631 Fantič
      }
76 160b7073 Fantič
      else {
77 9641b62f Fantič
        selectFloor(DEFAULT_FLOOR)
78 f8083631 Fantič
      }
79 9641b62f Fantič
    }
80 f8083631 Fantič
  }, [floorList, route.params.roomId, route.params.placeId])
81 9641b62f Fantič
82 160b7073 Fantič
  useEffect(() => {
83 a6999074 Fantič
    if (floorList) {
84
      if (!inventoriesLoading) {
85
        dispatch(getPlanInventories({ room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
86 160b7073 Fantič
      }
87
    }
88
  }, [selectedPlace, selectedRoom])
89
90 aac857cf Fantič
  useEffect(() => {
91
    if (selectedFloor) {
92
      console.log("Dispatching getFloorImage " + selectedFloor.id)
93
      dispatch(getPlanFloorImage(selectedFloor.id))
94
    }
95
  }, [selectedFloor])
96
97 160b7073 Fantič
98 c2c8470e Fantič
  useEffect(() => {
99
    if (lastError) {
100
      toast.closeAll()
101
      toast.show({
102
        render: ({
103
          id
104
        }) => {
105
          return <ErrorToast headerText={"Error"} text={lastError} onClose={() => toast.close(id)} />;
106
        },
107
        duration: 3000
108
      });
109
    }
110
  }, [lastError])
111
112
113 a6999074 Fantič
  const searchSubmit = (roomId: number, placeId?: number) => {
114 90af86f9 Fantič
    log.debug("PlanView", "searchSubmit")
115
116 160b7073 Fantič
    console.log("searching " + roomId + ", " + placeId)
117
118 a6999074 Fantič
    dispatch(getPlanInventories({ room: roomId, place: placeId }))
119 90af86f9 Fantič
  }
120
121 9641b62f Fantič
  const selectFloor = (floorId: string) => {
122
    if (floorId == selectedFloor?.id) {
123
      return;
124
    }
125
126
    for (let i = 0; i < floorList.length; i++) {
127
      let floor = floorList[i]
128
      if (floor.id == floorId) {
129
        setSelectedFloor(floor)
130
        setSelectedRoom(undefined)
131
        setSelectedPlace(undefined)
132
        return;
133
      }
134
    }
135
  }
136
137
  const selectRoom = (roomId: number) => {
138
    if (roomId == selectedRoom?.id) {
139
      return;
140
    }
141
142
    for (let i = 0; i < floorList.length; i++) {
143
      let floor = floorList[i]
144
145
      for (let j = 0; j < floor.roomList.length; j++) {
146
        let room = floor.roomList[j]
147
        if (room.id == roomId) {
148
          setSelectedFloor(floor)
149
          setSelectedRoom(room)
150
          setSelectedPlace(undefined)
151
          return;
152
        }
153
      }
154
    }
155
  }
156
157
  const selectPlace = (placeId: number) => {
158
    if (placeId == selectedPlace?.id) {
159
      return;
160
    }
161
162
    for (let i = 0; selectedRoom?.places && i < selectedRoom?.places?.length; i++) {
163
      let place = selectedRoom?.places[i]
164
      if (place.id == placeId) {
165
        setSelectedPlace(place)
166
        return;
167
      }
168
    }
169
  }
170
171
172 90af86f9 Fantič
  const clearForm = () => {
173
    log.debug("PlanView", "clearForm")
174
    setSelectedPlace(undefined)
175 a6999074 Fantič
    setSelectedRoom(undefined)
176
    selectFloor(DEFAULT_FLOOR)
177 90af86f9 Fantič
  }
178 c2c8470e Fantič
179
  const onBackPressed = () => {
180
    log.debug("back pressed")
181
    navigation.goBack();
182
  }
183
184
  return (
185 5cee436e Fantič
    <Box flex={1}>
186 d26c4168 Fantič
      <Box h={Dimensions.get('window').height - 55}>
187
        <ScrollView flex={1} w={"100%"} nestedScrollEnabled={!isInteractingWithCastlePlan}>
188
          <VStack space={1}>
189
190
            {/* Selection */}
191
192
            {
193
              floorListLoading ?
194
                <LoadingBox text="Floor list loading"></LoadingBox>
195
                :
196
                <>
197
                  {/* Floor */}
198
                  <Select
199
                    mt={2.5}
200
                    ml={2.5}
201
                    mr={2.5}
202 7a3ad946 Fantič
203 d26c4168 Fantič
                    placeholder={"Floor"}
204
                    selectedValue={selectedFloor?.id}
205
                    onValueChange={selectFloor}
206
                    variant="rounded"
207
                  >
208
                    {floorList.map((floor, index) => {
209
                      return (
210
                        <Select.Item value={floor.id} label={floor.label} />
211
                      );
212
                    })}
213
                  </Select>
214
215
                  {/* Room */}
216
217
                  < Select
218
                    mt={2.5}
219
                    ml={2.5}
220
                    mr={2.5}
221 7a3ad946 Fantič
222 d26c4168 Fantič
                    isDisabled={(selectedFloor && selectedFloor.roomList && selectedFloor.roomList.length) ? false : true}
223
224
                    placeholder={"Room"}
225
                    selectedValue={selectedRoom?.id.toString()}
226
                    onValueChange={(value: string) => selectRoom(parseInt(value))}
227
                    variant="rounded"
228
                  >
229
                    {selectedFloor?.roomList?.map((room, index) => {
230
                      if (room.room_list) {
231 7a3ad946 Fantič
                        return (
232 d26c4168 Fantič
                          <Select.Item value={room.id.toString()} label={room.label} />
233 7a3ad946 Fantič
                        );
234 d26c4168 Fantič
                      }
235
                    })}
236
                  </Select>
237 a6999074 Fantič
238 d26c4168 Fantič
                  {/* Place */}
239
                  <Select
240
                    mt={2.5}
241
                    ml={2.5}
242
                    mr={2.5}
243 7a3ad946 Fantič
244 d26c4168 Fantič
                    isDisabled={(selectedRoom && selectedRoom.places && selectedRoom.places.length > 0) ? false : true}
245
                    placeholder={"Place"}
246
                    selectedValue={selectedPlace?.id.toString()}
247
                    onValueChange={(value: string) => selectPlace(parseInt(value))}
248
                    variant="rounded"
249
                  >
250
                    {selectedRoom?.places?.map((place, index) => {
251
                      return (
252
                        <Select.Item value={place.id.toString()} label={place.label} />
253
                      );
254
                    })}
255
                  </Select>
256
257
                  {/* Filter */}
258
                  <Flex direction="row" alignItems="center" justify="flex-end"
259
                    mt={2.5}
260
                    ml={2.5}
261
                    mr={3}
262
                  >
263
                    <Button
264
                      startIcon={
265
                        <CloseIcon size="xs" />
266
                      }
267
                      onPress={clearForm}
268
                      variant="subtle"
269
                      color="secondary.500"
270
                      mr={2}
271
                      borderRadius={10}
272
                      size={"sm"}
273 5cee436e Fantič
                    >
274 d26c4168 Fantič
                      Reset
275
                    </Button>
276
                    <Button
277
                      onPress={() => {
278
                        if (selectedRoom && !selectedPlace) {
279
                          searchSubmit(selectedRoom.id)
280 5cee436e Fantič
                        }
281 d26c4168 Fantič
                        else if (selectedRoom && selectedPlace) {
282
                          searchSubmit(selectedRoom.id, selectedPlace.id)
283 5cee436e Fantič
                        }
284
285 d26c4168 Fantič
                      }}
286
                      backgroundColor={"#654B07"}
287
                      variant="subtle"
288
                      borderRadius={10}
289
                      size={"sm"}
290
                    >
291
                      <Text color="white" fontSize={11}>
292
                        Search
293
                      </Text>
294
                    </Button>
295
                  </Flex>
296
                </>
297
            }
298
299
            {/* Plan */}
300
            {castlePlanShown && selectedFloor && !floorListLoading && (
301
              floorMapImageLoading ?
302
                <LoadingBox text="Loading castle plan" />
303
                :
304
                floorMapImage &&
305
                <Box
306
                  mt={2.5}
307
                  ml={2.5}
308
                  mr={2.5}
309
                  height={Dimensions.get("window").height - 350}
310
                  onTouchStart={() => setIsInteractingWithCastlePlan(true)}
311
                  onTouchEnd={() => setIsInteractingWithCastlePlan(true)}>
312
                  <CastlePlanView mapImage={floorMapImage} selectedRoom={selectedRoom} roomList={selectedFloor.roomList} height={Dimensions.get("window").height - 350}
313
                    setSelectedRoom={(room: Room) => {
314
                      selectRoom(room.id)
315
                    }}
316
                    fullScreenMode={false}
317
                  />
318
                </Box>
319
            )
320
            }
321
322
            {/* Item List */}
323
            <>
324
              {!castlePlanShown && (
325
                inventoriesLoading ?
326
                  <LoadingBox text="Loading available inventories..." />
327 7a3ad946 Fantič
                  :
328 d26c4168 Fantič
                  <Box mt={5} ml={2.5} mr={2.5}>
329
                    <ListView
330
331
                      navigation={navigation}
332
                      hideHeaderText
333
334
                      inventories={inventories}
335
                      numOfResults={numberOfResults}
336
337
                      data={data}
338
                      loadedPages={pagination ?? {}}
339
                      inventoriesDataLoading={dataLoading ?? {}}
340
                      handleLoadMoreItems={(inventoryName: string, cursor: number) => {
341
                        dispatch(getPlanItems({ cursor: cursor, inventory: inventoryName, room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
342 36ede89c Fantič
                      }}
343
                    />
344 7a3ad946 Fantič
                  </Box>
345
              )
346 5cee436e Fantič
              }
347 d26c4168 Fantič
            </>
348
349
          </VStack>
350
        </ScrollView>
351
        {/* item notes switch tab */}
352
        <HStack alignItems="center">
353
          <Button
354
            variant={"unstyled"}
355
            w="50%"
356
            onPress={() => { setCastlePlanShown(true) }}
357
          >
358
            <VStack alignItems={"center"}>
359
              <Text bold={castlePlanShown} mb={castlePlanShown ? undefined : 2}>
360
                Castle
361
              </Text>
362
              {castlePlanShown && <Divider borderWidth={1} width={60} mt={2} />}
363 7a3ad946 Fantič
            </VStack>
364 d26c4168 Fantič
          </Button>
365
          <Button
366
            variant={"unstyled"}
367
            w="50%"
368
            onPress={() => { setCastlePlanShown(false) }}
369
          >
370
            <VStack alignItems={"center"}>
371
              <Text bold={!castlePlanShown} mb={!castlePlanShown ? undefined : 2}>
372
                Results
373
              </Text>
374
              {!castlePlanShown && <Divider borderWidth={1} width={60} mt={2} />}
375
            </VStack>
376
          </Button>
377
        </HStack>
378
      </Box>
379 5cee436e Fantič
    </Box>
380 c2c8470e Fantič
  );
381
}
382
383
export default PlanViewPage;