@messenger-box/chakra-ui-inbox 0.0.1-alpha.168

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE +21 -0
  3. package/jest.config.js +9 -0
  4. package/lib/components/InboxMessage/ConversationItem.d.ts +11 -0
  5. package/lib/components/InboxMessage/ConversationItem.d.ts.map +1 -0
  6. package/lib/components/InboxMessage/ConversationItem.js +50 -0
  7. package/lib/components/InboxMessage/ConversationItem.js.map +1 -0
  8. package/lib/components/InboxMessage/LeftSidebar.d.ts +17 -0
  9. package/lib/components/InboxMessage/LeftSidebar.d.ts.map +1 -0
  10. package/lib/components/InboxMessage/LeftSidebar.js +107 -0
  11. package/lib/components/InboxMessage/LeftSidebar.js.map +1 -0
  12. package/lib/components/InboxMessage/MessageInput.d.ts +8 -0
  13. package/lib/components/InboxMessage/MessageInput.d.ts.map +1 -0
  14. package/lib/components/InboxMessage/MessageInput.js +45 -0
  15. package/lib/components/InboxMessage/MessageInput.js.map +1 -0
  16. package/lib/components/InboxMessage/Messages.d.ts +10 -0
  17. package/lib/components/InboxMessage/Messages.d.ts.map +1 -0
  18. package/lib/components/InboxMessage/Messages.js +42 -0
  19. package/lib/components/InboxMessage/Messages.js.map +1 -0
  20. package/lib/components/InboxMessage/Popover.d.ts +3 -0
  21. package/lib/components/InboxMessage/Popover.d.ts.map +1 -0
  22. package/lib/components/InboxMessage/UserModalContent.d.ts +3 -0
  23. package/lib/components/InboxMessage/UserModalContent.d.ts.map +1 -0
  24. package/lib/components/InboxMessage/index.d.ts +4 -0
  25. package/lib/components/InboxMessage/index.d.ts.map +1 -0
  26. package/lib/components/inbox/FilesList.d.ts +12 -0
  27. package/lib/components/inbox/FilesList.d.ts.map +1 -0
  28. package/lib/components/inbox/FilesList.js +7 -0
  29. package/lib/components/inbox/FilesList.js.map +1 -0
  30. package/lib/components/inbox/MessageItem.d.ts +17 -0
  31. package/lib/components/inbox/MessageItem.d.ts.map +1 -0
  32. package/lib/compute.d.ts +8 -0
  33. package/lib/compute.d.ts.map +1 -0
  34. package/lib/compute.js +19 -0
  35. package/lib/compute.js.map +1 -0
  36. package/lib/constants/index.d.ts +2 -0
  37. package/lib/constants/index.d.ts.map +1 -0
  38. package/lib/constants/index.js +5 -0
  39. package/lib/constants/index.js.map +1 -0
  40. package/lib/container/Inbox.d.ts +4 -0
  41. package/lib/container/Inbox.d.ts.map +1 -0
  42. package/lib/container/Inbox.js +169 -0
  43. package/lib/container/Inbox.js.map +1 -0
  44. package/lib/container/index.d.ts +3 -0
  45. package/lib/container/index.d.ts.map +1 -0
  46. package/lib/hooks/upload-file.d.ts +27 -0
  47. package/lib/hooks/upload-file.d.ts.map +1 -0
  48. package/lib/hooks/upload-file.js +56 -0
  49. package/lib/hooks/upload-file.js.map +1 -0
  50. package/lib/hooks/upload-filex.d.ts +11 -0
  51. package/lib/hooks/upload-filex.d.ts.map +1 -0
  52. package/lib/hooks/upload-filex.js +5 -0
  53. package/lib/hooks/upload-filex.js.map +1 -0
  54. package/lib/hooks/upload-msg-files.d.ts +3 -0
  55. package/lib/hooks/upload-msg-files.d.ts.map +1 -0
  56. package/lib/hooks/upload-msg-files.js +10 -0
  57. package/lib/hooks/upload-msg-files.js.map +1 -0
  58. package/lib/index.d.ts +2 -0
  59. package/lib/index.d.ts.map +1 -0
  60. package/lib/index.js +1 -0
  61. package/lib/index.js.map +1 -0
  62. package/lib/module.d.ts +4 -0
  63. package/lib/module.d.ts.map +1 -0
  64. package/lib/module.js +5 -0
  65. package/lib/module.js.map +1 -0
  66. package/package.json +79 -0
  67. package/rollup.config.js +32 -0
  68. package/src/components/InboxMessage/ConversationItem.tsx +98 -0
  69. package/src/components/InboxMessage/LeftSidebar.tsx +250 -0
  70. package/src/components/InboxMessage/MessageInput.tsx +148 -0
  71. package/src/components/InboxMessage/Messages.tsx +137 -0
  72. package/src/components/InboxMessage/Popover.tsx +56 -0
  73. package/src/components/InboxMessage/UserModalContent.tsx +52 -0
  74. package/src/components/InboxMessage/index.ts +3 -0
  75. package/src/components/inbox/FilesList.tsx +17 -0
  76. package/src/components/inbox/MessageItem.tsx +56 -0
  77. package/src/compute.tsx +33 -0
  78. package/src/constants/index.ts +4 -0
  79. package/src/container/Inbox.tsx +283 -0
  80. package/src/container/index.ts +3 -0
  81. package/src/hooks/upload-file.tsx +92 -0
  82. package/src/hooks/upload-filex.tsx +22 -0
  83. package/src/hooks/upload-msg-files.tsx +14 -0
  84. package/src/index.ts +1 -0
  85. package/src/module.tsx +9 -0
  86. package/tsconfig.json +26 -0
  87. package/webpack.config.js +97 -0
