Projekt

Obecné

Profil

Stáhnout (7.93 KB) Statistiky
| Větev: | Tag: | Revize:
1
import React, { useEffect, useState } from "react"
2
import { log } from "../logging/logger"
3
import { DrawerScreenProps } from "@react-navigation/drawer"
4
import { RootDrawerParamList } from "../components/Navigation"
5
import { Box, Button, ChevronDownIcon, ChevronUpIcon, CloseIcon, Flex, HStack, Icon, IconButton, MinusIcon, Popover, Pressable, ScrollView, Switch, Text, TextArea, VStack } from "native-base"
6
import { SortOptions } from "../types/general"
7
import { Note } from "../types/note"
8
import NotesListView from "../components/notes/NotesListView"
9
import { G, Path } from "react-native-svg"
10
import { MessageIcon } from "../components/general/Icons"
11
import { ConfirmDialog } from "../components/general/Dialogs"
12
import { useDispatch, useSelector } from "react-redux"
13
import { AppDispatch, RootState } from "../stores/store"
14
import LoadingBox from "../components/loading/LoadingBox"
15
import { createNote, deleteNote, getAllNotes, updateNote } from "../stores/actions/notesThunks"
16
import { login } from "../stores/actions/userThunks"
17
const NotesViewPage = ({ route, navigation }: DrawerScreenProps<RootDrawerParamList, 'Notes'>) => {
18

    
19
  const { notes, notesLoading, requestPending, triggerRefresh } = useSelector((state: RootState) => state.noteViewState)
20
  
21
  const dispatch = useDispatch<AppDispatch>();
22

    
23
  const [isSortOpen, setIsSortOpen] = useState(false);
24
  
25
  const [newComment, setNewComment] = useState<string>("");
26

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

    
30
  const [replyingTo, setReplyingTo] = useState<{ messageId: string; userName: string } | null>(null);
31

    
32
  const cancelRef = React.useRef(null);
33

    
34
  const [confirmDialog, setConfirmDialog] = React.useState<{
35
    headerText?: string;
36
    bodyText?: string;
37
    confirmText?: string;
38
    confirmColor?: string;
39
    cancelRef?: any;
40
    onClose?: () => void;
41
    onSubmit?: () => void;
42
  } | null>(null);
43

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

    
49
  const handleSortChanged = (key: "items" | "date") => {
50
    let currentState = sortSettings[key];
51
    if (currentState == SortOptions.None) {
52
      setSortSettings({
53
        ...sortSettings,
54
        [key]: SortOptions.Asc
55
      })
56
    }
57
    else if (currentState == SortOptions.Asc) {
58
      setSortSettings({
59
        ...sortSettings,
60
        [key]: SortOptions.Desc
61
      })
62
    }
63
    else {
64
      setSortSettings({
65
        ...sortSettings,
66
        [key]: SortOptions.None
67
      })
68
    }
69
  }
70

    
71
  const getSortIcon = (sortOption: SortOptions, size: string) => {
72
    switch (sortOption) {
73
      case SortOptions.Asc:
74
        return <ChevronUpIcon size={size} />;
75
      case SortOptions.Desc:
76
        return <ChevronDownIcon size={size} />;
77
      default:
78
        return <MinusIcon size={size} />;
79
    }
80
  };
81

    
82
  // trigger refresh on triggerRefresh increment
83
  useEffect(() => {
84
    log.debug("NotesViewPage", "useEffect", "getNotes");
85
    getNotes();
86
    
87
    setNewComment("");
88
    setReplyingTo(null);
89
  }, [triggerRefresh])
90

    
91
  // general comments check changed
92
  useEffect(() => {
93
    if(!notesLoading){
94
      log.debug("NotesViewPage", "useEffect", "getNotes");
95
      getNotes();
96
    }
97
  }, [generalCommentsCheck, myCommentsCheck])
98

    
99

    
100
  const getNotes = () => {
101
    dispatch(getAllNotes({
102
      myComments: myCommentsCheck,
103
      generalComments: generalCommentsCheck,
104
      sortOptions: sortSettings
105
    }));
106
  }
107

    
108
  const handleReply = (messageId: string, userName: string) => {
109
    setReplyingTo({ messageId, userName })
110
  }
111

    
112
  const handleEdit = (note : Note) => {
113
    if(!requestPending)
114
      dispatch(updateNote(note));
115
  }
116

    
117
  const handleDelete = (messageId: string) => {
118
    if(!requestPending)
119
      dispatch(deleteNote({noteId: messageId}))
120
  }
121

    
122
  const handleCreateComment = () => {
123
    if(!requestPending){
124
      // creating new comment
125
      if(replyingTo != null){
126
        dispatch(createNote( {
127
          newNote: {note: newComment, reply_to: replyingTo.messageId} as Note
128
        }))
129
      }
130
      else{
131
        dispatch(createNote({
132
          newNote: {note: newComment} as Note
133
        }))
134
      }
135
    } 
136
  }
137

    
138
  return (
139
    <Box width="92%" marginLeft="5%">
140
      <VStack>
141
        <HStack marginTop="5%">
142
          <Box width="30%" justifyContent={"center"}>
143
            <Popover // @ts-ignore
144
              trigger={triggerProps => {
145
                return <Button colorScheme="primary" {...triggerProps} onPress={() => setIsSortOpen(true)}>
146
                  Sort Options
147
                </Button>;
148
              }} isOpen={isSortOpen} onClose={() => setIsSortOpen(!isSortOpen)}>
149
              <Popover.Content w="48">
150
                <Popover.Arrow />
151
                <Popover.CloseButton onPress={() => setIsSortOpen(false)} />
152
                <Popover.Header>Sort Options</Popover.Header>
153
                <Popover.Body>
154
                  <VStack>
155
                    <Button size="md" variant="outline" onPress={() => handleSortChanged("items")}
156
                      rightIcon={getSortIcon(sortSettings.items, "sm")}
157
                    >
158
                      Items</Button>
159
                    <Button size="md" variant="outline" marginTop={"5%"} onPress={() => handleSortChanged("date")}
160
                      rightIcon={getSortIcon(sortSettings.date, "sm")}>
161
                      Date</Button>
162
                  </VStack>
163
                </Popover.Body>
164
                <Popover.Footer justifyContent="flex-end">
165
                  <Button.Group space={2}>
166
                    <Button colorScheme="coolGray" variant="ghost" onPress={() => setIsSortOpen(false)}>
167
                      Cancel
168
                    </Button>
169
                    <Button colorScheme="success" onPress={() => { setIsSortOpen(false); getNotes() }}>
170
                      Save
171
                    </Button>
172
                  </Button.Group>
173
                </Popover.Footer>
174
              </Popover.Content>
175
            </Popover>
176
          </Box>
177
          <VStack width="70%" space="0">
178
            <Flex direction="row" alignItems="center" justify="flex-end">
179
              <Text>My comments</Text>
180
              <Switch isChecked={myCommentsCheck} onValueChange={() => {if(!notesLoading) setMyCommentsCheck(!myCommentsCheck)}} size="md" />
181
            </Flex>
182
            <Flex direction="row" alignItems="center" justify="flex-end" marginTop="-7.5%">
183
              <Text>General comments</Text>
184
              <Switch isChecked={generalCommentsCheck} onValueChange={() => {if(!notesLoading) setGeneralCommentsCheck(!generalCommentsCheck)}} size="md" />
185
            </Flex>
186
          </VStack>
187
        </HStack>
188
        <Box h={replyingTo != null ? "62.5%" : "67.5%"}>
189
          {
190
            notesLoading ? (<LoadingBox text="Loading notes"/>)
191
              :
192
              (<NotesListView notes={notes} handleReply={handleReply} handleDelete={handleDelete} handleEdit={handleEdit} setConfirmDialog={setConfirmDialog} navigation={navigation} />)
193
          }
194
        </Box>
195
        {replyingTo != null &&
196
          <Flex direction="row" alignItems="center" justify="flex-end" h="5%" marginRight="10%">
197
            <Text>Replying to {replyingTo.userName}</Text>
198
            <IconButton onPress={() => setReplyingTo(null)} size="sm" icon={<CloseIcon />} marginLeft="-1%">
199
            </IconButton>
200
          </Flex>
201
        }
202
        <HStack h={replyingTo != null ? "20%" : "15%"} marginTop={replyingTo != null ? "0%" : "5%"}>
203
          <TextArea placeholder="Add comment" width="90%" fontSize={14} value={newComment} onChangeText={setNewComment} autoCompleteType={undefined} ></TextArea>
204
          <VStack>
205
            <Box h={replyingTo != null ? "30%" : "45%"}></Box>
206
            <Box marginLeft="2">
207
              <Button onPress={handleCreateComment} startIcon={<MessageIcon color="#FFF" /> }></Button>
208
            </Box>
209
          </VStack>
210
        </HStack>
211
      </VStack>
212
      <ConfirmDialog {...confirmDialog} isShown={confirmDialog != null} cancelRef={cancelRef} />
213
    </Box>
214
  );
215
}
216

    
217
export default NotesViewPage;
(6-6/7)