Projekt

Obecné

Profil

Stáhnout (11.9 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 d5dd3956 Michal Schwob
import { RootStackParamList } from "./Navigation"
8
import { Box, CloseIcon, Select, useToast, Button, Flex, Text, VStack, ScrollView, 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 a6999074 Fantič
import ListView from "../components/listView/ListView"
13 aac857cf Fantič
import CastlePlanView from "../components/plan/CastlePlanView"
14 c2c8470e Fantič
15 7a3ad946 Fantič
import { Dimensions } from 'react-native';
16 f4af30c8 Fantič
import { login } from "../stores/actions/userThunks"
17 7a3ad946 Fantič
18 d5dd3956 Michal Schwob
const PlanViewPage = ({ route, navigation }: DrawerScreenProps<RootStackParamList, 'Plan'>) => {
19 c2c8470e Fantič
20 a6999074 Fantič
  const dispatch = useDispatch<AppDispatch>()
21 c2c8470e Fantič
22 160b7073 Fantič
  // Route: set selected room / place from 
23
  useEffect(() => {
24
    console.log("dispatching get floor list")
25
    dispatch(getFloorList())
26
  }, [])
27 eb8efa3f Fantič
28 9641b62f Fantič
  const DEFAULT_FLOOR = "first_floor"
29 c2c8470e Fantič
30 7a3ad946 Fantič
  const [castlePlanShown, setCastlePlanShown] = useState<boolean>(true)
31
32 9641b62f Fantič
  const [selectedFloor, setSelectedFloor] = useState<Floor | undefined>(undefined)
33
  const [selectedRoom, setSelectedRoom] = useState<Room | undefined>(undefined)
34
  const [selectedPlace, setSelectedPlace] = useState<Place | undefined>(undefined)
35 c2c8470e Fantič
36 d26c4168 Fantič
  const [isInteractingWithCastlePlan, setIsInteractingWithCastlePlan] = useState(false)
37
38 28ab969f Fantič
39 a6999074 Fantič
  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 c2c8470e Fantič
44 a6999074 Fantič
  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 c2c8470e Fantič
50 aac857cf Fantič
  const floorMapImage = useSelector((state: RootState) => state.planViewState.mapImage)
51
  const floorMapImageLoading = useSelector((state: RootState) => state.planViewState.mapImageLoading)
52
53 c2c8470e Fantič
  const toast = useToast();
54
55 9641b62f Fantič
  useEffect(() => {
56
    if (floorList && !selectedFloor) {
57 a6999074 Fantič
58 f8083631 Fantič
      if (route.params && route.params.roomId) {
59
60 723e4dda Michal Schwob
        selectRoom(route.params?.roomId)
61 160b7073 Fantič
62 f8083631 Fantič
        if (route.params.placeId) {
63
          selectPlace(route.params.placeId)
64
        }
65 160b7073 Fantič
66 d0870262 Fantič
        
67
        dispatch(getPlanInventories({ room: route.params.roomId, place: route.params.placeId }))
68
69 f8083631 Fantič
      }
70 160b7073 Fantič
      else {
71 9641b62f Fantič
        selectFloor(DEFAULT_FLOOR)
72 f8083631 Fantič
      }
73 9641b62f Fantič
    }
74 723e4dda Michal Schwob
  }, [floorList, route.params?.roomId, route.params?.placeId])
75 9641b62f Fantič
76 160b7073 Fantič
  useEffect(() => {
77 a6999074 Fantič
    if (floorList) {
78
      if (!inventoriesLoading) {
79
        dispatch(getPlanInventories({ room: selectedRoom?.id ?? 0, place: selectedPlace?.id }))
80 160b7073 Fantič
      }
81
    }
82
  }, [selectedPlace, selectedRoom])
83
84 aac857cf Fantič
  useEffect(() => {
85
    if (selectedFloor) {
86
      console.log("Dispatching getFloorImage " + selectedFloor.id)
87
      dispatch(getPlanFloorImage(selectedFloor.id))
88
    }
89
  }, [selectedFloor])
90
91 160b7073 Fantič
92 c2c8470e Fantič
  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 a6999074 Fantič
  const searchSubmit = (roomId: number, placeId?: number) => {
108 90af86f9 Fantič
    log.debug("PlanView", "searchSubmit")
109
110 160b7073 Fantič
    console.log("searching " + roomId + ", " + placeId)
111
112 a6999074 Fantič
    dispatch(getPlanInventories({ room: roomId, place: placeId }))
113 90af86f9 Fantič
  }
114
115 9641b62f Fantič
  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 90af86f9 Fantič
  const clearForm = () => {
167
    log.debug("PlanView", "clearForm")
168
    setSelectedPlace(undefined)
169 a6999074 Fantič
    setSelectedRoom(undefined)
170
    selectFloor(DEFAULT_FLOOR)
171 90af86f9 Fantič
  }
172 c2c8470e Fantič
173
  const onBackPressed = () => {
174
    log.debug("back pressed")
175
    navigation.goBack();
176
  }
177
178
  return (
179 9abf01c3 Michal Schwob
    <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 d26c4168 Fantič
196 9abf01c3 Michal Schwob
                  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 d26c4168 Fantič
215 9abf01c3 Michal Schwob
                  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 d26c4168 Fantič
                      return (
225 9abf01c3 Michal Schwob
                        <Select.Item value={room.id.toString()} label={room.label} />
226 d26c4168 Fantič
                      );
227 9abf01c3 Michal Schwob
                    }
228
                  })}
229
                </Select>
230 d26c4168 Fantič
231 9abf01c3 Michal Schwob
                {/* Place */}
232
                <Select
233
                  mt={2.5}
234
                  ml={2.5}
235
                  mr={2.5}
236 d26c4168 Fantič
237 9abf01c3 Michal Schwob
                  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 d26c4168 Fantič
                  >
267 9abf01c3 Michal Schwob
                    Reset
268
                  </Button>
269
                  <Button
270
                    onPress={() => {
271
                      if (selectedRoom && !selectedPlace) {
272
                        searchSubmit(selectedRoom.id)
273 d26c4168 Fantič
                      }
274 9abf01c3 Michal Schwob
                      else if (selectedRoom && selectedPlace) {
275
                        searchSubmit(selectedRoom.id, selectedPlace.id)
276 d26c4168 Fantič
                      }
277
278 9abf01c3 Michal Schwob
                    }}
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 d26c4168 Fantič
                :
321 9abf01c3 Michal Schwob
                <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 d26c4168 Fantič
                    }}
336
                  />
337
                </Box>
338
            )
339
            }
340 9abf01c3 Michal Schwob
          </>
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 d26c4168 Fantič
          </VStack>
369 9abf01c3 Michal Schwob
        </Button>
370
      </HStack>
371 5cee436e Fantič
    </Box>
372 c2c8470e Fantič
  );
373
}
374
375
export default PlanViewPage;