@@ -0,0 +1,250 @@
1
+ import { SearchIcon } from '@chakra-ui/icons';
2
+ import {
3
+ Button,
4
+ Avatar,
5
+ Box,
6
+ Heading,
7
+ Icon,
8
+ Input,
9
+ InputGroup,
10
+ InputRightElement,
11
+ Tab,
12
+ TabList,
13
+ TabPanel,
14
+ TabPanels,
15
+ Tabs,
16
+ useColorModeValue,
17
+ } from '@chakra-ui/react';
18
+ import { GoSettings } from '@react-icons/all-files/go/GoSettings';
19
+ import React, { useEffect, useState } from 'react';
20
+ import { ConversationItem } from './ConversationItem';
21
+
22
+ type LeftSidebarProps = {
23
+ allChannels: any;
24
+ allChannelsLoading: boolean;
25
+ userChannels: any;
26
+ userChannelsLoading: boolean;
27
+ currentUser: any;
28
+ users?: any[];
29
+ handleSelectChannel: (channel: any) => void;
30
+ clearMessages: () => void;
31
+ selectedChannelId?: any;
32
+ channelToTop: number;
33
+ getChannelsRefetch: any;
34
+ };
35
+
36
+ export const LeftSidebar = (props: LeftSidebarProps) => {
37
+ const {
38
+ currentUser,
39
+ handleSelectChannel,
40
+ clearMessages,
41
+ users,
42
+ allChannels,
43
+ allChannelsLoading,
44
+ channelToTop,
45
+ userChannels,
46
+ userChannelsLoading,
47
+ getChannelsRefetch,
48
+ selectedChannelId,
49
+ } = props;
50
+ const [hostChannels, setHostChannels] = useState([]);
51
+ const [guestChannels, setGuestChannels] = useState([]);
52
+ const [hostKeyword, setHostKeyword] = useState('');
53
+ const [guestKeyword, setGuestKeyword] = useState('');
54
+ const [tabIndex, setTabIndex] = useState(0);
55
+
56
+ useEffect(() => {
57
+ if (channelToTop) {
58
+ }
59
+ }, [channelToTop]);
60
+
61
+ useEffect(() => {
62
+ if (!userChannelsLoading && userChannels.length !== 0) {
63
+ let fChannels = [];
64
+ let diChal = [];
65
+ // if (currentUser?.id !== '' && !allChannelsLoading) {
66
+ // console.log(props);
67
+ let uc = [];
68
+ userChannels?.channelsByUser?.forEach((u) => uc.push(u.id)); // id of user's channel
69
+ let ac = [];
70
+ allChannels?.channels?.forEach((a) => ac.push(a.id)); // id of all channel
71
+ diChal = ac.filter((t) => !uc.includes(t)); // id of other's channel
72
+ allChannels?.channels?.filter((dc) => {
73
+ if (diChal.includes(dc.id)) {
74
+ dc.members.forEach((m) => {
75
+ if (m.user === currentUser?.id) {
76
+ fChannels.push(dc);
77
+ }
78
+ });
79
+ }
80
+ });
81
+ // }
82
+ console.log(props);
83
+ let chls = [...(userChannels?.channelsByUser ?? []), ...fChannels];
84
+ const tempGuestChannels = [
85
+ ...(chls && chls.length && currentUser
86
+ ? chls?.filter(
87
+ (chl) =>
88
+ chl.type === 'DIRECT' &&
89
+ chl?.displayName !== 'admin (you)' &&
90
+ chl?.displayName !== 'surveybot' &&
91
+ chl.members[0].user == currentUser?.id,
92
+ )
93
+ : []),
94
+ ];
95
+ setGuestChannels(tempGuestChannels);
96
+ const tempHostChannels = [
97
+ ...(chls && chls.length && currentUser
98
+ ? chls?.filter(
99
+ (chl) =>
100
+ chl.type === 'DIRECT' &&
101
+ chl?.displayName !== 'admin (you)' &&
102
+ chl?.displayName !== 'surveybot' &&
103
+ chl.members[0].user != currentUser?.id,
104
+ )
105
+ : []),
106
+ ];
107
+ setHostChannels(tempHostChannels);
108
+ const isHost = tempHostChannels.findIndex((chl) => chl.id == selectedChannelId);
109
+ const isGuest = tempGuestChannels.findIndex((chl) => chl.id == selectedChannelId);
110
+ if (isHost == -1 && isGuest == -1) getChannelsRefetch();
111
+ // setHostChannels([...fChannels.filter((chl) => chl.type === 'DIRECT')]);
112
+ }
113
+ }, [allChannels, allChannelsLoading, userChannels, userChannelsLoading, currentUser, getChannelsRefetch]);
114
+
115
+ useEffect(() => {
116
+ if (selectedChannelId && hostChannels && hostChannels.length !== 0) {
117
+ const chlIndex = hostChannels.findIndex((chl) => chl.id == selectedChannelId);
118
+ if (chlIndex > -1) setTabIndex(0);
119
+ }
120
+ if (selectedChannelId && guestChannels && guestChannels.length !== 0) {
121
+ const chlIndex = guestChannels.findIndex((chl) => chl.id == selectedChannelId);
122
+ if (chlIndex > -1) setTabIndex(1);
123
+ }
124
+ }, [hostChannels, guestChannels, selectedChannelId]);
125
+
126
+ const handleTabChange = (index: number) => {
127
+ setTabIndex(index);
128
+ if ((index == 0 && hostChannels.length == 0) || (index == 1 && guestChannels.length == 0)) {
129
+ clearMessages();
130
+ return;
131
+ }
132
+ handleSelectChannel(index == 0 ? hostChannels[0].id : guestChannels[0].id);
133
+ };
134
+
135
+ return (
136
+ <Box w="100%" p="4" borderRightWidth="1px" borderRightColor="gray.300">
137
+ <Tabs index={tabIndex} onChange={handleTabChange}>
138
+ <TabList w="100%">
139
+ <Tab w="50%" fontSize="24px" justifyContent={'flex-start'}>
140
+ Host
141
+ </Tab>
142
+ <Tab w="50%" fontSize="24px" justifyContent={'flex-start'}>
143
+ Guest
144
+ </Tab>
145
+ </TabList>
146
+ <TabPanels>
147
+ <TabPanel p="0" pt="1">
148
+ <SearchInput keyword={hostKeyword} setKeyword={setHostKeyword} />
149
+ {currentUser &&
150
+ hostChannels &&
151
+ hostChannels.length !== 0 &&
152
+ hostChannels.map((channel, index) => (
153
+ <ConversationItem
154
+ key={`conv_channel_${channel.id}`}
155
+ filter={hostKeyword}
156
+ channel={channel}
157
+ currentUser={currentUser}
158
+ handleSelectChannel={handleSelectChannel}
159
+ users={users}
160
+ selectedChannelId={selectedChannelId}
161
+ showBorder={index == hostChannels.length - 1 ? false : true}
162
+ />
163
+ ))}
164
+ </TabPanel>
165
+ <TabPanel p="0" pt="1">
166
+ <SearchInput keyword={guestKeyword} setKeyword={setGuestKeyword} />
167
+ {currentUser &&
168
+ guestChannels &&
169
+ guestChannels.length !== 0 &&
170
+ guestChannels.map((channel, index) => (
171
+ <ConversationItem
172
+ key={`conv_channel_${channel.id}`}
173
+ filter={guestKeyword}
174
+ channel={channel}
175
+ currentUser={currentUser}
176
+ handleSelectChannel={handleSelectChannel}
177
+ users={users}
178
+ selectedChannelId={selectedChannelId}
179
+ showBorder={index == guestChannels.length - 1 ? false : true}
180
+ />
181
+ ))}
182
+ </TabPanel>
183
+ </TabPanels>
184
+ </Tabs>
185
+ </Box>
186
+ );
187
+ };
188
+ const SearchInput = ({ keyword, setKeyword }: any) => {
189
+ return (
190
+ <Box w="100%" d="flex" alignItems={'center'} my="15px">
191
+ <InputGroup size="md">
192
+ <Input
193
+ pr="4.5rem"
194
+ pl="2rem"
195
+ type="text"
196
+ placeholder="Search Inbox"
197
+ display="flex"
198
+ alignItems="center"
199
+ color="gray.500"
200
+ backgroundColor="white"
201
+ borderRadius="30px"
202
+ borderWidth="1px"
203
+ borderColor="gray.200"
204
+ height="60px"
205
+ value={keyword}
206
+ onChange={(e) => setKeyword(e.target.value)}
207
+ fontWeight="medium"
208
+ />
209
+ <InputRightElement width="60px" height="100%">
210
+ <Button
211
+ alignSelf="center"
212
+ size="lg"
213
+ minW="50px"
214
+ w="50px"
215
+ h="50px"
216
+ borderRadius="24px"
217
+ alignItems="center"
218
+ justifyContent="center"
219
+ borderWidth="1px"
220
+ borderColor="yellow.400"
221
+ backgroundColor="yellow.400"
222
+ color="white"
223
+ d="flex"
224
+ onClick={() => {}}
225
+ >
226
+ <SearchIcon w="1.4rem" h="1.4rem" />
227
+ </Button>
228
+ </InputRightElement>
229
+ </InputGroup>
230
+ <Button
231
+ alignSelf="center"
232
+ size="lg"
233
+ minW="50px"
234
+ w="50px"
235
+ h="50px"
236
+ marginLeft="5px"
237
+ borderRadius="30px"
238
+ alignItems="center"
239
+ justifyContent="center"
240
+ backgroundColor="white"
241
+ borderWidth="1px"
242
+ borderColor="gray.200"
243
+ color="#333"
244
+ d="flex"
245
+ >
246
+ <Icon as={GoSettings} w="1.4rem" h="1.4rem" />
247
+ </Button>
248
+ </Box>
249
+ );
250
+ };
@@ -0,0 +1,148 @@
1
+ import {
2
+ Box,
3
+ Button,
4
+ Image,
5
+ InputGroup,
6
+ InputLeftElement,
7
+ InputRightElement,
8
+ Textarea,
9
+ Tooltip,
10
+ } from '@chakra-ui/react';
11
+ import { BiImage } from '@react-icons/all-files/bi/BiImage';
12
+ import { fi } from 'date-fns/locale';
13
+ import React, { useMemo, useRef, useState } from 'react';
14
+ import { logoURL } from '../../constants/index';
15
+ import { FilesList } from '../inbox/FilesList';
16
+
17
+ type MessageInputProps = {
18
+ channelId: string;
19
+ handleSend: (message: string, files?: File[]) => void;
20
+ };
21
+
22
+ export const MessageInput = ({ channelId, handleSend: handleSendProp }: MessageInputProps) => {
23
+ const files$ = useRef<HTMLInputElement>();
24
+ const [files, setFiles] = useState([]);
25
+ const [message, setMessage] = useState('');
26
+ const [height, setHeight] = useState<any>('40px');
27
+ const handleSend = () => {
28
+ handleSendProp(message, files);
29
+
30
+ setMessage('');
31
+ setFiles([]);
32
+ };
33
+
34
+ const handleKeyDown = (e) => {
35
+ const keyCode = e.which || e.keyCode;
36
+ if (keyCode == 13 && !e.shiftKey) {
37
+ e.preventDefault();
38
+ handleSend();
39
+ }
40
+ };
41
+
42
+ const inputHeight = useMemo(() => {
43
+ return 40 + (message.split('\n').length - 1) * 20 + 'px';
44
+ }, [message]);
45
+
46
+ const handleFileChange = ({ target: { files } }) => setFiles((existing) => existing.concat(...files));
47
+
48
+ const openFileUpload = () => files$.current?.click();
49
+ return (
50
+ <>
51
+ <input
52
+ style={{ display: 'none' }}
53
+ accept="image/png, image/gif, image/jpeg"
54
+ type="file" onChange={handleFileChange} ref={files$} multiple={true} />
55
+ <Box p="6" px={{ base: 0, md: '80px', lg: '150px'}}>
56
+ <Tooltip
57
+ label="Image"
58
+ placement="top"
59
+ // bg="white"
60
+ display="flex"
61
+ alignItems="center"
62
+ width="60px"
63
+ height="40px"
64
+ borderRadius="10px"
65
+ fontSize="15px"
66
+ justifyContent="center"
67
+ marginTop="5px"
68
+ // color="white"
69
+ boxShadow="0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)"
70
+ hasArrow={true}
71
+ >
72
+ <Button
73
+ onClick={openFileUpload}
74
+ border="none"
75
+ borderRadius="50%"
76
+ bg="none"
77
+ width="42px"
78
+ height="42px"
79
+ p="4px"
80
+ _hover={{ backgroundColor: 'rgb(221, 221, 221)' }}
81
+ >
82
+ <BiImage color="#464646" width="full" height="full" />
83
+ </Button>
84
+ </Tooltip>
85
+ <InputGroup size="md" marginBottom={15}>
86
+ <InputLeftElement height="100%" pl="25px" width="60px">
87
+ <Image width={'28px'} height={'28px'} src={logoURL} />
88
+ </InputLeftElement>
89
+ <Textarea
90
+ fontSize="16px"
91
+ placeholder="Reminder - Leave a review"
92
+ value={message}
93
+ height={inputHeight}
94
+ minHeight="50px"
95
+ maxH="220px"
96
+ pl="75px"
97
+ pr="15px"
98
+ pt="12px"
99
+ pb="12px"
100
+ borderRadius={'25px'}
101
+ borderColor={'transparent'}
102
+ backgroundColor={'gray.300'}
103
+ color="gray.600"
104
+ resize="none"
105
+ overflow={'hidden'}
106
+ onKeyDown={handleKeyDown}
107
+ onChange={(e) => setMessage(e.target.value)}
108
+ onSubmit={(e) => alert(e)}
109
+ />
110
+ <InputRightElement height="100%">
111
+ {message || files.length && (
112
+ <Box
113
+ position="relative"
114
+ right="20px"
115
+ as="button"
116
+ height="30px"
117
+ lineHeight="1.2"
118
+ transition="all 0.2s cubic-bezier(.08,.52,.52,1)"
119
+ border="1px"
120
+ px="15px"
121
+ borderRadius="5px"
122
+ fontSize="13px"
123
+ fontWeight="semibold"
124
+ bg="transparent"
125
+ borderColor="#ccd0d5"
126
+ color="#4b4f56"
127
+ _hover={{ bg: '#ebedf0' }}
128
+ _active={{
129
+ bg: '#dddfe2',
130
+ transform: 'scale(0.98)',
131
+ borderColor: '#bec3c9',
132
+ }}
133
+ _focus={{
134
+ boxShadow: '0 0 1px 2px rgba(88, 144, 255, .75), 0 1px 1px rgba(0, 0, 0, .15)',
135
+ }}
136
+ onClick={handleSend}
137
+ >
138
+ Send
139
+ </Box>
140
+ )}
141
+ {/* </Button> */}
142
+ </InputRightElement>
143
+ </InputGroup>
144
+ <FilesList files={files} />
145
+ </Box>
146
+ </>
147
+ );
148
+ };
@@ -0,0 +1,137 @@
1
+ import {
2
+ Icon,
3
+ Avatar,
4
+ Box,
5
+ Flex,
6
+ Modal,
7
+ ModalBody,
8
+ ModalCloseButton,
9
+ ModalContent,
10
+ ModalOverlay,
11
+ Text,
12
+ useDisclosure,
13
+ } from '@chakra-ui/react';
14
+ import { BsFlag } from '@react-icons/all-files/bs/BsFlag';
15
+ import React, { useMemo, useRef } from 'react';
16
+ import { UserModalContent } from './UserModalContent';
17
+ import { isToday, isYesterday, format } from 'date-fns';
18
+ import { FilesList } from '../inbox/FilesList';
19
+
20
+ type MessagesProps = {
21
+ channelId: number;
22
+ currentUser: any;
23
+ channelMessages: any[];
24
+ totalCount: number;
25
+ };
26
+ export const Messages = ({ channelId, currentUser, channelMessages, totalCount }: MessagesProps) => {
27
+ const { isOpen, onOpen, onClose } = useDisclosure();
28
+
29
+ const messagesEndRef = useRef(null);
30
+ const scrollToBottom = () => {
31
+ messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });
32
+ };
33
+
34
+ const messageList = useMemo(() => {
35
+ let currentDate = '';
36
+ let res = [];
37
+ channelMessages.map((msg) => {
38
+ const date = new Date(msg.createdAt);
39
+ let msgDate;
40
+ if (isToday(date)) msgDate = 'Today';
41
+ else if (isYesterday(date)) msgDate = 'Yesterday';
42
+ else msgDate = format(new Date(msg.createdAt), 'eee, do MMMM');
43
+
44
+ if (msgDate !== currentDate) {
45
+ res.push(msgDate);
46
+ currentDate = msgDate;
47
+ }
48
+ res.push(msg);
49
+ });
50
+ return res;
51
+ }, [channelMessages]);
52
+ return (
53
+ <Box w="full">
54
+ {messageList.map((message, index) => {
55
+ return typeof message !== 'object' ? (
56
+ <Flex w="full" key={`msgList_${index}`} justifyContent={'center'} mb="7">
57
+ <Text fontSize="14px" color="gray.600" fontWeight={'bold'}>
58
+ {message}
59
+ </Text>
60
+ </Flex>
61
+ ) : (
62
+ <Flex w="full" key={`msgList_${index}`} justifyContent={'flex-start'} mb="7">
63
+ <Flex flexGrow={1}>
64
+ <Avatar
65
+ width="60px"
66
+ height="60px"
67
+ backgroundColor="grey"
68
+ borderRadius="50%"
69
+ src={message?.imageUrl ? message?.imageUrl : ''}
70
+ marginRight="15px"
71
+ onClick={onOpen}
72
+ ></Avatar>
73
+ <Box flexGrow={1}>
74
+ <Flex flexGrow={1} mt="5px">
75
+ <Text fontSize="14px" color="gray.600" fontWeight={'bold'}>
76
+ {message?.author?.familyName && message?.author?.givenName
77
+ ? message?.author?.givenName + ' ' + message?.author?.familyName
78
+ : message?.author?.username}
79
+ </Text>
80
+ <Text fontSize="14px" color="gray.500" ml="10px">
81
+ {format(new Date(message?.createdAt), 'MMM dd, yyyy hh:mm aaa')}
82
+ </Text>
83
+ </Flex>
84
+ <Box>
85
+ <Text fontSize="14px" mt="5px" mb="5px" color="gray.600" whiteSpace={'pre-line'}>
86
+ {message?.message}
87
+ </Text>
88
+ {message.files?.totalCount ? <FilesList uploaded files={message.files?.data} /> : null}
89
+ </Box>
90
+ </Box>
91
+ </Flex>
92
+ {currentUser?.id !== message?.author?.id && (
93
+ <Box ml="8px">
94
+ <Icon as={BsFlag} color="gray.600" width={'24px'} height={'24px'} />
95
+ </Box>
96
+ )}
97
+ </Flex>
98
+ );
99
+ })}
100
+ </Box>
101
+ );
102
+ };
103
+
104
+ // TODO: remove unused code
105
+ const ChateeModal = ({ element, isOpen, onClose }) => {
106
+ return (
107
+ <Modal isOpen={isOpen} onClose={onClose} motionPreset="slideInBottom">
108
+ <ModalOverlay />
109
+ <ModalContent
110
+ backgroundColor="white"
111
+ width="1036px"
112
+ position="absolute"
113
+ left="530px"
114
+ top="100px"
115
+ height="700px"
116
+ borderRadius="10px"
117
+ boxShadow="0 10px 20px rgba(0,0,0,0.19), 0 6px 6px rgba(0,0,0,0.23)"
118
+ >
119
+ <Box
120
+ display="flex"
121
+ justifyContent="space-between"
122
+ borderBottom="1px solid rgb(221, 221, 221)"
123
+ paddingBottom="15px"
124
+ paddingTop="15px"
125
+ >
126
+ <ModalCloseButton as="a" width="30px" marginLeft="10px" color="black" _hover={{ color: 'black' }} />
127
+ </Box>
128
+ <ModalBody>
129
+ <UserModalContent
130
+ username={element?.author?.username}
131
+ image={element.imageUrl ? element.imageUrl : ''}
132
+ />
133
+ </ModalBody>
134
+ </ModalContent>
135
+ </Modal>
136
+ );
137
+ };
@@ -0,0 +1,56 @@
1
+ import React from 'react';
2
+ import { useFela } from 'react-fela';
3
+ import { Button, Box } from '@chakra-ui/react';
4
+
5
+ export const Popover = () => {
6
+ const content = [
7
+ {
8
+ name: 'All Conversations',
9
+ },
10
+ {
11
+ name: 'Archived Conversations',
12
+ total: '0',
13
+ },
14
+ {
15
+ name: 'Unread Conversations',
16
+ total: '0',
17
+ },
18
+ ];
19
+ return (
20
+ <Box>
21
+ {content?.map((item, index) => {
22
+ if (!item.total) {
23
+ return (
24
+ <Box _hover={{ bg: '#edecec' }} className="popover-style" key={index}>
25
+ <Button
26
+ border="none"
27
+ fontSize="15px"
28
+ color="#282121"
29
+ variant="link"
30
+ bg='none'
31
+ height= '30px'
32
+ >
33
+ {item.name}
34
+ </Button>
35
+ </Box>
36
+ );
37
+ } else {
38
+ return (
39
+ <Box _hover={{ bg: '#edecec' }} className="popover-style" key={index}>
40
+ <Button
41
+ border="none"
42
+ fontSize="15px"
43
+ color="#282121"
44
+ variant="link"
45
+ bg='none'
46
+ height= '30px'
47
+ >
48
+ {item.name + `(${item.total})`}
49
+ </Button>
50
+ </Box>
51
+ );
52
+ }
53
+ })}
54
+ </Box>
55
+ );
56
+ }
@@ -0,0 +1,52 @@
1
+ import React from 'react';
2
+ import { Avatar, Button, Box, Flex, Text, Link } from '@chakra-ui/react';
3
+ import { AiOutlineSecurityScan } from '@react-icons/all-files/ai/AiOutlineSecurityScan';
4
+ import { FiCheck } from '@react-icons/all-files/fi/FiCheck';
5
+ import { BsFillStarFill } from '@react-icons/all-files/bs/BsFillStarFill';
6
+
7
+ export const UserModalContent = ({ username, imageUrl }: any) => {
8
+ return (
9
+ <Box>
10
+ <Box>
11
+ <Avatar
12
+ size="large"
13
+ src={imageUrl !== '' ? imageUrl : ''}
14
+ backgroundColor="grey"
15
+ width="200px"
16
+ height="200px"
17
+ borderRadius="50%"
18
+ />
19
+ <a href="#">Update photo</a>
20
+ <AiOutlineSecurityScan style={{ width: '24px', height: '24px', color: 'black' }} />
21
+ <Box>
22
+ <Text>Identity verification</Text>
23
+ <Text as="p" color="black">
24
+ Show others you’re really you with the identity verification badge.
25
+ </Text>
26
+ <Button className="get-badge-btn" color="black" bg="transparent">
27
+ Get the badge
28
+ </Button>
29
+ </Box>
30
+ <Box>
31
+ <Text>{username} confirmed </Text>
32
+ <Box>
33
+ <FiCheck color="black" />
34
+ <Text as="p" color="black">
35
+ Email address
36
+ </Text>
37
+ </Box>
38
+ </Box>
39
+ </Box>
40
+ <Box>
41
+ <Flex>
42
+ <Text>Hi, I'm {username}</Text>
43
+ <Text as="p">Joined in 2021</Text>
44
+ <Link>Edit profile</Link>
45
+ <BsFillStarFill color="black" fontSize="md" />
46
+ Reviews
47
+ </Flex>
48
+ <Link href="">Reviews by you</Link>
49
+ </Box>
50
+ </Box>
51
+ );
52
+ };
@@ -0,0 +1,3 @@
1
+ export * from './LeftSidebar';
2
+ export * from './Messages';
3
+ export * from './MessageInput';
@@ -0,0 +1,17 @@
1
+ import React, { useMemo } from 'react';
2
+
3
+ export function FilesList({ files, uploaded = false }: { files: any[], uploaded?: boolean }) {
4
+ return (
5
+ <div style={{ display: 'flex', flexDirection: 'row' }}>
6
+ {files.map(file => <FilesList.FileElement uploaded={uploaded} file={file} />)}
7
+ </div>
8
+ );
9
+ }
10
+
11
+ FilesList.FileElement = function FileElement({ file, uploaded }: { file: any, uploaded: boolean }) {
12
+ const url = useMemo(() => uploaded ? file.url : URL.createObjectURL(file), [file, uploaded]);
13
+
14
+ return (
15
+ <div style={{ height: 50, width: 50, backgroundImage: `url(${url})`, backgroundSize: 'contain', marginRight: '10px' }} />
16
+ );
17
+ }