Projekt

Obecné

Profil

Stáhnout (7.85 KB) Statistiky
| Větev: | Tag: | Revize:
1
import React, { useCallback, useEffect, useState } from "react"
2
import { log } from "../logging/logger"
3
import { DrawerScreenProps } from "@react-navigation/drawer"
4
import { Box, Button, ChevronDownIcon, ChevronUpIcon, Flex, HStack, MinusIcon, Popover, Switch, Text, VStack, useToast } from "native-base"
5
import { SortOptions } from "../types/general"
6
import { Note } from "../types/note"
7
import NotesListView from "../components/notes/NotesListView"
8
import { useDispatch, useSelector } from "react-redux"
9
import { AppDispatch, RootState } from "../stores/store"
10
import LoadingBox from "../components/loading/LoadingBox"
11
import { createNote, getAllNotes } from "../stores/actions/notesThunks"
12
import { RootStackParamList } from "./Navigation"
13
import { ErrorToast } from "../components/toast/ErrorToast"
14
import { InfoToast } from "../components/toast/InfoToast"
15

    
16
import { Dimensions } from "react-native";
17

    
18
const NotesViewPage = ({ navigation }: DrawerScreenProps<RootStackParamList, 'Notes'>) => {
19

    
20
  const { notes, notesLoading, requestPending, triggerRefresh } = useSelector((state: RootState) => state.noteViewState);
21

    
22
  const dispatch = useDispatch<AppDispatch>();
23

    
24
  const [isSortOpen, setIsSortOpen] = useState(false);
25

    
26
  const [myCommentsCheck, setMyCommentsCheck] = useState(false);
27
  const [generalCommentsCheck, setGeneralCommentsCheck] = useState(true);
28

    
29
  const lastError = useSelector((state: RootState) => state.noteViewState.lastError)
30
  const toast = useToast();
31

    
32
  useEffect(() => {
33
    if (lastError) {
34
      toast.closeAll()
35
      toast.show({
36
        render: ({
37
          id
38
        }) => {
39
          return <ErrorToast headerText={"Error"} text={lastError} onClose={() => toast.close(id)} />;
40
        },
41
        duration: 3000
42
      });
43
    }
44
  }, [lastError])
45

    
46
  const [sortSettings, setSortSettings] = useState({
47
    items: SortOptions.None,
48
    date: SortOptions.None
49
  });
50

    
51
  console.log(sortSettings)
52

    
53
  const handleSortChanged = useCallback((key: "items" | "date", sortSettings: any) => {
54
    let currentState = sortSettings[key];
55
    let otherKey = "items"
56

    
57
    if (key == "items") {
58
      otherKey = "date"
59
    }
60

    
61
    if (currentState == SortOptions.None) {
62
      setSortSettings({
63
        ...sortSettings,
64
        [key]: SortOptions.Asc,
65
        [otherKey]: SortOptions.None
66
      })
67
    }
68
    else if (currentState == SortOptions.Asc) {
69
      setSortSettings({
70
        ...sortSettings,
71
        [key]: SortOptions.Desc,
72
        [otherKey]: SortOptions.None
73
      })
74
    }
75
    else {
76
      setSortSettings({
77
        ...sortSettings,
78
        [key]: SortOptions.None,
79
        [otherKey]: SortOptions.None
80
      })
81
    }
82
  }, [setSortSettings]);
83

    
84
  const getSortIcon = (sortOption: SortOptions, size: string, color?: string) => {
85
    switch (sortOption) {
86
      case SortOptions.Asc:
87
        return <ChevronUpIcon size={size} color={color} />;
88
      case SortOptions.Desc:
89
        return <ChevronDownIcon size={size} color={color} />;
90
      default:
91
        return <MinusIcon size={size} color={color} />;
92
    }
93
  };
94

    
95
  // trigger refresh on triggerRefresh increment
96
  useEffect(() => {
97
    log.debug("NotesViewPage", "useEffect", "getNotes");
98
    getNotes();
99
  }, [triggerRefresh])
100

    
101
  // general comments check changed
102
  useEffect(() => {
103
    if (!notesLoading) {
104
      log.debug("NotesViewPage", "useEffect", "getNotes");
105
      getNotes();
106
    }
107
  }, [generalCommentsCheck, myCommentsCheck])
108

    
109

    
110
  const getNotes = useCallback(() => {
111
    dispatch(getAllNotes({
112
      myComments: myCommentsCheck,
113
      generalComments: generalCommentsCheck,
114
      sortOptions: sortSettings
115
    }));
116
  }, [myCommentsCheck, generalCommentsCheck, sortSettings]);
117

    
118

    
119
  const handleCreateComment = useCallback((newComment: string, replyingTo: { messageId: string; userName: string } | null) => {
120
    console.log(newComment, replyingTo)
121

    
122
    if (!requestPending) {
123
      // creating new comment
124
      toast.show({
125
        render: ({
126
          id
127
        }) => {
128
          return <InfoToast text={"Adding note"} onClose={() => toast.close(id)} />;
129
        },
130
        duration: 2000
131
      });
132
      if (replyingTo != null) {
133
        dispatch(createNote({
134
          newNote: { note: newComment, reply_to: replyingTo.messageId } as Note
135
        }))
136
      }
137
      else {
138
        dispatch(createNote({
139
          newNote: { note: newComment } as Note
140
        }))
141
      }
142
    }
143
  }, [dispatch, createNote]);
144

    
145

    
146

    
147
  return (
148
    <Box>
149
      <VStack>
150
        <HStack height={75} justifyContent="space-between" paddingLeft={2.5} paddingRight={2.5} marginTop={2.5}>
151
          <Box justifyContent={"center"}>
152
            <Popover // @ts-ignore
153
              trigger={triggerProps => {
154
                return <Button width={150} backgroundColor="#F4DFAB" {...triggerProps} onPress={() => setIsSortOpen(true)}
155
                  borderRadius={7}
156
                  rightIcon={(sortSettings.date != SortOptions.None || sortSettings.items != SortOptions.None) ? (getSortIcon(sortSettings.date != SortOptions.None ? sortSettings.date : sortSettings.items, "xs", "#654B07")) : undefined}
157
                >
158
                  <Text fontSize={14} color="#654B07">
159
                    Sort {(sortSettings.date != SortOptions.None || sortSettings.items != SortOptions.None) ? (sortSettings.date != SortOptions.None ? "by date" : "by items") : ""}
160
                  </Text>
161
                </Button>;
162
              }} isOpen={isSortOpen} onClose={() => setIsSortOpen(!isSortOpen)}>
163
              <Popover.Content w="48">
164
                <Popover.Arrow />
165
                <Popover.CloseButton onPress={() => setIsSortOpen(false)} />
166
                <Popover.Header><Text fontSize={"md"} color="#654B07">Sort Options</Text></Popover.Header>
167
                <Popover.Body>
168
                  <VStack>
169
                    <Button size="md" variant="outline" onPress={() => handleSortChanged("items", sortSettings)}
170
                      rightIcon={getSortIcon(sortSettings.items, "sm", "#654B07")}
171
                    >
172
                      Items</Button>
173
                    <Button size="md" variant="outline" marginTop={"5%"} onPress={() => handleSortChanged("date", sortSettings)}
174
                      rightIcon={getSortIcon(sortSettings.date, "sm", "#654B07")}>
175
                      Date</Button>
176
                  </VStack>
177
                </Popover.Body>
178
                <Popover.Footer justifyContent="flex-end">
179
                  <Button.Group space={2}>
180
                    <Button colorScheme="coolGray" variant="ghost" onPress={() => setIsSortOpen(false)}>
181
                      Cancel
182
                    </Button>
183
                    <Button backgroundColor={"#F4DFAB"} onPress={() => { setIsSortOpen(false); getNotes() }}>
184
                      <Text color="#654B07">
185
                        Save
186
                      </Text>
187
                    </Button>
188
                  </Button.Group>
189
                </Popover.Footer>
190
              </Popover.Content>
191
            </Popover>
192
          </Box>
193

    
194
          <VStack space={0.5}>
195
            <Flex direction="row" alignItems="center" justify="flex-end" height={35}>
196
              <Text>My comments</Text>
197
              <Switch isChecked={myCommentsCheck} onValueChange={() => { if (!notesLoading) setMyCommentsCheck(!myCommentsCheck) }} size="md" />
198
            </Flex>
199
            <Flex direction="row" alignItems="center" justify="flex-end" height={35}>
200
              <Text>General comments</Text>
201
              <Switch isChecked={generalCommentsCheck} onValueChange={() => { if (!notesLoading) setGeneralCommentsCheck(!generalCommentsCheck) }} size="md" />
202
            </Flex>
203
          </VStack>
204
        </HStack>
205
        {
206
          notesLoading ? (
207
            <LoadingBox text="Loading notes" />
208
          )
209
            :
210
            (<NotesListView height={Dimensions.get('window').height - 70 - 160} notes={notes} navigation={navigation} handleCreateComment={handleCreateComment} requestPending={requestPending} />)
211
        }
212

    
213

    
214
      </VStack>
215
    </Box>
216
  );
217
}
218

    
219
export default NotesViewPage;
(6-6/8)