contentoh-components-library 21.3.30 → 21.3.32

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 (128) hide show
  1. package/.env.development +3 -0
  2. package/.env.production +5 -2
  3. package/dist/assets/images/generalButton/closeIcon.svg +2 -2
  4. package/dist/components/atoms/ProgressBar/index.js +36 -6
  5. package/dist/components/atoms/ProgressBar/styles.js +11 -3
  6. package/dist/components/molecules/CustomSelect/CustomSelect.stories.js +21 -22
  7. package/dist/components/molecules/CustomSelect/SelectItem.js +10 -1
  8. package/dist/components/molecules/GalleryElement/index.js +1 -1
  9. package/dist/components/molecules/HeaderTop/index.js +15 -1
  10. package/dist/components/molecules/HeaderTop/styles.js +1 -1
  11. package/dist/components/molecules/ProductNameHeader/index.js +6 -4
  12. package/dist/components/molecules/StatusAsignationInfo/index.js +1 -1
  13. package/dist/components/organisms/FullProductNameHeader/index.js +1 -0
  14. package/dist/components/organisms/ProductImageModal/index.js +10 -3
  15. package/dist/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +214 -30
  16. package/dist/components/pages/ProviderProductEdition/index.js +86 -65
  17. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +88 -52
  18. package/dist/components/pages/RetailerProductEdition/index.js +27 -18
  19. package/dist/components/pages/RetailerProductEdition/utils.js +1 -1
  20. package/dist/global-files/data.js +18 -23
  21. package/dist/global-files/fonts.css +6 -0
  22. package/dist/global-files/variables.js +2 -0
  23. package/dist/index.js +267 -46
  24. package/package.json +14 -1
  25. package/src/assets/images/customSelect/starIcon.svg +14 -0
  26. package/src/assets/images/defaultImages/Spinner.gif +0 -0
  27. package/src/assets/images/defaultImages/notFound.svg +124 -0
  28. package/src/assets/images/generalButton/closeIcon.svg +2 -2
  29. package/src/assets/sounds/newMessage.mp3 +0 -0
  30. package/src/components/atoms/ButtonFileChooser/ButtonFileChooser.stories.js +47 -0
  31. package/src/components/atoms/ButtonFileChooser/index.js +68 -0
  32. package/src/components/atoms/ButtonFileChooser/styles.js +4 -0
  33. package/src/components/atoms/ButtonV2/ButtonV2.stories.js +53 -0
  34. package/src/components/atoms/ButtonV2/index.js +85 -0
  35. package/src/components/atoms/ButtonV2/styles.js +217 -0
  36. package/src/components/atoms/CustomIcon/CustomIcon.stories.js +36 -0
  37. package/src/components/atoms/CustomIcon/index.js +41 -0
  38. package/src/components/atoms/CustomIcon/styles.js +85 -0
  39. package/src/components/atoms/IconFile/IconFile.stories.js +35 -0
  40. package/src/components/atoms/IconFile/index.js +119 -0
  41. package/src/components/atoms/IconFile/styles.js +67 -0
  42. package/src/components/atoms/Image/Image.stories.js +51 -0
  43. package/src/components/atoms/Image/index.js +55 -0
  44. package/src/components/atoms/Image/styles.js +34 -0
  45. package/src/components/atoms/ImageLink/ImageLink.stories.js +43 -0
  46. package/src/components/atoms/ImageLink/index.js +57 -0
  47. package/src/components/atoms/ImageLink/styles.js +30 -0
  48. package/src/components/atoms/ImagePreview/ImagePreview.stories.js +52 -0
  49. package/src/components/atoms/ImagePreview/index.js +178 -0
  50. package/src/components/atoms/ImagePreview/styles.js +77 -0
  51. package/src/components/atoms/InputText/InputText.stories.js +39 -0
  52. package/src/components/atoms/InputText/index.js +61 -0
  53. package/src/components/atoms/InputText/styles.js +89 -0
  54. package/src/components/atoms/NotFound/NotFound.stories.js +19 -0
  55. package/src/components/atoms/NotFound/index.js +52 -0
  56. package/src/components/atoms/NotFound/styles.js +55 -0
  57. package/src/components/atoms/ProgressBar/index.js +40 -5
  58. package/src/components/atoms/ProgressBar/styles.js +24 -0
  59. package/src/components/atoms/SelectItemV2/SelectItemV2.stories.js +26 -0
  60. package/src/components/atoms/SelectItemV2/index.js +61 -0
  61. package/src/components/atoms/SelectItemV2/styles.js +90 -0
  62. package/src/components/atoms/Tooltip/Tooltip.stories.js +51 -0
  63. package/src/components/atoms/Tooltip/index.js +59 -0
  64. package/src/components/atoms/Tooltip/styles.js +42 -0
  65. package/src/components/molecules/ButtonDownloadFile/DownloadFile.stories.js +54 -0
  66. package/src/components/molecules/ButtonDownloadFile/index.js +109 -0
  67. package/src/components/molecules/ButtonDownloadFile/styles.js +66 -0
  68. package/src/components/molecules/CustomSelect/CustomSelect.stories.js +20 -12
  69. package/src/components/molecules/CustomSelect/SelectItem.js +7 -0
  70. package/src/components/molecules/Dropdown/Dropdown.stories.js +103 -0
  71. package/src/components/molecules/Dropdown/index.js +150 -0
  72. package/src/components/molecules/Dropdown/styles.js +75 -0
  73. package/src/components/molecules/GalleryElement/index.js +1 -1
  74. package/src/components/molecules/HeaderTop/index.js +17 -0
  75. package/src/components/molecules/HeaderTop/styles.js +5 -2
  76. package/src/components/molecules/ImageTooltip/ImageTooltip.stories.js +68 -0
  77. package/src/components/molecules/ImageTooltip/index.js +63 -0
  78. package/src/components/molecules/ImageTooltip/styles.js +18 -0
  79. package/src/components/molecules/ProductNameHeader/index.js +7 -2
  80. package/src/components/molecules/SelectV2/SelectV2.stories.js +115 -0
  81. package/src/components/molecules/SelectV2/index.js +357 -0
  82. package/src/components/molecules/SelectV2/styles.js +105 -0
  83. package/src/components/molecules/SelectV2/test.js +60 -0
  84. package/src/components/molecules/SelectV2/test.stories.js +10 -0
  85. package/src/components/molecules/StatusAsignationInfo/index.js +11 -9
  86. package/src/components/organisms/Chat/Chat.stories.js +149 -0
  87. package/src/components/organisms/Chat/ChatLists/ChatLists.stories.js +65 -0
  88. package/src/components/organisms/Chat/ChatLists/Rotoplas.jpeg +0 -0
  89. package/src/components/organisms/Chat/ChatLists/THD.png +0 -0
  90. package/src/components/organisms/Chat/ChatLists/index.js +141 -0
  91. package/src/components/organisms/Chat/ChatLists/styles.js +162 -0
  92. package/src/components/organisms/Chat/ContainerItems/ContainerItems.stories.js +142 -0
  93. package/src/components/organisms/Chat/ContainerItems/index.js +522 -0
  94. package/src/components/organisms/Chat/ContainerItems/styles.js +348 -0
  95. package/src/components/organisms/Chat/ContentChat/ContentChat.stories.js +102 -0
  96. package/src/components/organisms/Chat/ContentChat/Rotoplas.jpeg +0 -0
  97. package/src/components/organisms/Chat/ContentChat/THD.png +0 -0
  98. package/src/components/organisms/Chat/ContentChat/index.js +922 -0
  99. package/src/components/organisms/Chat/ContentChat/styles.js +41 -0
  100. package/src/components/organisms/Chat/Footer/Footer.stories.js +22 -0
  101. package/src/components/organisms/Chat/Footer/index.js +661 -0
  102. package/src/components/organisms/Chat/Footer/styles.js +286 -0
  103. package/src/components/organisms/Chat/Header/Header.stories.js +66 -0
  104. package/src/components/organisms/Chat/Header/index.js +93 -0
  105. package/src/components/organisms/Chat/Header/styles.js +49 -0
  106. package/src/components/organisms/Chat/index.js +238 -0
  107. package/src/components/organisms/Chat/styles.js +42 -0
  108. package/src/components/organisms/FullProductNameHeader/index.js +1 -0
  109. package/src/components/organisms/Modal/Modal.stories.js +55 -0
  110. package/src/components/organisms/Modal/index.js +97 -0
  111. package/src/components/organisms/Modal/styles.js +103 -0
  112. package/src/components/organisms/ProductImageModal/index.js +6 -3
  113. package/src/components/organisms/RangeCalendar/RangeCalendar.stories.js +16 -0
  114. package/src/components/organisms/RangeCalendar/index.js +121 -0
  115. package/src/components/organisms/RangeCalendar/styles.js +883 -0
  116. package/src/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +239 -32
  117. package/src/components/pages/ProviderProductEdition/index.js +87 -67
  118. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +93 -52
  119. package/src/components/pages/RetailerProductEdition/index.js +23 -21
  120. package/src/components/pages/RetailerProductEdition/utils.js +2 -1
  121. package/src/global-files/data.js +18 -23
  122. package/src/global-files/fonts.css +6 -0
  123. package/src/global-files/handle_http.js +225 -0
  124. package/src/global-files/handle_userTech.js +7 -0
  125. package/src/global-files/utils.js +330 -0
  126. package/src/global-files/variables.js +2 -0
  127. package/src/index.js +17 -0
  128. package/src/assets/fonts/roboto/LICENSE.txt +0 -202
