agx-chat-web 0.4.9

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 (154) hide show
  1. package/README.md +9 -0
  2. package/dist/agx-chat.js +3 -0
  3. package/dist/agx-chat.js.LICENSE.txt +303 -0
  4. package/dist/agx-chat.js.map +1 -0
  5. package/dist/agx-chat.min.js +3 -0
  6. package/dist/agx-chat.min.js.LICENSE.txt +303 -0
  7. package/dist/agx-chat.min.js.map +1 -0
  8. package/dist/esm/__tests__/app/Messenger/classes/slaCalculations.spec.d.ts +1 -0
  9. package/dist/esm/__tests__/app/Messenger/classes/slaCalculations.spec.js +46 -0
  10. package/dist/esm/__tests__/app/Messenger/classes/slaCalculations.spec.js.map +1 -0
  11. package/dist/esm/app/Messenger/classes/slaCalculations.d.ts +30 -0
  12. package/dist/esm/app/Messenger/classes/slaCalculations.js +142 -0
  13. package/dist/esm/app/Messenger/classes/slaCalculations.js.map +1 -0
  14. package/dist/esm/app/Messenger/components/ChatButton/ChatButton.d.ts +14 -0
  15. package/dist/esm/app/Messenger/components/ChatButton/ChatButton.js +31 -0
  16. package/dist/esm/app/Messenger/components/ChatButton/ChatButton.js.map +1 -0
  17. package/dist/esm/app/Messenger/components/ChatTabs/ChatTabs.d.ts +9 -0
  18. package/dist/esm/app/Messenger/components/ChatTabs/ChatTabs.js +15 -0
  19. package/dist/esm/app/Messenger/components/ChatTabs/ChatTabs.js.map +1 -0
  20. package/dist/esm/app/Messenger/components/ImagesContainer/ImagesContainer.d.ts +3 -0
  21. package/dist/esm/app/Messenger/components/ImagesContainer/ImagesContainer.js +24 -0
  22. package/dist/esm/app/Messenger/components/ImagesContainer/ImagesContainer.js.map +1 -0
  23. package/dist/esm/app/Messenger/components/IncomingMessage/IncomingMessage.d.ts +3 -0
  24. package/dist/esm/app/Messenger/components/IncomingMessage/IncomingMessage.js +33 -0
  25. package/dist/esm/app/Messenger/components/IncomingMessage/IncomingMessage.js.map +1 -0
  26. package/dist/esm/app/Messenger/components/InfiniteScroll/InfiniteScroll.d.ts +11 -0
  27. package/dist/esm/app/Messenger/components/InfiniteScroll/InfiniteScroll.js +37 -0
  28. package/dist/esm/app/Messenger/components/InfiniteScroll/InfiniteScroll.js.map +1 -0
  29. package/dist/esm/app/Messenger/components/InputFile/InputFile.d.ts +8 -0
  30. package/dist/esm/app/Messenger/components/InputFile/InputFile.js +59 -0
  31. package/dist/esm/app/Messenger/components/InputFile/InputFile.js.map +1 -0
  32. package/dist/esm/app/Messenger/components/MessageBallon/MessageBalloon.d.ts +8 -0
  33. package/dist/esm/app/Messenger/components/MessageBallon/MessageBalloon.js +32 -0
  34. package/dist/esm/app/Messenger/components/MessageBallon/MessageBalloon.js.map +1 -0
  35. package/dist/esm/app/Messenger/components/MessengerAvatar/MessengerAvatar.d.ts +3 -0
  36. package/dist/esm/app/Messenger/components/MessengerAvatar/MessengerAvatar.js +13 -0
  37. package/dist/esm/app/Messenger/components/MessengerAvatar/MessengerAvatar.js.map +1 -0
  38. package/dist/esm/app/Messenger/components/MessengerThemeWrapper/MessengerThemeWrapper.d.ts +40 -0
  39. package/dist/esm/app/Messenger/components/MessengerThemeWrapper/MessengerThemeWrapper.js +39 -0
  40. package/dist/esm/app/Messenger/components/MessengerThemeWrapper/MessengerThemeWrapper.js.map +1 -0
  41. package/dist/esm/app/Messenger/components/SearchInput/SearchInput.d.ts +10 -0
  42. package/dist/esm/app/Messenger/components/SearchInput/SearchInput.js +32 -0
  43. package/dist/esm/app/Messenger/components/SearchInput/SearchInput.js.map +1 -0
  44. package/dist/esm/app/Messenger/components/Select/Select.d.ts +13 -0
  45. package/dist/esm/app/Messenger/components/Select/Select.js +16 -0
  46. package/dist/esm/app/Messenger/components/Select/Select.js.map +1 -0
  47. package/dist/esm/app/Messenger/components/SenderMessages/SenderMessages.d.ts +3 -0
  48. package/dist/esm/app/Messenger/components/SenderMessages/SenderMessages.js +32 -0
  49. package/dist/esm/app/Messenger/components/SenderMessages/SenderMessages.js.map +1 -0
  50. package/dist/esm/app/Messenger/components/SystemMessage/SystemMessage.d.ts +3 -0
  51. package/dist/esm/app/Messenger/components/SystemMessage/SystemMessage.js +14 -0
  52. package/dist/esm/app/Messenger/components/SystemMessage/SystemMessage.js.map +1 -0
  53. package/dist/esm/app/Messenger/components/TextArea/TextArea.d.ts +8 -0
  54. package/dist/esm/app/Messenger/components/TextArea/TextArea.js +14 -0
  55. package/dist/esm/app/Messenger/components/TextArea/TextArea.js.map +1 -0
  56. package/dist/esm/app/Messenger/hooks/useConversations.d.ts +11 -0
  57. package/dist/esm/app/Messenger/hooks/useConversations.js +59 -0
  58. package/dist/esm/app/Messenger/hooks/useConversations.js.map +1 -0
  59. package/dist/esm/app/Messenger/hooks/useThemes.d.ts +31 -0
  60. package/dist/esm/app/Messenger/hooks/useThemes.js +11 -0
  61. package/dist/esm/app/Messenger/hooks/useThemes.js.map +1 -0
  62. package/dist/esm/app/Messenger/icons/AttachFileIcon.d.ts +3 -0
  63. package/dist/esm/app/Messenger/icons/AttachFileIcon.js +10 -0
  64. package/dist/esm/app/Messenger/icons/AttachFileIcon.js.map +1 -0
  65. package/dist/esm/app/Messenger/icons/CloseIcon.d.ts +1 -0
  66. package/dist/esm/app/Messenger/icons/CloseIcon.js +9 -0
  67. package/dist/esm/app/Messenger/icons/CloseIcon.js.map +1 -0
  68. package/dist/esm/app/Messenger/icons/EmptyIcon.d.ts +1 -0
  69. package/dist/esm/app/Messenger/icons/EmptyIcon.js +8 -0
  70. package/dist/esm/app/Messenger/icons/EmptyIcon.js.map +1 -0
  71. package/dist/esm/app/Messenger/icons/MessageIcon.d.ts +5 -0
  72. package/dist/esm/app/Messenger/icons/MessageIcon.js +12 -0
  73. package/dist/esm/app/Messenger/icons/MessageIcon.js.map +1 -0
  74. package/dist/esm/app/Messenger/icons/ReadIcon.d.ts +3 -0
  75. package/dist/esm/app/Messenger/icons/ReadIcon.js +7 -0
  76. package/dist/esm/app/Messenger/icons/ReadIcon.js.map +1 -0
  77. package/dist/esm/app/Messenger/icons/SearchIcon.d.ts +1 -0
  78. package/dist/esm/app/Messenger/icons/SearchIcon.js +8 -0
  79. package/dist/esm/app/Messenger/icons/SearchIcon.js.map +1 -0
  80. package/dist/esm/app/Messenger/icons/TimerIcon.d.ts +1 -0
  81. package/dist/esm/app/Messenger/icons/TimerIcon.js +6 -0
  82. package/dist/esm/app/Messenger/icons/TimerIcon.js.map +1 -0
  83. package/dist/esm/app/Messenger/icons/TrashIcon.d.ts +5 -0
  84. package/dist/esm/app/Messenger/icons/TrashIcon.js +7 -0
  85. package/dist/esm/app/Messenger/icons/TrashIcon.js.map +1 -0
  86. package/dist/esm/app/Messenger/views/MessengerList.d.ts +39 -0
  87. package/dist/esm/app/Messenger/views/MessengerList.js +50 -0
  88. package/dist/esm/app/Messenger/views/MessengerList.js.map +1 -0
  89. package/dist/esm/app/Messenger/views/MessengerListItem.d.ts +11 -0
  90. package/dist/esm/app/Messenger/views/MessengerListItem.js +87 -0
  91. package/dist/esm/app/Messenger/views/MessengerListItem.js.map +1 -0
  92. package/dist/esm/app/Messenger/views/MessengerMessages.d.ts +23 -0
  93. package/dist/esm/app/Messenger/views/MessengerMessages.js +133 -0
  94. package/dist/esm/app/Messenger/views/MessengerMessages.js.map +1 -0
  95. package/dist/esm/app/Messenger/views/NewFormChat.d.ts +10 -0
  96. package/dist/esm/app/Messenger/views/NewFormChat.js +64 -0
  97. package/dist/esm/app/Messenger/views/NewFormChat.js.map +1 -0
  98. package/dist/esm/index.d.ts +8 -0
  99. package/dist/esm/index.js +9 -0
  100. package/dist/esm/index.js.map +1 -0
  101. package/dist/esm/setupTests.d.ts +1 -0
  102. package/dist/esm/setupTests.js +6 -0
  103. package/dist/esm/setupTests.js.map +1 -0
  104. package/dist/esm/types.d.ts +134 -0
  105. package/dist/esm/types.js +2 -0
  106. package/dist/esm/types.js.map +1 -0
  107. package/package.json +67 -0
  108. package/src/__tests__/app/Messenger/classes/slaCalculations.spec.ts +115 -0
  109. package/src/app/Messenger/classes/slaCalculations.ts +165 -0
  110. package/src/app/Messenger/components/ChatButton/ChatButton.tsx +63 -0
  111. package/src/app/Messenger/components/ChatTabs/ChatTabs.less +18 -0
  112. package/src/app/Messenger/components/ChatTabs/ChatTabs.tsx +32 -0
  113. package/src/app/Messenger/components/ImagesContainer/ImagesContainer.less +64 -0
  114. package/src/app/Messenger/components/ImagesContainer/ImagesContainer.tsx +40 -0
  115. package/src/app/Messenger/components/IncomingMessage/IncomingMessage.tsx +59 -0
  116. package/src/app/Messenger/components/InfiniteScroll/InfiniteScroll.tsx +52 -0
  117. package/src/app/Messenger/components/InputFile/InputFile.tsx +106 -0
  118. package/src/app/Messenger/components/InputFile/inputFile.less +52 -0
  119. package/src/app/Messenger/components/MessageBallon/MessageBalloon.tsx +88 -0
  120. package/src/app/Messenger/components/MessengerAvatar/MessengerAvatar.tsx +21 -0
  121. package/src/app/Messenger/components/MessengerThemeWrapper/MessengerThemeWrapper.tsx +58 -0
  122. package/src/app/Messenger/components/SearchInput/SearchInput.less +45 -0
  123. package/src/app/Messenger/components/SearchInput/SearchInput.tsx +68 -0
  124. package/src/app/Messenger/components/Select/Select.less +22 -0
  125. package/src/app/Messenger/components/Select/Select.tsx +41 -0
  126. package/src/app/Messenger/components/SenderMessages/SenderMessages.tsx +52 -0
  127. package/src/app/Messenger/components/SystemMessage/SystemMessage.tsx +23 -0
  128. package/src/app/Messenger/components/TextArea/TextArea.tsx +31 -0
  129. package/src/app/Messenger/components/TextArea/Textarea.less +22 -0
  130. package/src/app/Messenger/hooks/useConversations.tsx +80 -0
  131. package/src/app/Messenger/hooks/useThemes.tsx +14 -0
  132. package/src/app/Messenger/icons/AttachFileIcon.tsx +11 -0
  133. package/src/app/Messenger/icons/CloseIcon.tsx +11 -0
  134. package/src/app/Messenger/icons/EmptyIcon.tsx +11 -0
  135. package/src/app/Messenger/icons/MessageIcon.tsx +18 -0
  136. package/src/app/Messenger/icons/ReadIcon.tsx +9 -0
  137. package/src/app/Messenger/icons/SearchIcon.tsx +12 -0
  138. package/src/app/Messenger/icons/TimerIcon.tsx +10 -0
  139. package/src/app/Messenger/icons/TrashIcon.tsx +13 -0
  140. package/src/app/Messenger/views/Messenger.less +610 -0
  141. package/src/app/Messenger/views/MessengerList.tsx +172 -0
  142. package/src/app/Messenger/views/MessengerListItem.tsx +136 -0
  143. package/src/app/Messenger/views/MessengerMessages.tsx +287 -0
  144. package/src/app/Messenger/views/NewFormChat.tsx +126 -0
  145. package/src/assets/right-arrow.svg +10 -0
  146. package/src/index.ts +17 -0
  147. package/src/react-app-env.d.ts +16 -0
  148. package/src/setupTests.ts +5 -0
  149. package/src/styles/abstracts/animations.less +8 -0
  150. package/src/styles/abstracts/mixins.less +5 -0
  151. package/src/styles/abstracts/variables.less +25 -0
  152. package/src/styles/base/base.less +6 -0
  153. package/src/styles/index.less +6 -0
  154. package/src/types.ts +166 -0
@@ -0,0 +1,172 @@
1
+ import React, { Fragment } from 'react'
2
+ import { IList } from 'types'
3
+ import ChatTabs from '../components/ChatTabs/ChatTabs'
4
+ import ChatButtons from '../components/ChatButton/ChatButton'
5
+ import SearchInput from '../components/SearchInput/SearchInput'
6
+ import MessengerListItem, { activeItem } from './MessengerListItem'
7
+ import useTheme from '../hooks/useThemes'
8
+ import EmptyIcon from '../icons/EmptyIcon'
9
+ import InfiniteScroll from '../components/InfiniteScroll/InfiniteScroll'
10
+
11
+ interface IMessengerList {
12
+ affix?: React.ReactElement
13
+ loading: boolean
14
+ conversations: IList[]
15
+ currentId?: string
16
+ failed?: boolean
17
+ showBadge: boolean
18
+ tab?: 'list' | 'messages'
19
+ className?: string
20
+ onClick: (item: IList) => void
21
+ searchChat: (search: string, key: string) => void
22
+ searchKeys: { label: string, value: string }[]
23
+ messegerView: 'empty' | 'messages' | 'newChat'
24
+ helpDesk: boolean
25
+ handleChangeTickets: (tab: string) => void
26
+ loadingSearch: boolean
27
+ chatListTabs: { value: string, label: string }[]
28
+ chatButtons: {
29
+ label: string
30
+ onClick: () => void
31
+ type: string
32
+ canSee: boolean
33
+ disabled?: boolean
34
+ }[]
35
+ canSeeTimer: boolean
36
+ hasNext: boolean
37
+ onIntersect: () => void
38
+ sliceCount: number
39
+ }
40
+
41
+ const ListLoading = () => {
42
+ const {theme} = useTheme()
43
+ return (
44
+ <Fragment>
45
+ {new Array(5).fill('').map((_, idx) => (
46
+ <button
47
+ key={`asideSkeleton${idx}`}
48
+ style={{background: theme.listItemHover}}
49
+ className="messenger__aside-skeleton"
50
+ />
51
+ ))}
52
+ </Fragment>
53
+ )
54
+ }
55
+
56
+ const ShowProtocol = ({ item }: { item: IList }) => {
57
+ const { theme } = useTheme()
58
+ return (
59
+ <span
60
+ className='messenger__aside-protocol'
61
+ style={{
62
+ background: theme.buttonPrimary,
63
+ color: theme.buttonPrimaryText
64
+ }}
65
+ >
66
+ #{item.protocol}
67
+ </span>
68
+ )
69
+ }
70
+
71
+
72
+ function MessengerList({
73
+ affix,
74
+ conversations,
75
+ tab,
76
+ className = '',
77
+ loading,
78
+ failed,
79
+ showBadge,
80
+ currentId,
81
+ onClick,
82
+ searchChat,
83
+ searchKeys,
84
+ messegerView,
85
+ helpDesk,
86
+ handleChangeTickets,
87
+ chatListTabs,
88
+ chatButtons,
89
+ loadingSearch,
90
+ canSeeTimer,
91
+ hasNext,
92
+ onIntersect,
93
+ sliceCount
94
+ }: IMessengerList) {
95
+ const { theme } = useTheme()
96
+
97
+ return (
98
+ <aside
99
+ className={`messenger__aside ${className} ${tab === 'messages' ? 'mobile-hide' : ''}`}
100
+ style={{
101
+ border: `1px solid ${theme.borderColor}`,
102
+ borderRadius: '20px 0 0 20px',
103
+ background: theme.asideBg
104
+ }}
105
+ >
106
+ <div className="messenger__buttons-container">
107
+ <ChatButtons
108
+ chatButtons={chatButtons}
109
+ messegerView={messegerView}
110
+ removeActiveItem={(e: React.MouseEvent<HTMLElement, MouseEvent>) => {
111
+ activeItem(e, 'messenger__aside-list-item', 'messenger__aside-list-item--active')
112
+ }}
113
+ />
114
+
115
+ {helpDesk &&
116
+ <SearchInput
117
+ searchKeys={searchKeys}
118
+ searchChat={searchChat}
119
+ loadingSearch={loadingSearch}
120
+ />
121
+ }
122
+ </div>
123
+
124
+ {affix && (
125
+ <div className="messenger__aside-header">
126
+ {React.cloneElement(affix)}
127
+ </div>
128
+ )}
129
+
130
+ <ChatTabs
131
+ chatListTabs={chatListTabs}
132
+ handleChangeTickets={handleChangeTickets}
133
+ />
134
+
135
+ <div className="messenger__aside-list">
136
+ <InfiniteScroll
137
+ root={document.querySelector('.messenger__aside-list')}
138
+ loading={loading}
139
+ loadingCover={<ListLoading />}
140
+ more={hasNext}
141
+ fetch={onIntersect}
142
+ >
143
+ {Array.isArray(conversations) && conversations.length > 0 && conversations.slice(0, sliceCount).map((item) => {
144
+ return (
145
+ <div
146
+ key={item?._id}
147
+ className={`messenger__aside-item-container ${showBadge ? 'messenger__active-badge' : ''}`}
148
+ >
149
+ <ShowProtocol item={item} />
150
+ <MessengerListItem
151
+ canSeeTimer={canSeeTimer}
152
+ currentId={currentId}
153
+ item={item}
154
+ onClick={onClick}
155
+ />
156
+ </div>
157
+ )
158
+ })}
159
+ </InfiniteScroll>
160
+
161
+ {failed || (conversations?.length === 0 && !loading) && (
162
+ <div className="messenger__aside-empty">
163
+ <EmptyIcon />
164
+ <p>Nenhuma conversa encontrada</p>
165
+ </div>
166
+ )}
167
+ </div>
168
+ </aside>
169
+ )
170
+ }
171
+
172
+ export default MessengerList
@@ -0,0 +1,136 @@
1
+ import React, { useState, useMemo, useEffect } from 'react'
2
+ import { IList } from 'types'
3
+ import { SlaDates, timeAsDayjs } from '../classes/slaCalculations'
4
+ import MessengerAvatar from '../components/MessengerAvatar/MessengerAvatar'
5
+ import useTheme from '../hooks/useThemes'
6
+ import TimerIcon from '../icons/TimerIcon'
7
+
8
+ interface IListItem {
9
+ onClick: (item: IList) => void
10
+ item: IList
11
+ currentId?: string
12
+ canSeeTimer: boolean
13
+ }
14
+
15
+ export function activeItem(e: React.MouseEvent<HTMLElement, MouseEvent>, defaultClass: string, activeClass: string,) {
16
+ const click = document.querySelectorAll(`.${defaultClass}`)
17
+ click.forEach((item) => {
18
+ item.classList.remove(activeClass)
19
+ })
20
+
21
+ e.currentTarget.className += ` ${activeClass} `
22
+ }
23
+
24
+ function MessengerListItem ({ item, onClick, canSeeTimer, currentId }: IListItem) {
25
+ const [unreadMessages, setUnreadMessages] = useState<typeof item.totalUnreadMessages>(item.totalUnreadMessages)
26
+ const closedChat = useMemo(() => item.status.current.state === 'final' ? 'messenger__aside-list-item--closed' : '', [item])
27
+ const [background, setBackground] = useState<string | undefined>('')
28
+ const [counter, setCounter] = useState<number | null>(null)
29
+
30
+ const { theme } = useTheme()
31
+ const isInprogress = item.status?.current?.systemicValue === 'inprogress'
32
+
33
+ useEffect(() => {
34
+ let interval: NodeJS.Timer
35
+ if (isInprogress && canSeeTimer) {
36
+ const sla = new SlaDates(timeAsDayjs(item.currentTime).diff(item.createdAt, 'second'))
37
+ const diference = sla.calculateWorkingTime(
38
+ timeAsDayjs(item.createdAt),
39
+ timeAsDayjs(), { start: 9, end: 18 }
40
+ )
41
+
42
+ setCounter(diference)
43
+ if (sla.canUpdateClock(timeAsDayjs())) {
44
+ interval = setInterval(() => {
45
+ setCounter(prev => prev !== null ? prev + 1 : null)
46
+ }, 1000)
47
+ }
48
+ } else {
49
+ setCounter(item.SLATimePassed ?? null)
50
+ }
51
+
52
+ return () => {
53
+ clearInterval(interval)
54
+ }
55
+ }, [])
56
+
57
+ useEffect(() => {
58
+ setUnreadMessages(item.totalUnreadMessages)
59
+ }, [item])
60
+
61
+ function handleClick(e: React.MouseEvent<HTMLElement, MouseEvent>, item: IList) {
62
+ activeItem(e, 'messenger__aside-list-item', 'messenger__aside-list-item--active')
63
+ onClick(item)
64
+ }
65
+
66
+ function formatUnreadMessages(unread: number) {
67
+ if (!unread) return 0
68
+ if (unread >= 99) return 99
69
+ return unread
70
+ }
71
+
72
+ const onMouseOver = () => {
73
+ setBackground(theme?.listItemHover)
74
+ }
75
+
76
+ const onMouseLeave = () => {
77
+ setBackground('')
78
+ }
79
+
80
+
81
+ const ShowTimer = () => {
82
+ if (counter === null) return null
83
+
84
+ return (
85
+ <span
86
+ className='messenger__aside-timer'
87
+ style={{
88
+ background: SlaDates.getColorsByTime(counter),
89
+ color: 'white'
90
+ }}
91
+ >
92
+ <TimerIcon />&nbsp;
93
+
94
+ <b>
95
+ {SlaDates.secondsInHours(counter)}
96
+ </b>
97
+ </span>
98
+ )
99
+ }
100
+
101
+ return (
102
+ <>
103
+ <div
104
+ className={`messenger__aside-list-item ${closedChat}`}
105
+ onClick={(e) => handleClick(e, item)}
106
+ onMouseOver={onMouseOver}
107
+ onMouseLeave={onMouseLeave}
108
+ style={{
109
+ color: theme?.asideFontColor,
110
+ backgroundColor: currentId === item._id ? theme?.active : background,
111
+ }}
112
+ >
113
+ <MessengerAvatar image={item?.creator?.image}>
114
+ {(item?.creator && item?.creator.username) ? item?.creator.username.slice(0, 1) : ''}
115
+ </MessengerAvatar>
116
+
117
+ <div className="messenger__aside-list-item--info">
118
+ <p className="messenger__aside-list-item--title">{item?.creator?.username}</p>
119
+ {item?.reason && (<p className="messenger__aside-list-item--description">{item.reason}</p>)}
120
+ </div>
121
+
122
+ <div className="messenger__aside-list-item--additional">
123
+ {unreadMessages > 0 && (
124
+ <div className="messenger__aside-list-item--unread">
125
+ <span>{formatUnreadMessages(unreadMessages)}</span>
126
+ </div>
127
+ )}
128
+ </div>
129
+
130
+ {canSeeTimer && <ShowTimer />}
131
+ </div>
132
+ </>
133
+ )
134
+ }
135
+
136
+ export default MessengerListItem
@@ -0,0 +1,287 @@
1
+ import React, { Fragment, MutableRefObject, useMemo, useRef, useState } from 'react'
2
+ import ImagesContainer from '../components/ImagesContainer/ImagesContainer'
3
+ import MessageBalloon from '../components/MessageBallon/MessageBalloon'
4
+ import AttachFileIcon from '../icons/AttachFileIcon'
5
+ import MessageIcon from '../icons/MessageIcon'
6
+ import rightArrow from '../../../assets/right-arrow.svg'
7
+ import { ICommonProps, IList, IMessages, IOption } from 'types'
8
+ import useTheme from '../hooks/useThemes'
9
+
10
+ import NewChatForm from './NewFormChat'
11
+ import EmptyIcon from '../icons/EmptyIcon'
12
+
13
+ interface IMessengerMessages extends ICommonProps {
14
+ header: React.ReactElement
15
+ current?: IList
16
+ creatorId?: string
17
+ loading: boolean
18
+ allowImages: boolean
19
+ tab?: 'list' | 'messages'
20
+ messegerView: 'empty' | 'messages' | 'newChat',
21
+ className?: string
22
+ messages: IMessages[]
23
+ onSubmit: (value: FormData, callback: () => void) => void
24
+ cancelNewChat: () => void
25
+ formatDate: (date: string | Date) => string | undefined
26
+ onScroll: (e: React.UIEvent<HTMLDivElement, UIEvent>) => void
27
+ reasons: Array<IOption>
28
+ products: Array<IOption>
29
+ submitNewChat: (values: FormData) => void,
30
+ newChatLoading: boolean
31
+ }
32
+
33
+ interface IMessengerForm {
34
+ children: React.ReactElement,
35
+ messegerView: 'empty' | 'messages' | 'newChat',
36
+ reasons: Array<IOption>
37
+ products: Array<IOption>
38
+ submitNewChat: (values: FormData) => void,
39
+ cancelNewChat: () => void,
40
+ newChatLoading: boolean
41
+ }
42
+
43
+ function MessengerEmpty({ children, messegerView }: { children: React.ReactElement, messegerView: 'empty' | 'messages' | 'newChat' }) {
44
+ const { theme } = useTheme()
45
+
46
+ if (messegerView === 'empty') {
47
+ return (
48
+ <div className="messenger__messages-container--empty" style={{ backgroundColor: theme?.messengerNotSelectedBg }}>
49
+ <MessageIcon width="72" height="72" />
50
+ <p>Selecione uma conversa para visualizar as mensagens</p>
51
+ </div>
52
+ )
53
+ }
54
+
55
+ return children
56
+ }
57
+
58
+ function MessengerForm({
59
+ children,
60
+ messegerView,
61
+ submitNewChat,
62
+ cancelNewChat,
63
+ reasons,
64
+ products,
65
+ newChatLoading
66
+ }: IMessengerForm) {
67
+ if (messegerView === 'newChat') {
68
+ return (
69
+ <NewChatForm reasons={reasons} products={products} submitNewChat={submitNewChat} cancelNewChat={cancelNewChat} loading={newChatLoading}/>
70
+ )
71
+ }
72
+ return children
73
+ }
74
+
75
+ function Loading({ loading }: { loading: boolean }) {
76
+ if (loading) {
77
+ return (
78
+ (
79
+ <div className="messenger__messages-loading">
80
+ <div className="messenger__messages-loading--loader" />
81
+ </div>
82
+ )
83
+ )
84
+ }
85
+
86
+ return <></>
87
+ }
88
+
89
+ function Messages({ messages, creatorId, formatDate }: { messages: IMessages[], creatorId?: string, formatDate: (date: string | Date) => string | undefined }) {
90
+ if (messages && Array.isArray(messages)) {
91
+ return <>
92
+ {messages.map((item, idx) => {
93
+ return (
94
+ <Fragment key={`${item.ticketId}_${item.senderId}_${idx}`}>
95
+ <MessageBalloon
96
+ id={`message_${idx}`}
97
+ formatDate={formatDate}
98
+ creatorId={creatorId}
99
+ item={item}
100
+ />
101
+ </Fragment>
102
+ )
103
+ })}
104
+ </>
105
+ }
106
+
107
+ return <></>
108
+ }
109
+
110
+ function NoMessages({ messages, loading }: { messages: IMessages[], loading: boolean }) {
111
+ const { theme } = useTheme()
112
+ if (!messages || messages.length === 0 && !loading) {
113
+ return <div className="messenger__message-empty"
114
+ style={{color: theme.emptyMessagesFontColor}}
115
+ >
116
+ <EmptyIcon />
117
+ <p>Nenhuma mensagem encontrada</p>
118
+ </div>
119
+ }
120
+ return <></>
121
+ }
122
+
123
+ function AllowImages({ allowImages, attachFile, handleFile, closedChat }: { allowImages: boolean, attachFile: MutableRefObject<HTMLInputElement | null>, handleFile: (e: React.ChangeEvent<HTMLInputElement>) => void, closedChat: boolean }) {
124
+ if (allowImages) {
125
+ return <Fragment>
126
+ <input
127
+ type="file"
128
+ size={1}
129
+ className="messenger__messages-send--file"
130
+ ref={attachFile}
131
+ onChange={handleFile}
132
+ accept="image/*"
133
+ />
134
+
135
+ <AttachFileIcon
136
+ className={`messenger__messages-send__attach ${closedChat ? 'messenger__messages-send__attach--disabled' : ''}`}
137
+ onClick={() => !closedChat ? attachFile.current?.click() : null}
138
+ />
139
+ </Fragment>
140
+ }
141
+ return <></>
142
+ }
143
+
144
+ function MessengerMessages({
145
+ header,
146
+ tab,
147
+ className = '',
148
+ current,
149
+ messages,
150
+ allowImages,
151
+ creatorId,
152
+ loading,
153
+ onSubmit,
154
+ submitNewChat,
155
+ cancelNewChat,
156
+ reasons,
157
+ products,
158
+ messegerView,
159
+ formatDate,
160
+ onScroll,
161
+ newChatLoading
162
+ }: IMessengerMessages) {
163
+
164
+ const [file, setFile] = useState<File | null>()
165
+ const [sending, setSending] = useState<boolean>(false)
166
+
167
+ const inputRef: MutableRefObject<HTMLTextAreaElement | null> = useRef(null)
168
+ const attachFile: MutableRefObject<HTMLInputElement | null> = useRef(null)
169
+ const closedChat = useMemo(() => current?.status.current.state === 'final', [current])
170
+ const { theme } = useTheme()
171
+
172
+ function handleSubmit(e?: React.FormEvent<HTMLFormElement>) {
173
+ e?.preventDefault()
174
+ if (sending) return
175
+ setSending(true)
176
+
177
+ const data = new FormData()
178
+ if (file) data.append('file', file)
179
+ if (inputRef.current?.value) data.append('message', inputRef.current?.value)
180
+
181
+ onSubmit(data, () => {
182
+ if (inputRef.current) inputRef.current.value = ''
183
+ if (file) setFile(null)
184
+ setSending(false)
185
+ })
186
+ }
187
+
188
+ function handleFile(e: React.ChangeEvent<HTMLInputElement>) {
189
+ if (e.target.files) {
190
+ const file = e.target.files[0]
191
+ if (file?.type?.includes('image/')) setFile(e.target.files[0])
192
+ }
193
+ }
194
+
195
+ return (
196
+ <div className={`${className} ${tab === 'list' ? 'mobile-hide' : ''} messenger__messages`}>
197
+ <MessengerEmpty messegerView={messegerView}>
198
+ <Fragment>
199
+ <MessengerForm
200
+ newChatLoading={newChatLoading}
201
+ reasons={reasons}
202
+ products={products}
203
+ submitNewChat={submitNewChat}
204
+ cancelNewChat={cancelNewChat}
205
+ messegerView={messegerView}
206
+ >
207
+ <>
208
+ {file ? (<ImagesContainer file={file} onClose={() => setFile(null)} />) : (
209
+ <Fragment>
210
+ <div
211
+ className="messenger__messages-header"
212
+ style={
213
+ { backgroundColor: theme?.headerAndSenderBg,
214
+ border: `1px solid ${theme.borderColor}`
215
+ }}
216
+ >
217
+ {React.cloneElement(header)}
218
+ </div>
219
+
220
+ <div
221
+ className="messenger__messages-container" onScroll={onScroll}
222
+ style={{
223
+ padding: '1rem',
224
+ backgroundColor: theme?.messengerMessagesBg ,
225
+ border: `1px solid ${theme.borderColor}`
226
+ }}
227
+ >
228
+ <Loading loading={loading} />
229
+ <Messages formatDate={formatDate} messages={messages} creatorId={creatorId} />
230
+ <NoMessages messages={messages} loading={loading} />
231
+ </div>
232
+ </Fragment>
233
+ )}
234
+ <div
235
+ className="messenger__messages-send"
236
+ style={{
237
+ backgroundColor: theme?.headerAndSenderBg,
238
+ border: `1px solid ${theme.borderColor}`,
239
+ }}
240
+ >
241
+ <form
242
+ onSubmit={handleSubmit}
243
+ className="messenger__messages-send--form"
244
+ >
245
+ <textarea
246
+ cols={30}
247
+ rows={10}
248
+ placeholder={closedChat ? 'Conversa finalizada' : 'Digite uma mensagem'}
249
+ ref={inputRef}
250
+ onKeyDown={(e) => { if (e.key === 'Enter' && !e.shiftKey) handleSubmit() }}
251
+ className={`messenger__messages-send__input ${closedChat || sending ? 'messenger__messages-send__input--disabled' : ''} `}
252
+ disabled={closedChat || sending}
253
+ style={{
254
+ backgroundColor: theme?.inputBg,
255
+ border: theme?.chatInputBorder ? `1px solid ${theme?.chatInputBorder}` : ''
256
+ }}
257
+ />
258
+
259
+ <AllowImages allowImages={allowImages} handleFile={handleFile} attachFile={attachFile} closedChat={closedChat} />
260
+
261
+ <button
262
+ type="submit"
263
+ className={`messenger__messages-send__button ${closedChat || sending ? 'messenger__messages-send__button--disabled' : ''}`}
264
+ disabled={closedChat || sending}
265
+ style={{
266
+ backgroundColor: theme?.buttonPrimary
267
+ }}
268
+ >
269
+ <img
270
+ alt='Icone para a direita'
271
+ height={25}
272
+ width={25}
273
+ className="ml-1"
274
+ src={rightArrow}
275
+ />
276
+ </button>
277
+ </form>
278
+ </div>
279
+ </>
280
+ </MessengerForm>
281
+ </Fragment>
282
+ </MessengerEmpty>
283
+ </div>
284
+ )
285
+ }
286
+
287
+ export default MessengerMessages