@@ -0,0 +1,922 @@
1
+ import ReactHowler from "react-howler";
2
+ import { Container } from "./styles";
3
+ import { useEffect, useState } from "react";
4
+ import { NotFound } from "../../../atoms/NotFound";
5
+ import { Header } from "../Header";
6
+ import { faComments as IconChat } from "@fortawesome/free-solid-svg-icons";
7
+ import { Loading } from "../../../atoms/Loading";
8
+ import { ContainerItems } from "../ContainerItems";
9
+ import { Footer } from "../Footer";
10
+ import { ChatLists } from "../ChatLists";
11
+ import { CustomIcon } from "../../../atoms/CustomIcon";
12
+ import { fetchGET, fetchPOST } from "../../../../global-files/handle_http";
13
+ import {
14
+ encodeUriJson,
15
+ isStringEmpty,
16
+ isValidNaturalNumber,
17
+ } from "../../../../global-files/utils";
18
+ import newMessage from "../../../../assets/sounds/newMessage.mp3";
19
+
20
+ export const ContentChat = (props) => {
21
+ const {
22
+ chatType, // "merchant_product" | "order_product" | "ticket"
23
+ chatContainerType, // "fixed" | "popUp"
24
+ dataChat, // { data | error }
25
+ showBtnClose, // boolean
26
+ onClickBtnClose, // () => {}
27
+ showPopUpChat, // boolean
28
+ ticketCompany, // id de la compañía que creó el ticket
29
+ } = props;
30
+ const [companies, setCompanies] = useState({}); /* {
31
+ companyId: {
32
+ name: string,
33
+ statusChat: string => current | open | closed
34
+ items: [{..}] ,
35
+ enabledLoadMore: boolean
36
+ },
37
+ ...
38
+ } chat orderProduct */
39
+ const [singleChat, setSingleChat] = useState({
40
+ items: undefined,
41
+ enabledLoadMore: false,
42
+ statusChat: undefined,
43
+ }); // chat merchantProduct o ticket
44
+ const [activeCompanyId, setActiveCompanyId] = useState(); // number
45
+ const [allUsers, setAllUsers] = useState({}); // {...}
46
+ const [currentUser, setCurrentUser] = useState({
47
+ id: undefined,
48
+ companyId: undefined,
49
+ });
50
+ const [currentArticle, setCurrentArticle] = useState({
51
+ status: undefined,
52
+ version: undefined,
53
+ });
54
+ const [lastUpdateDate, setLastUpdateDate] = useState(); // string
55
+ const [isLoading, setIsLoading] = useState(true); // boolean
56
+ const [showChatsList, setShowChatsList] = useState(false); // boolean
57
+ const [processUpdateID, setProcessUpdateID] = useState(); // number
58
+ const [startUpdate, setStartUpdate] = useState(0); // number
59
+ const [runUpdate, setRunUpdate] = useState(0); // number
60
+ const [errorChat, setErrorChat] = useState({
61
+ existError: false,
62
+ code: undefined,
63
+ message: undefined,
64
+ errorDetail: undefined,
65
+ });
66
+ const [errorUpdate, setErrorUpdate] = useState({
67
+ startDate: undefined, // Date()
68
+ lastDate: undefined, // Date()
69
+ });
70
+ const [playSound, setPlaySound] = useState(false);
71
+
72
+ // matar update al desmontar el componente del chat
73
+ useEffect(() => {
74
+ return () => {
75
+ if (processUpdateID !== undefined) clearTimeout(processUpdateID);
76
+ };
77
+ }, []);
78
+ // al cargar el componente
79
+ useEffect(() => {
80
+ if (dataChat) {
81
+ stopUpdate();
82
+ if (dataChat.code) {
83
+ setErrorChat({
84
+ existError: true,
85
+ code: dataChat.code,
86
+ message: dataChat.message,
87
+ errorDetail: dataChat.errorDetail,
88
+ });
89
+ setIsLoading(false);
90
+ return;
91
+ }
92
+ if (chatType === "merchant_product") getInitialMerchantProduct();
93
+ else if (chatType === "order_product") getInitialOrderProduct();
94
+ else getInitialTicket();
95
+ }
96
+ }, [dataChat, showPopUpChat]);
97
+
98
+ // comenzar temporizador del update de 20s
99
+ useEffect(() => {
100
+ //return; -- descomentarizar para hacer pruebas sin update
101
+ if (startUpdate == 0) return;
102
+ const processID = setTimeout(() => {
103
+ setRunUpdate((prev) => prev + 1);
104
+ }, 15000);
105
+ setProcessUpdateID(processID);
106
+ return () => clearTimeout(processID);
107
+ }, [startUpdate]);
108
+
109
+ // ejecutar update
110
+ useEffect(() => {
111
+ if (chatType === "merchant_product") {
112
+ if (singleChat.items) getUpdateLatestMerchantProduct();
113
+ else getInitialMerchantProduct();
114
+ } else if (chatType === "order_product") {
115
+ if (companies) getUpdateLatestOrderProduct();
116
+ else getInitialOrderProduct();
117
+ } else {
118
+ if (singleChat.items) getUpdateLatestTicket(true);
119
+ else getInitialTicket();
120
+ }
121
+ }, [runUpdate]);
122
+
123
+ /*=======================================================================
124
+ PETICION GET INICIAL SEGUN EL TIPO DE CHAT
125
+ ======================================================================= */
126
+ const getInitialMerchantProduct = async () => {
127
+ const paramsQuery = {
128
+ getType: "initial",
129
+ id: JSON.stringify(dataChat.id),
130
+ version: JSON.stringify(dataChat.version),
131
+ };
132
+ const paramsHeaders = { Authorization: dataChat.userToken };
133
+ const response = await fetchGET(
134
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
135
+ paramsQuery,
136
+ paramsHeaders
137
+ );
138
+ if (!response.body) {
139
+ setErrorChat({
140
+ existError: true,
141
+ code: 400,
142
+ message: response.message,
143
+ errorDetail: response.errorDetail,
144
+ });
145
+ setIsLoading(false);
146
+ return;
147
+ }
148
+ // success
149
+ setCurrentUser({
150
+ id: response.body.data.currentUserId,
151
+ companyId: response.body.data.currentCompanyId,
152
+ });
153
+ setLastUpdateDate(response.body.data.lastUpdateDate);
154
+ setAllUsers(response.body.users);
155
+ setSingleChat({
156
+ items: response.body.items,
157
+ enabledLoadMore: response.body.items.length === 50,
158
+ });
159
+ setErrorChat({ existError: false });
160
+ setIsLoading(false);
161
+ };
162
+
163
+ const getInitialOrderProduct = async () => {
164
+ clearTimeout(processUpdateID); // finalizamos el temporizador
165
+ const paramsQuery = {
166
+ getType: "initial",
167
+ id: JSON.stringify(dataChat.id),
168
+ orderId: JSON.stringify(dataChat.orderId),
169
+ retailerId: JSON.stringify(dataChat.retailerId),
170
+ };
171
+ const paramsHeaders = { Authorization: dataChat.userToken };
172
+ const response = await fetchGET(
173
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
174
+ paramsQuery,
175
+ paramsHeaders
176
+ );
177
+ setStartUpdate((prev) => prev + 1); // TEMPORAL
178
+ if (!response.body) {
179
+ setErrorChat({
180
+ existError: true,
181
+ code: 400,
182
+ message: response.message,
183
+ errorDetail: response.errorDetail,
184
+ });
185
+ setIsLoading(false);
186
+ return;
187
+ }
188
+ // success
189
+ setCurrentUser({
190
+ id: response.body.data.currentUserId,
191
+ companyId: response.body.data.currentCompanyId,
192
+ });
193
+ setLastUpdateDate(response.body.data.lastUpdateDate);
194
+ setCurrentArticle({
195
+ status: response.body.data.status,
196
+ version: response.body.data.version,
197
+ });
198
+ setAllUsers(response.body.users);
199
+ const companiesList = response.body.companies;
200
+ const companiesIdList = Object.keys(companiesList);
201
+ let companyActive;
202
+ // encontrar el chat inicial a cargar y si se debe permitir cargar mas
203
+ for (const companyId of companiesIdList) {
204
+ if (companiesList[companyId].items.length < 50) {
205
+ companiesList[companyId].enabledLoadMore = false;
206
+ } else {
207
+ companiesList[companyId].enabledLoadMore = true;
208
+ }
209
+
210
+ if (companiesList[companyId].statusChat === "current") {
211
+ companyActive = Number(companyId);
212
+ }
213
+ }
214
+ if (!companyActive && companiesIdList.length) {
215
+ companyActive = Number(companiesIdList[0]);
216
+ }
217
+ setCompanies(companiesList);
218
+ if (companyActive) setActiveCompanyId(companyActive);
219
+ setErrorChat({ existError: false });
220
+ setIsLoading(false);
221
+ };
222
+
223
+ const getInitialTicket = async () => {
224
+ stopUpdate(); // finalizamos el temporizador
225
+ const dataUser = {
226
+ id: dataChat.currentUser?.id,
227
+ companyId: dataChat.currentUser?.companyId,
228
+ isUserTech: dataChat.currentUser?.isUserTech,
229
+ };
230
+ const paramsQuery = {
231
+ id: JSON.stringify(dataChat.id),
232
+ getType: "initial",
233
+ currentUser: encodeUriJson(dataUser),
234
+ currentItemsFront: encodeUriJson(getItemsIdSingleChat()),
235
+ };
236
+ const response = await fetchGET(
237
+ process.env.REACT_APP_TICKETS_CHAT_ENDPOINT,
238
+ paramsQuery,
239
+ { Authorization: dataChat.currentUser?.token }
240
+ );
241
+ // programar update en 20s
242
+ setStartUpdate((prev) => prev + 1);
243
+ if (!response.body) {
244
+ setErrorChat({
245
+ existError: true,
246
+ code: 400,
247
+ message: response.message,
248
+ errorDetail: response.errorDetail,
249
+ });
250
+ setIsLoading(false);
251
+ return;
252
+ }
253
+ // success
254
+ setLastUpdateDate(response.body.data.lastUpdateDate);
255
+ setAllUsers(response.body.users);
256
+ setSingleChat({
257
+ items: response.body.items,
258
+ enabledLoadMore: response.body.items.length === 50,
259
+ statusChat: dataChat.statusChat,
260
+ });
261
+ setErrorChat({ existError: false });
262
+ setIsLoading(false);
263
+ };
264
+
265
+ /*=======================================================================
266
+ PETICION GET LOAD_MORE SEGUN EL TIPO DE CHAT
267
+ ======================================================================= */
268
+ const getLoadMoreMerchantProduct = async () => {
269
+ clearTimeout(processUpdateID); // finalizamos el temporizador
270
+ let date = singleChat.items[singleChat.items.length - 1].date;
271
+ const paramsQuery = {
272
+ getType: "loadMore",
273
+ id: JSON.stringify(dataChat.id),
274
+ version: JSON.stringify(dataChat.version),
275
+ date: encodeURIComponent(date),
276
+ };
277
+ const response = await fetchGET(
278
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
279
+ paramsQuery
280
+ );
281
+ //setStartUpdate((prev) => prev + 1); // comendar un nuevo temporizador
282
+ if (!response.body) {
283
+ return {
284
+ title: response.message,
285
+ message: response.errorDetail,
286
+ };
287
+ }
288
+ // success
289
+ // actualizar la lista de los users
290
+ updateAllUsers(response.body.users);
291
+ // actualizar los items del chat
292
+ let newSingleChat = { ...singleChat };
293
+ newSingleChat.items = addOldItemsChat(
294
+ newSingleChat.items,
295
+ response.body.items
296
+ );
297
+ newSingleChat.enabledLoadMore = response.body.items.length === 50;
298
+ setSingleChat(newSingleChat);
299
+ };
300
+
301
+ const getLoadMoreOrderProduct = async () => {
302
+ clearTimeout(processUpdateID); // finalizamos el temporizador
303
+ let company = companies[activeCompanyId];
304
+ let date = company.items[company.items.length - 1].date;
305
+ const paramsQuery = {
306
+ getType: "loadMore",
307
+ id: JSON.stringify(dataChat.id),
308
+ orderId: JSON.stringify(dataChat.orderId),
309
+ version: JSON.stringify(currentArticle.version),
310
+ currentCompanyId: JSON.stringify(currentUser.companyId),
311
+ date: encodeURIComponent(date),
312
+ othersCompanyId: JSON.stringify([activeCompanyId]),
313
+ };
314
+ const response = await fetchGET(
315
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
316
+ paramsQuery
317
+ );
318
+ //setStartUpdate((prev) => prev + 1); // comendar un nuevo temporizador
319
+ if (!response.body) {
320
+ return {
321
+ title: response.message,
322
+ message: response.errorDetail,
323
+ };
324
+ }
325
+ // success
326
+ // actualizar la lista de los users
327
+ updateAllUsers(response.body.users);
328
+ // actualizar los items del chat y la lista de users
329
+ company.items = addOldItemsChat(company.items, response.body.items);
330
+ company.enabledLoadMore = response.body.items.length === 50;
331
+ setCompanies((prev) => ({
332
+ ...prev,
333
+ [activeCompanyId]: company,
334
+ }));
335
+ };
336
+
337
+ // este GET obtiene la lista de compañoas con las que se puede chatear
338
+ const getLoadMoreTicket = async () => {
339
+ stopUpdate(); // finalizamos el temporizador
340
+ let date = singleChat.items[singleChat.items.length - 1].date;
341
+ const dataUser = {
342
+ id: dataChat.currentUser?.id,
343
+ companyId: dataChat.currentUser?.companyId,
344
+ isUserTech: dataChat.currentUser?.isUserTech,
345
+ };
346
+ const paramsQuery = {
347
+ id: JSON.stringify(dataChat.id),
348
+ getType: "loadMore",
349
+ date: encodeURIComponent(date),
350
+ currentUser: encodeUriJson(dataUser),
351
+ currentItemsFront: encodeUriJson(getItemsIdSingleChat()),
352
+ };
353
+ const response = await fetchGET(
354
+ process.env.REACT_APP_TICKETS_CHAT_ENDPOINT,
355
+ paramsQuery,
356
+ { Authorization: dataChat.currentUser?.token }
357
+ );
358
+ //programar update en 20s
359
+ setStartUpdate((prev) => prev + 1);
360
+ if (!response.body) {
361
+ return {
362
+ title: response.message,
363
+ message: response.errorDetail,
364
+ };
365
+ }
366
+ // success
367
+ // actualizar la lista de los users
368
+ updateAllUsers(response.body.users);
369
+ // actualizar los items del chat
370
+ let newSingleChat = { ...singleChat };
371
+ newSingleChat.items = addOldItemsChat(
372
+ newSingleChat.items,
373
+ response.body.items
374
+ );
375
+ newSingleChat.enabledLoadMore = response.body.items.length === 50;
376
+ setSingleChat(newSingleChat);
377
+ };
378
+
379
+ /*=======================================================================
380
+ PETICION GET UPDATE_LATEST SEGUN EL TIPO DE CHAT
381
+ ======================================================================= */
382
+ const getUpdateLatestMerchantProduct = async () => {
383
+ const paramsQuery = {
384
+ getType: "updateLatest",
385
+ id: JSON.stringify(dataChat.id),
386
+ version: JSON.stringify(dataChat.version),
387
+ date: encodeURIComponent(lastUpdateDate),
388
+ };
389
+ const response = await fetchGET(
390
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
391
+ paramsQuery
392
+ );
393
+ if (!response.body) {
394
+ console.log("ERROR updateLatest:", {
395
+ message: response.message,
396
+ errorDetail: response.errorDetail,
397
+ });
398
+ return;
399
+ }
400
+ // success
401
+ setLastUpdateDate(response.body.data.lastUpdateDate);
402
+ // actualizar la lista de los users
403
+ updateAllUsers(response.body.users);
404
+ // actualizar los items del chat
405
+ let newSingleChat = { ...singleChat };
406
+ newSingleChat.items = addNewItemsChat(
407
+ newSingleChat.items,
408
+ response.body.items
409
+ );
410
+ setSingleChat(newSingleChat);
411
+ };
412
+
413
+ const getUpdateLatestOrderProduct = async () => {
414
+ const paramsQuery = {
415
+ getType: "updateLatest",
416
+ id: JSON.stringify(dataChat.id),
417
+ orderId: JSON.stringify(dataChat.orderId),
418
+ retailerId: JSON.stringify(dataChat.retailerId),
419
+ version: JSON.stringify(currentArticle.version),
420
+ status: currentArticle.status,
421
+ currentCompanyId: JSON.stringify(currentUser.companyId),
422
+ othersCompanyId: encodeURIComponent(
423
+ JSON.stringify(Object.keys(companies))
424
+ ),
425
+ date: encodeURIComponent(lastUpdateDate),
426
+ };
427
+ const response = await fetchGET(
428
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
429
+ paramsQuery
430
+ );
431
+ if (!response.body) {
432
+ console.log("ERROR update: ", {
433
+ message: response.message,
434
+ errorDetail: response.errorDetail,
435
+ });
436
+ return;
437
+ }
438
+ // success
439
+
440
+ // cuando cambie la lista de chats por un cambio de version o estatus
441
+ if (response.body.data.status) {
442
+ setIsLoading(true);
443
+ setTimeout(() => {
444
+ setLastUpdateDate(response.body.data.lastUpdateDate);
445
+ setCurrentArticle({
446
+ status: response.body.data.status,
447
+ version: response.body.data.version,
448
+ });
449
+ setAllUsers(response.body.users);
450
+ const companiesList = response.body.companies;
451
+ const companiesIdList = Object.keys(companiesList);
452
+ let companyActive;
453
+ // encontrar el chat inicial a cargar y si se debe permitir cargar mas
454
+ for (const companyId of companiesIdList) {
455
+ if (companiesList[companyId].items.length < 50) {
456
+ companiesList[companyId].enabledLoadMore = false;
457
+ } else {
458
+ companiesList[companyId].enabledLoadMore = true;
459
+ }
460
+
461
+ if (companiesList[companyId].statusChat === "current") {
462
+ companyActive = Number(companyId);
463
+ }
464
+ }
465
+ if (!companyActive && companiesIdList.length) {
466
+ companyActive = Number(companiesIdList[0]);
467
+ }
468
+ setCompanies(companiesList);
469
+ if (companyActive) setActiveCompanyId(companyActive);
470
+ setErrorChat({ existError: false });
471
+ setIsLoading(false);
472
+ }, 2000);
473
+ }
474
+ // cuando se hizo un update de los mismos chats
475
+ else {
476
+ setLastUpdateDate(response.body.data.lastUpdateDate);
477
+ // actualizar la lista de los users
478
+ updateAllUsers(response.body.users);
479
+ // actualizar los items de los chats
480
+ let companiesList = { ...companies };
481
+ Object.keys(response.body.companies).forEach((companyId) => {
482
+ companiesList[companyId].items = addNewItemsChat(
483
+ companiesList[companyId].items,
484
+ response.body.companies[companyId].items
485
+ );
486
+ });
487
+ setCompanies(companiesList);
488
+ }
489
+ };
490
+
491
+ const getUpdateLatestTicket = async (fromUpdate = false) => {
492
+ if (singleChat.statusChat === "closed") return;
493
+ const dataUser = {
494
+ id: dataChat.currentUser?.id,
495
+ companyId: dataChat.currentUser?.companyId,
496
+ isUserTech: dataChat.currentUser?.isUserTech,
497
+ };
498
+ const paramsQuery = {
499
+ id: JSON.stringify(dataChat.id),
500
+ getType: "updateLatest",
501
+ date: encodeURIComponent(lastUpdateDate),
502
+ currentUser: encodeUriJson(dataUser),
503
+ currentItemsFront: encodeUriJson(getItemsIdSingleChat()),
504
+ };
505
+ const response = await fetchGET(
506
+ process.env.REACT_APP_TICKETS_CHAT_ENDPOINT,
507
+ paramsQuery,
508
+ { Authorization: dataChat.currentUser?.token }
509
+ );
510
+ //programar update en 20s
511
+ setStartUpdate((prev) => prev + 1);
512
+ if (!response.body) {
513
+ if (errorUpdate.startDate) {
514
+ setErrorUpdate((prev) => ({
515
+ ...prev,
516
+ lastDate: new Date(),
517
+ }));
518
+ } else {
519
+ setErrorUpdate((prev) => ({
520
+ startDate: new Date(),
521
+ }));
522
+ }
523
+ console.log("ERROR updateLatest:", {
524
+ message: response.message,
525
+ errorDetail: response.errorDetail,
526
+ });
527
+ return;
528
+ }
529
+ // limpiar error update
530
+ if (errorUpdate.startDate) {
531
+ setErrorUpdate({});
532
+ }
533
+ // success
534
+ setLastUpdateDate(response.body.data.lastUpdateDate);
535
+ // actualizar la lista de los users
536
+ updateAllUsers(response.body.users);
537
+ // actualizar los items del chat
538
+ if (response.body.items.length === 0) return;
539
+ let newSingleChat = { ...singleChat };
540
+ newSingleChat.items = addNewItemsChat(
541
+ newSingleChat.items,
542
+ response.body.items,
543
+ fromUpdate
544
+ );
545
+ newSingleChat.statusChat = response.body.data.statusChat;
546
+
547
+ setSingleChat(newSingleChat);
548
+ };
549
+
550
+ /*=======================================================================
551
+ FUNCION QUE EJECUTA EL MICROSERVICIO CREATE-ITEM
552
+ Este metodo recibe los items que queremos agregar al chat.
553
+ requiere:
554
+ => items: [ { type , value } , ... ]
555
+ NOTA: si se quiere agregar un mensaje mandar un array con un object
556
+ example: [ {
557
+ type: "message" ,
558
+ value: "mi mensaje"
559
+ } ]
560
+ ======================================================================= */
561
+ const createItemsChat = async (items = []) => {
562
+ if (items.length === 0) {
563
+ return {
564
+ message:
565
+ "No se especifico ningun mensaje, imagen o archivo nuevo " +
566
+ "que se quiera enviar al chat",
567
+ errorDetail: "Reporta esto a TI",
568
+ };
569
+ }
570
+ for (const item of items) {
571
+ if (!["message", "img", "file"].includes(item.type)) {
572
+ return {
573
+ message:
574
+ "Uno de los elementos que se quiere enviar al chat " +
575
+ `no es un tipo valido "${item.type}"`,
576
+ errorDetail: "Reporta esto a TI",
577
+ };
578
+ }
579
+ if (isStringEmpty(item.value)) {
580
+ return {
581
+ message:
582
+ "Uno de los elementos que se quiere enviar al chat " +
583
+ `contiene un valor vacio`,
584
+ errorDetail: "Reporta esto a TI",
585
+ };
586
+ }
587
+ }
588
+ let errorCreate;
589
+ stopUpdate(); // finalizamos el temporizador
590
+
591
+ // enviar items a la BD
592
+ if (chatType === "merchant_product") {
593
+ errorCreate = await createItemsMerchantProduct(items);
594
+ } else if (chatType === "order_product") {
595
+ errorCreate = await createItemsOrderProduct(items);
596
+ } else errorCreate = await createItemsTicket(items);
597
+
598
+ // actualizar chat para que aparezcan los items enviados
599
+ if (chatType === "merchant_product") {
600
+ await getUpdateLatestMerchantProduct();
601
+ } else if (chatType === "order_product") {
602
+ await getUpdateLatestOrderProduct();
603
+ } else await getUpdateLatestTicket();
604
+
605
+ // cuando no se pudieron guardar los items
606
+ if (errorCreate) {
607
+ return errorCreate;
608
+ }
609
+ };
610
+
611
+ const createItemsMerchantProduct = async (items = []) => {
612
+ const paramsBody = {
613
+ id: JSON.stringify(dataChat.id),
614
+ version: JSON.stringify(dataChat.version),
615
+ userId: JSON.stringify(currentUser.id),
616
+ items: JSON.stringify(items),
617
+ };
618
+ const response = await fetchPOST(
619
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
620
+ paramsBody
621
+ );
622
+ if (!response.body) {
623
+ return {
624
+ message: response.message,
625
+ errorDetail: response.errorDetail,
626
+ };
627
+ }
628
+ };
629
+
630
+ const createItemsOrderProduct = async (items = []) => {
631
+ const paramsBody = {
632
+ id: JSON.stringify(dataChat.id),
633
+ version: JSON.stringify(currentArticle.version),
634
+ userId: JSON.stringify(currentUser.id),
635
+ items: JSON.stringify(items),
636
+ orderId: JSON.stringify(dataChat.orderId),
637
+ sentCompanyId: JSON.stringify(currentUser.companyId),
638
+ receivedCompanyId: JSON.stringify(activeCompanyId),
639
+ };
640
+ const response = await fetchPOST(
641
+ process.env.REACT_APP_PRODUCTS_CHAT_ENDPOINT,
642
+ paramsBody
643
+ );
644
+ if (!response.body) {
645
+ return {
646
+ message: response.message,
647
+ errorDetail: response.errorDetail,
648
+ };
649
+ }
650
+ };
651
+
652
+ const createItemsTicket = async (items = []) => {
653
+ const paramsBody = {
654
+ id: JSON.stringify(dataChat.id),
655
+ userId: JSON.stringify(dataChat.currentUser.id),
656
+ items: JSON.stringify(items),
657
+ };
658
+ const response = await fetchPOST(
659
+ process.env.REACT_APP_TICKETS_CHAT_ENDPOINT,
660
+ paramsBody
661
+ );
662
+ if (!response.body) {
663
+ return {
664
+ message: response.message,
665
+ errorDetail: response.errorDetail,
666
+ };
667
+ }
668
+ };
669
+
670
+ /*=======================================================================
671
+ SECCION DE FUNCIONES
672
+ ======================================================================= */
673
+ const isSingleChat = () => {
674
+ if (chatType === "merchant_product" || chatType === "ticket") {
675
+ return true;
676
+ }
677
+ if (companies && Object.keys(companies).length < 2) return true;
678
+ else return false;
679
+ };
680
+
681
+ const getItemsIdSingleChat = () => {
682
+ const itemsId = {};
683
+ if (Array.isArray(singleChat.items)) {
684
+ singleChat.items.forEach((item) => {
685
+ if (isValidNaturalNumber(item.id)) itemsId[item.id] = true;
686
+ });
687
+ }
688
+ return itemsId;
689
+ };
690
+
691
+ const getChatCompany = () => {
692
+ if (chatType === "merchant_product" || chatType === "ticket") {
693
+ return undefined;
694
+ }
695
+ if (companies && companies[activeCompanyId]) {
696
+ return {
697
+ ...companies[activeCompanyId],
698
+ id: activeCompanyId,
699
+ };
700
+ }
701
+ return undefined;
702
+ };
703
+
704
+ const addOldItemsChat = (currentItems = [], newItems = []) => {
705
+ let items = currentItems.slice();
706
+ let itemsId = {};
707
+ items.forEach((item) => {
708
+ itemsId[item.id] = true;
709
+ });
710
+ newItems.forEach((item) => {
711
+ if (!itemsId[item.id]) {
712
+ items.push(item);
713
+ itemsId[item.id] = true;
714
+ }
715
+ });
716
+ return items;
717
+ };
718
+
719
+ const addNewItemsChat = (
720
+ currentItems = [],
721
+ newItems = [],
722
+ fromUpdate = false
723
+ ) => {
724
+ let itemsId = {};
725
+ currentItems.forEach((item) => {
726
+ itemsId[item.id] = item;
727
+ });
728
+ let thereAreNewItems = false;
729
+ newItems.forEach((newitem) => {
730
+ if (!itemsId[newitem.id]) {
731
+ itemsId[newitem.id] = newitem;
732
+ thereAreNewItems = true;
733
+ }
734
+ });
735
+ if (thereAreNewItems && fromUpdate) {
736
+ setPlaySound(true);
737
+ setTimeout(() => {
738
+ setPlaySound(false);
739
+ }, 5000);
740
+ }
741
+ return Object.values(itemsId).sort((a, b) => {
742
+ if (a.id < b.id) return 1;
743
+ if (a.id > b.id) return -1;
744
+ return 0;
745
+ });
746
+ };
747
+
748
+ const updateAllUsers = (newUsers = {}) => {
749
+ let currentUsers = { ...allUsers };
750
+ Object.keys(newUsers).forEach((userId) => {
751
+ if (!currentUsers[userId]) {
752
+ currentUsers[userId] = newUsers[userId];
753
+ }
754
+ });
755
+ setAllUsers(currentUsers);
756
+ };
757
+
758
+ const stopUpdate = () => {
759
+ if (processUpdateID !== undefined) {
760
+ clearTimeout(processUpdateID);
761
+ setProcessUpdateID(undefined);
762
+ }
763
+ };
764
+
765
+ const renderBodyChat = () => {
766
+ if (isLoading) return <Loading />;
767
+ if (errorChat.existError) {
768
+ return (
769
+ <NotFound
770
+ code={errorChat.code}
771
+ message={errorChat.message}
772
+ details={errorChat.errorDetail}
773
+ />
774
+ );
775
+ }
776
+ // cuando se quiere ver la lista de chats
777
+ if (showChatsList) {
778
+ return (
779
+ <ChatLists
780
+ companies={companies}
781
+ currentCompanyId={currentUser?.companyId}
782
+ onClickCompany={(companyIdSelected) => {
783
+ setActiveCompanyId(Number(companyIdSelected));
784
+ setShowChatsList(false);
785
+ }}
786
+ />
787
+ );
788
+ }
789
+ // mostrar chat?
790
+ let items;
791
+ let enabledLoadMore;
792
+ if (["merchant_product", "ticket"].includes(chatType)) {
793
+ items = singleChat.items;
794
+ enabledLoadMore = singleChat.enabledLoadMore;
795
+ }
796
+ // ORDER_PRODUCT
797
+ else if (companies) {
798
+ // caso 0 chats
799
+ if (Object.keys(companies).length === 0) {
800
+ return (
801
+ <div className="container-chatEmpty">
802
+ <CustomIcon
803
+ className="icon-chat"
804
+ transparent
805
+ size={35}
806
+ icon={IconChat}
807
+ type={"gray"}
808
+ />
809
+ <label>
810
+ De acuerdo al estatus del producto, tu compañia no tiene
811
+ disponible ningun chat abierto o cerrado
812
+ </label>
813
+ </div>
814
+ );
815
+ }
816
+ // caso 1 o mas chats
817
+ if (companies[activeCompanyId]) {
818
+ items = companies[activeCompanyId].items;
819
+ enabledLoadMore = companies[activeCompanyId].enabledLoadMore;
820
+ }
821
+ }
822
+ if (items) {
823
+ let containerItems = null;
824
+ if (items.length) {
825
+ containerItems = (
826
+ <ContainerItems
827
+ items={items}
828
+ users={allUsers}
829
+ showBtnLoadMore={enabledLoadMore}
830
+ chatType={chatType}
831
+ activeCompanyId={activeCompanyId}
832
+ ticketCompany={ticketCompany}
833
+ currentUser={
834
+ ["merchant_product", "order_product"].includes(chatType)
835
+ ? currentUser
836
+ : dataChat.currentUser
837
+ }
838
+ onClickBtnLoadMore={
839
+ chatType === "merchant_product"
840
+ ? getLoadMoreMerchantProduct
841
+ : chatType === "order_product"
842
+ ? getLoadMoreOrderProduct
843
+ : getLoadMoreTicket
844
+ }
845
+ />
846
+ );
847
+ } else {
848
+ containerItems = (
849
+ <div className="container-chatEmpty">
850
+ <CustomIcon
851
+ className="icon-chat"
852
+ size={35}
853
+ icon={IconChat}
854
+ type={"gray"}
855
+ transparent
856
+ />
857
+ <label>Este chat no tiene mensajes</label>
858
+ </div>
859
+ );
860
+ }
861
+ return (
862
+ <>
863
+ {containerItems}
864
+ <Footer
865
+ chatType={chatType}
866
+ dataChat={
867
+ chatType === "merchant_product"
868
+ ? { id: dataChat.id, version: dataChat.version }
869
+ : chatType === "order_product"
870
+ ? { id: dataChat.id, version: currentArticle.version }
871
+ : chatType === "ticket"
872
+ ? { id: dataChat.id }
873
+ : undefined
874
+ }
875
+ chatCompany={getChatCompany()}
876
+ statusChat={
877
+ chatType === "order_product"
878
+ ? getChatCompany()?.statusChat
879
+ : chatType === "ticket"
880
+ ? singleChat.statusChat
881
+ : undefined
882
+ }
883
+ messageDisabled={
884
+ chatType === "order_product"
885
+ ? `La conversación con ${getChatCompany()?.name} ha finalizado`
886
+ : chatType === "ticket"
887
+ ? "Ticket cerrado"
888
+ : `La conversación ha finalizado`
889
+ }
890
+ createItemsChat={createItemsChat}
891
+ errorUpdate={errorUpdate}
892
+ />
893
+ </>
894
+ );
895
+ }
896
+ return <Loading />;
897
+ };
898
+
899
+ return (
900
+ <>
901
+ <Container>
902
+ {/* header */}
903
+ {(chatContainerType !== "fixed" || !isSingleChat()) && (
904
+ <Header
905
+ showBtnClose={showBtnClose}
906
+ onClickBtnClose={onClickBtnClose}
907
+ showChatsList={showChatsList}
908
+ chatCompany={getChatCompany()}
909
+ multipleCompanies={!isSingleChat()}
910
+ onClickBtnChooseChat={() => {
911
+ setShowChatsList(true);
912
+ }}
913
+ />
914
+ )}
915
+
916
+ {/* body */}
917
+ {renderBodyChat()}
918
+ </Container>
919
+ <ReactHowler src={newMessage} playing={playSound} />
920
+ </>
921
+ );
922
+ };