contentoh-components-library 21.0.72 → 21.0.75

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 (196) hide show
  1. package/.env.development +21 -4
  2. package/.env.production +19 -2
  3. package/CHANGELOG.md +37 -0
  4. package/dist/assets/images/generalButton/downloadIcon.svg +3 -0
  5. package/dist/assets/images/genericModal/closeWhite.svg +3 -0
  6. package/dist/assets/images/genericModal/errorModal.svg +3 -0
  7. package/dist/assets/images/genericModal/yellowAlert.svg +12 -0
  8. package/dist/assets/images/modalsSVGs/attributesSent.svg +208 -0
  9. package/dist/assets/images/modalsSVGs/descriptionSent.svg +237 -0
  10. package/dist/assets/images/modalsSVGs/providerSent.svg +445 -0
  11. package/dist/assets/images/modalsSVGs/uploadingImages.svg +148 -0
  12. package/dist/components/atoms/AsignationOption/index.js +9 -5
  13. package/dist/components/atoms/AsignationOption/styles.js +1 -1
  14. package/dist/components/{molecules/SignInLoginCreationApp/SignInLogin.stories.js → atoms/CharCounter/CharCounter.stories.js} +10 -7
  15. package/dist/components/atoms/CharCounter/index.js +22 -0
  16. package/dist/components/{molecules/ApproveRejetPanel → atoms/CharCounter}/styles.js +3 -1
  17. package/dist/components/atoms/CheckBox/index.js +4 -2
  18. package/dist/components/atoms/Commentary/Commentary.stories.js +1 -0
  19. package/dist/components/atoms/Commentary/index.js +23 -0
  20. package/dist/components/atoms/Commentary/styles.js +23 -0
  21. package/dist/components/atoms/GeneralButton/index.js +5 -0
  22. package/dist/components/atoms/GeneralButton/styles.js +4 -2
  23. package/dist/components/atoms/GeneralInput/index.js +72 -24
  24. package/dist/components/atoms/GeneralInput/styles.js +7 -1
  25. package/dist/components/atoms/GenericModal/index.js +4 -2
  26. package/dist/components/atoms/GenericModal/styles.js +1 -1
  27. package/dist/components/atoms/Input/index.js +26 -0
  28. package/dist/components/atoms/Input/style.js +26 -0
  29. package/dist/components/atoms/InputFormatter/Wysiwyg.stories.js +30 -0
  30. package/dist/components/atoms/InputFormatter/index.js +184 -0
  31. package/dist/components/atoms/InputFormatter/styles.js +33 -0
  32. package/dist/components/atoms/LabelToInput/index.js +53 -0
  33. package/dist/components/atoms/LabelToInput/style.js +22 -0
  34. package/dist/components/atoms/Percent/Percent.stories.js +39 -0
  35. package/dist/components/atoms/Percent/index.js +39 -0
  36. package/dist/components/atoms/Percent/styles.js +20 -0
  37. package/dist/components/atoms/PriorityFlag/index.js +1 -1
  38. package/dist/components/atoms/ProductImage/styles.js +1 -1
  39. package/dist/components/atoms/ProgressBar/index.js +2 -2
  40. package/dist/components/atoms/ProgressBar/styles.js +3 -5
  41. package/dist/components/atoms/ScreenHeader/index.js +1 -1
  42. package/dist/components/atoms/ScreenHeader/styles.js +1 -1
  43. package/dist/components/atoms/Select/index.js +39 -0
  44. package/dist/components/atoms/Select/style.js +32 -0
  45. package/dist/components/atoms/StatusTag/index.js +37 -2
  46. package/dist/components/atoms/StatusTag/styles.js +1 -1
  47. package/dist/components/atoms/ValidationPanel/index.js +5 -3
  48. package/dist/components/atoms/VerticalSideMenuMainPage/index.js +15 -10
  49. package/dist/components/atoms/VerticalSideMenuMainPage/styles.js +1 -1
  50. package/dist/components/molecules/AvatarAndValidation/index.js +17 -7
  51. package/dist/components/molecules/AvatarAndValidation/styles.js +1 -1
  52. package/dist/components/molecules/FeaturesBar/index.js +1 -1
  53. package/dist/components/molecules/GalleryElement/index.js +80 -21
  54. package/dist/components/molecules/GalleryElement/styles.js +1 -1
  55. package/dist/components/molecules/GalleryHeader/index.js +28 -6
  56. package/dist/components/molecules/GalleryHeader/styles.js +1 -1
  57. package/dist/components/molecules/ImageSelector/index.js +2 -4
  58. package/dist/components/molecules/ProductNameHeader/index.js +1 -2
  59. package/dist/components/molecules/RetailerSelector/RetailerSelector.stories.js +48 -0
  60. package/dist/components/molecules/RetailerSelector/index.js +74 -0
  61. package/dist/components/{atoms/MenuCommercialRetailers → molecules/RetailerSelector}/styles.js +1 -1
  62. package/dist/components/molecules/StatusAsignationInfo/index.js +46 -28
  63. package/dist/components/molecules/StatusAsignationInfo/styles.js +1 -1
  64. package/dist/components/molecules/TableHeader/index.js +12 -5
  65. package/dist/components/molecules/TableHeader/styles.js +1 -1
  66. package/dist/components/molecules/TagAndInput/index.js +24 -0
  67. package/dist/components/molecules/TextAndGradient/TextAndGradient.stories.js +31 -0
  68. package/dist/components/molecules/TextAndGradient/index.js +36 -0
  69. package/dist/components/molecules/TextAndGradient/styles.js +18 -0
  70. package/dist/components/organisms/FullProductNameHeader/index.js +31 -9
  71. package/dist/components/organisms/FullTabsMenu/index.js +18 -5
  72. package/dist/components/organisms/GlobalModal/index.js +73 -0
  73. package/dist/components/organisms/GlobalModal/styles.js +66 -0
  74. package/dist/components/organisms/ImageDataTable/index.js +90 -14
  75. package/dist/components/organisms/InputGroup/index.js +34 -13
  76. package/dist/components/organisms/InputGroup/styles.js +1 -1
  77. package/dist/components/organisms/ProductImageModal/index.js +13 -10
  78. package/dist/components/organisms/ProductImageModal/styles.js +1 -1
  79. package/dist/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +135 -0
  80. package/dist/components/pages/ProviderProductEdition/index.js +1979 -0
  81. package/dist/components/pages/ProviderProductEdition/styles.js +23 -0
  82. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +91 -347
  83. package/dist/components/pages/RetailerProductEdition/index.js +1610 -60
  84. package/dist/components/pages/RetailerProductEdition/styles.js +1 -1
  85. package/dist/global-files/data.js +213 -53
  86. package/dist/global-files/global-styles.css +1 -0
  87. package/dist/global-files/variables.js +1 -0
  88. package/dist/index.js +13 -0
  89. package/package.json +16 -9
  90. package/src/assets/images/generalButton/downloadIcon.svg +3 -0
  91. package/src/assets/images/genericModal/closeWhite.svg +3 -0
  92. package/src/assets/images/genericModal/errorModal.svg +3 -0
  93. package/src/assets/images/genericModal/yellowAlert.svg +12 -0
  94. package/src/assets/images/modalsSVGs/attributesSent.svg +208 -0
  95. package/src/assets/images/modalsSVGs/descriptionSent.svg +237 -0
  96. package/src/assets/images/modalsSVGs/providerSent.svg +445 -0
  97. package/src/assets/images/modalsSVGs/uploadingImages.svg +148 -0
  98. package/src/components/atoms/AsignationOption/index.js +7 -5
  99. package/src/components/atoms/AsignationOption/styles.js +9 -1
  100. package/src/components/atoms/CharCounter/CharCounter.stories.js +11 -0
  101. package/src/components/atoms/CharCounter/index.js +13 -0
  102. package/src/components/atoms/CharCounter/styles.js +10 -0
  103. package/src/components/atoms/CheckBox/index.js +8 -2
  104. package/src/components/atoms/Commentary/Commentary.stories.js +0 -0
  105. package/src/components/atoms/Commentary/index.js +9 -0
  106. package/src/components/atoms/Commentary/styles.js +16 -0
  107. package/src/components/atoms/GeneralButton/index.js +9 -2
  108. package/src/components/atoms/GeneralButton/styles.js +23 -0
  109. package/src/components/atoms/GeneralInput/index.js +71 -22
  110. package/src/components/atoms/GeneralInput/styles.js +11 -1
  111. package/src/components/atoms/GenericModal/index.js +2 -2
  112. package/src/components/atoms/GenericModal/styles.js +10 -2
  113. package/src/components/atoms/Input/index.js +15 -0
  114. package/src/components/atoms/Input/style.js +31 -0
  115. package/src/components/atoms/InputFormatter/Wysiwyg.stories.js +12 -0
  116. package/src/components/atoms/InputFormatter/index.js +144 -0
  117. package/src/components/atoms/InputFormatter/styles.js +40 -0
  118. package/src/components/atoms/LabelToInput/index.js +26 -0
  119. package/src/components/atoms/LabelToInput/style.js +41 -0
  120. package/src/components/atoms/PriorityFlag/index.js +1 -1
  121. package/src/components/atoms/ProductImage/styles.js +1 -1
  122. package/src/components/atoms/ProgressBar/index.js +2 -2
  123. package/src/components/atoms/ProgressBar/styles.js +54 -3
  124. package/src/components/atoms/ScreenHeader/index.js +7 -3
  125. package/src/components/atoms/ScreenHeader/styles.js +9 -2
  126. package/src/components/atoms/Select/index.js +35 -0
  127. package/src/components/atoms/Select/style.js +76 -0
  128. package/src/components/atoms/StatusTag/index.js +30 -2
  129. package/src/components/atoms/StatusTag/styles.js +15 -3
  130. package/src/components/atoms/ValidationPanel/index.js +4 -3
  131. package/src/components/atoms/VerticalSideMenuMainPage/index.js +15 -11
  132. package/src/components/atoms/VerticalSideMenuMainPage/styles.js +8 -7
  133. package/src/components/molecules/AvatarAndValidation/index.js +23 -6
  134. package/src/components/molecules/AvatarAndValidation/styles.js +1 -1
  135. package/src/components/molecules/FeaturesBar/index.js +10 -7
  136. package/src/components/molecules/GalleryElement/index.js +75 -36
  137. package/src/components/molecules/GalleryElement/styles.js +38 -11
  138. package/src/components/molecules/GalleryHeader/index.js +14 -8
  139. package/src/components/molecules/GalleryHeader/styles.js +16 -0
  140. package/src/components/molecules/ImageSelector/index.js +2 -3
  141. package/src/components/molecules/ProductNameHeader/index.js +1 -2
  142. package/src/components/molecules/RetailerSelector/RetailerSelector.stories.js +35 -0
  143. package/src/components/molecules/RetailerSelector/index.js +63 -0
  144. package/src/components/molecules/RetailerSelector/styles.js +18 -0
  145. package/src/components/molecules/StatusAsignationInfo/index.js +64 -39
  146. package/src/components/molecules/StatusAsignationInfo/styles.js +12 -2
  147. package/src/components/molecules/TableHeader/index.js +16 -3
  148. package/src/components/molecules/TableHeader/styles.js +5 -0
  149. package/src/components/molecules/TagAndInput/index.js +24 -0
  150. package/src/components/organisms/FullProductNameHeader/index.js +38 -8
  151. package/src/components/organisms/FullTabsMenu/index.js +15 -3
  152. package/src/components/organisms/GlobalModal/index.js +68 -0
  153. package/src/components/organisms/GlobalModal/styles.js +113 -0
  154. package/src/components/organisms/ImageDataTable/index.js +89 -11
  155. package/src/components/organisms/InputGroup/index.js +46 -11
  156. package/src/components/organisms/InputGroup/styles.js +3 -0
  157. package/src/components/organisms/ProductImageModal/index.js +19 -12
  158. package/src/components/organisms/ProductImageModal/styles.js +3 -0
  159. package/src/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +123 -0
  160. package/src/components/pages/ProviderProductEdition/index.js +1493 -0
  161. package/src/components/pages/ProviderProductEdition/styles.js +118 -0
  162. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +91 -343
  163. package/src/components/pages/RetailerProductEdition/index.js +1245 -48
  164. package/src/components/pages/RetailerProductEdition/styles.js +67 -4
  165. package/src/global-files/data.js +158 -57
  166. package/src/global-files/global-styles.css +1 -0
  167. package/src/global-files/variables.js +1 -0
  168. package/src/index.js +1 -0
  169. package/dist/assets/images/editField/showPassword.png +0 -0
  170. package/dist/assets/images/sliderToolTip/infoIcon.svg +0 -4
  171. package/dist/assets/images/sliderToolTip/slide1.svg +0 -5
  172. package/dist/assets/images/sliderToolTip/slide2.svg +0 -9
  173. package/dist/assets/images/sliderToolTip/slide3.svg +0 -9
  174. package/dist/assets/images/sliderToolTip/slide4.svg +0 -9
  175. package/dist/assets/images/sliderToolTip/slide5.svg +0 -40
  176. package/dist/assets/images/verticalSideMenuMainPage/closeMenu.svg +0 -4
  177. package/dist/assets/images/verticalSideMenuMainPage/iconFAQS.svg +0 -12
  178. package/dist/assets/images/verticalSideMenuMainPage/iconGroup.svg +0 -3
  179. package/dist/assets/images/verticalSideMenuMainPage/iconLogo.svg +0 -12
  180. package/dist/assets/images/verticalSideMenuMainPage/iconLogoContentoh.svg +0 -15
  181. package/dist/assets/images/verticalSideMenuMainPage/iconProduct.svg +0 -3
  182. package/dist/assets/images/verticalSideMenuMainPage/iconSpeedometer.svg +0 -12
  183. package/dist/assets/images/verticalSideMenuMainPage/iconTask.svg +0 -10
  184. package/dist/assets/images/verticalSideMenuMainPage/openMenu.svg +0 -4
  185. package/dist/components/atoms/ListCommercialRetailers/ListCommercialRetailers.stories.js +0 -36
  186. package/dist/components/atoms/ListCommercialRetailers/index.js +0 -64
  187. package/dist/components/atoms/ListCommercialRetailers/styles.js +0 -20
  188. package/dist/components/atoms/MenuCommercialRetailers/MenuCommercialRetailers.stories.js +0 -37
  189. package/dist/components/atoms/MenuCommercialRetailers/index.js +0 -25
  190. package/dist/components/atoms/MenuProductImage/MenuProductImage.stories.js +0 -28
  191. package/dist/components/atoms/MenuProductImage/index.js +0 -88
  192. package/dist/components/atoms/MenuProductImage/styles.js +0 -20
  193. package/dist/components/molecules/ApproveRejetPanel/ApproveRejetPanel.stories.js +0 -25
  194. package/dist/components/molecules/ApproveRejetPanel/index.js +0 -49
  195. package/dist/components/molecules/SignInLoginCreationApp/index.js +0 -270
  196. package/dist/components/molecules/SignInLoginCreationApp/styles.js +0 -20
@@ -0,0 +1,1493 @@
1
+ import { Container } from "./styles";
2
+ import { HeaderTop } from "../../molecules/HeaderTop";
3
+ import { ImagePreviewer } from "../../organisms/ImagePreviewer";
4
+ import { ImageDataTable } from "../../organisms/ImageDataTable";
5
+ import { FullProductNameHeader } from "../../organisms/FullProductNameHeader";
6
+ import { FullTabsMenu } from "../../organisms/FullTabsMenu";
7
+ import { InputGroup } from "../../organisms/InputGroup";
8
+ import { useEffect, useReducer, useState, useCallback } from "react";
9
+ import { GalleryElement } from "../../molecules/GalleryElement";
10
+ import { saveAs } from "file-saver";
11
+ import {
12
+ getRetailerServices,
13
+ getPercentage,
14
+ fetchUsers,
15
+ } from "../../../global-files/data";
16
+ import { GalleryHeader } from "../../molecules/GalleryHeader";
17
+ import { ProductImageModal } from "../../organisms/ProductImageModal";
18
+ import { useDropzone } from "react-dropzone";
19
+ import axios from "axios";
20
+ import { v4 as uuidv4 } from "uuid";
21
+ import AWS from "aws-sdk";
22
+ import attributesSent from "../../../assets/images/modalsSVGs/attributesSent.svg";
23
+ import descriptionSent from "../../../assets/images/modalsSVGs/descriptionSent.svg";
24
+ import imagesSent from "../../../assets/images/modalsSVGs/uploadingImages.svg";
25
+ import { TagAndInput } from "../../molecules/TagAndInput/index";
26
+ import { Button } from "../../atoms/GeneralButton";
27
+ import { Commentary } from "../../atoms/Commentary";
28
+ import { GenericModal } from "../../atoms/GenericModal";
29
+ import { ScreenHeader } from "../../atoms/ScreenHeader";
30
+ import { Loading } from "../../atoms/Loading";
31
+ import succes from "../../../assets/images/genericModal/genericModalCheck.svg";
32
+ import { Link } from "react-router-dom";
33
+ import face from "../../../assets/images/defaultImages/defaultProfileImage.svg";
34
+ import errorModal from "../../../assets/images/genericModal/errorModal.svg";
35
+ import { GlobalModal } from "../../organisms/GlobalModal/index";
36
+
37
+ const reducerImages = (state, action) => {
38
+ let { values, attrForImgs } = state;
39
+ switch (action.action) {
40
+ case "init":
41
+ return action.init;
42
+ case "addImg":
43
+ values = [...values, action.img];
44
+ return { ...state, values };
45
+ case "changeImageInfo":
46
+ values[action.index][action.attribute] = action.value;
47
+ return { ...state, values };
48
+ case "changeAttrValue":
49
+ attrForImgs[action.retailer][action.index].value = action.value;
50
+ return { ...state, attrForImgs, values };
51
+ default:
52
+ return state;
53
+ }
54
+ };
55
+
56
+ const S3_BUCKET = process.env.REACT_APP_IMAGES_BUCKET;
57
+ const REGION = "us-east-1";
58
+
59
+ AWS.config.update({
60
+ accessKeyId: process.env.REACT_APP_KEY_UPLOAD_TO_S3,
61
+ secretAccessKey: process.env.REACT_APP_ACCESS_KEY_UPLOAD_TO_S3,
62
+ });
63
+
64
+ const myBucket = new AWS.S3({
65
+ params: { Bucket: S3_BUCKET },
66
+ region: REGION,
67
+ });
68
+
69
+ export const ProviderProductEdition = ({
70
+ tabsSections,
71
+ productSelected = {},
72
+ productToEdit,
73
+ user = {},
74
+ location = {},
75
+ token,
76
+ revision = false,
77
+ setShowContentohRequestModal,
78
+ showSurvey,
79
+ }) => {
80
+ const [activeTab, setActiveTab] = useState("Descripción");
81
+ const [activeImage, setActiveImage] = useState();
82
+ const [imageLayout, setImageLayout] = useState(false);
83
+ const [headerTop, setHeaderTop] = useState(0);
84
+ const [descriptions, setDescriptions] = useState([]);
85
+ const [datasheets, setDatasheets] = useState([]);
86
+ const [images, setImages] = useReducer(reducerImages, {});
87
+ const [showModal, setShowModal] = useState(false);
88
+ const { getRootProps, getInputProps } = useDropzone({
89
+ accept: "image/*",
90
+ noKeyboard: true,
91
+ multiple: true,
92
+ noClick: true,
93
+ onDrop: (acceptedFiles) => {
94
+ const newImages = [];
95
+ acceptedFiles.map((file) => {
96
+ const reader = new FileReader();
97
+ reader.fileName = file.name;
98
+ reader.onload = async function (e) {
99
+ const ext = e.srcElement.fileName.split(".");
100
+ const img = new Image();
101
+ img.src = e.target.result;
102
+ const width = img.width;
103
+ const height = img.height;
104
+ const newImg = {
105
+ action: "addImg",
106
+ img: {
107
+ src: e.target.result,
108
+ name: e.target.fileName,
109
+ ext: ext[ext.length - 1],
110
+ width: width,
111
+ height: width,
112
+ },
113
+ };
114
+ setImages(newImg);
115
+ };
116
+ reader.onerror = function (error) {
117
+ console.log("dropzoneError: ", error);
118
+ };
119
+ reader.readAsDataURL(file);
120
+ return file;
121
+ });
122
+ },
123
+ });
124
+ const [updatedDatasheets, setUpdatedDatasheets] = useState([]);
125
+ const [updatedDescriptions, setUpdatedDescriptions] = useState([]);
126
+ const [imagesUploaded, setImagesUploaded] = useState(false);
127
+ const [dataImages, setDataImages] = useState();
128
+ const [percentages, setPercentages] = useState(
129
+ product?.retailers
130
+ ? new Array(product?.retailers?.length).fill({ percentage: 0 })
131
+ : new Array(product?.retailersAvailable?.length).fill({ percentage: 0 })
132
+ );
133
+ const [activePercentage, setActivePercentage] = useState(0);
134
+ const [activeRetailer, setActiveRetailer] = useState({});
135
+ const [services, setServices] = useState([]);
136
+ const [servicesData, setServicesData] = useState([]);
137
+ const [message, setMessage] = useState("");
138
+ const [product, setProduct] = useState(
139
+ JSON.parse(sessionStorage.getItem("productSelected"))
140
+ ? JSON.parse(sessionStorage.getItem("productSelected"))
141
+ : productSelected
142
+ );
143
+ const [productEdit, setProductEdit] = useState(
144
+ JSON.parse(sessionStorage.getItem("productEdit"))
145
+ ? JSON.parse(sessionStorage.getItem("productEdit"))
146
+ : productToEdit
147
+ );
148
+ const [icon, setIcon] = useState(null);
149
+ const [version, setVersion] = useState(product?.version);
150
+ const [comments, setComments] = useState({});
151
+ const [comment, setComment] = useState("");
152
+ const [requiredNull, setRequiredNull] = useState({
153
+ "Ficha técnica": 0,
154
+ Descripción: 0,
155
+ Imágenes: 0,
156
+ });
157
+ const [crossComment, setCrossComment] = useState(false);
158
+ const [userGroups, setUserGroups] = useState([]);
159
+ const [assig, setAssig] = useState({});
160
+ const [selectedImages, setSelectedImages] = useState([]);
161
+ const [componentsArray, setComponentsArray] = useState([]);
162
+ const [checkAll, setCheckAll] = useState(false);
163
+ const isRetailer = user?.is_retailer;
164
+ const [loading, setLoading] = useState(true);
165
+ const [statusArray, setStatusArray] = useState([]);
166
+
167
+ const originProp = location?.state?.origin;
168
+ const [origin, setOrigin] = useState({
169
+ "Ficha técnica": originProp,
170
+ Descripción: originProp,
171
+ Imágenes: originProp,
172
+ });
173
+ const [inCart, setInCart] = useState(false);
174
+ const [modalSent, setModalSent] = useState(false);
175
+ const [modalViewError, setModalViewError] = useState(false);
176
+ const [showGenericModal, setShowGenericModal] = useState(false);
177
+ const [dataGenericModal, setDataGenericModal] = useState({
178
+ message: "¿Estás seguro de continuar?",
179
+ detail: ` ${
180
+ user.is_retailer
181
+ ? "Asegurate de haber revisado las tres secciones"
182
+ : "Envíar el producto a la cadena"
183
+ }`,
184
+ button1: {
185
+ name: "Cerrar",
186
+ action: () => setModalViewTextArea(false),
187
+ },
188
+ button2: {
189
+ name: "Continuar",
190
+ action: () => evaluationToRetailer(false),
191
+ },
192
+ img: face,
193
+ });
194
+ const [modalViewTextArea, setModalViewTextArea] = useState(false);
195
+
196
+ useEffect(() => {
197
+ checkAll && setSelectedImages(images.values);
198
+ }, [checkAll]);
199
+
200
+ const loadData = async () => {
201
+ const services = await getRetailerServices(
202
+ product?.id_article || product?.article?.id_article,
203
+ parseInt(product?.article?.id_category || product?.id_category),
204
+ product?.version
205
+ );
206
+
207
+ //Converts the data inside the datasheets object to array
208
+ setServices(services);
209
+
210
+ //setActiveRetailer(product?.retailers[0]);
211
+ setImages({
212
+ action: "init",
213
+ init: services[2],
214
+ });
215
+ if (services[2]?.values?.length > 0) setActiveImage(0);
216
+
217
+ setActiveRetailer(
218
+ product.retailers ? product.retailers[0] : product.retailersAvailable[0]
219
+ );
220
+
221
+ getPercentage({ data: [product] }).then((res) => setPercentages(res));
222
+ setLoading(false);
223
+ };
224
+
225
+ const getServices = async () => {
226
+ const productInOrder = product.id_order || product.orderId;
227
+ if (isRevision() || productInOrder) {
228
+ const servicesResponse = await axios.get(
229
+ `${process.env.REACT_APP_SERVICES_ENDPOINT}?articleId=${
230
+ product?.id_article
231
+ }&orderId=${product?.id_order ?? product.orderId}&end=true`
232
+ );
233
+ const parsedResponse = JSON.parse(servicesResponse?.data?.body).data;
234
+ setServicesData(parsedResponse);
235
+ }
236
+ };
237
+
238
+ const translateConcept = (concept) => {
239
+ let translation = "";
240
+ if (concept === "datasheet") {
241
+ translation = "Ficha técnica";
242
+ } else if (concept === "description") {
243
+ translation = "Descripción";
244
+ } else if (concept === "images") {
245
+ translation = "Imágenes";
246
+ }
247
+ return translation;
248
+ };
249
+
250
+ const isRevision = () => {
251
+ if (productEdit) {
252
+ const concept = getConcept(activeTab);
253
+ const isRetailer = user.is_retailer;
254
+ const currentService = productEdit?.product[`${concept}_status`];
255
+ const orgn = origin[activeTab];
256
+ const revision = [
257
+ "RequestWithContentoh",
258
+ "RequestWithoutContentoh",
259
+ "Contentoh",
260
+ ].includes(orgn);
261
+ if (isRetailer) {
262
+ if (revision && currentService === "AP") return true;
263
+ } else {
264
+ const { product } = productEdit;
265
+ if (
266
+ orgn === "Contentoh" ||
267
+ (["RECEIVED", "IN_PROGRESS"].includes(currentService) &&
268
+ orgn === "RequestWithoutContentoh") ||
269
+ (currentService === "AA" && orgn === "RequestWithContentoh") ||
270
+ (currentService === "RC" &&
271
+ orgn === "RequestWithoutContentoh" &&
272
+ (!product.id_order || !product.orderId))
273
+ )
274
+ return true;
275
+ }
276
+ }
277
+ return false;
278
+ };
279
+
280
+ const getCart = async () => {
281
+ const res = await axios.get(process.env.REACT_APP_CART, {
282
+ headers: {
283
+ Authorization: token,
284
+ },
285
+ });
286
+ const arr = JSON.parse(res.data.body).data.map((e) => e.article_id);
287
+ setInCart(arr.some((e) => e.articleId === product.id_article));
288
+ };
289
+
290
+ useEffect(async () => {
291
+ loadData();
292
+ // getPercentage({ data: [product] }).then((res) =>
293
+ // setPercentages(res)
294
+ // );
295
+ getCart();
296
+ getServices();
297
+ setUserGroups(await fetchUsers(token));
298
+ let arr = [];
299
+ switch (user.id_role) {
300
+ case 7:
301
+ case 8:
302
+ arr = ["IN_PROGRESS", "RF", "RA"];
303
+ break;
304
+ case 4:
305
+ case 5:
306
+ arr = ["RF", "AF", "AA", "AP", "AC"];
307
+ break;
308
+ case 6:
309
+ arr = ["RP", "RC", "AF"];
310
+ break;
311
+ default:
312
+ arr = [];
313
+ break;
314
+ }
315
+ setStatusArray(arr);
316
+ }, [product]);
317
+
318
+ const loadAssignations = (currentProduct) => {
319
+ setAssig(product?.asignations);
320
+ };
321
+
322
+ useEffect(() => {
323
+ loadAssignations(product);
324
+ }, [userGroups]);
325
+
326
+ useEffect(() => {
327
+ const productTemp = product;
328
+ const retailers = productTemp?.retailersAvailable || productTemp?.retailers;
329
+ retailers?.forEach((retailer) => {
330
+ retailer["percentage"] = percentages?.filter(
331
+ (percent) => retailer?.id === percent?.id_retailer
332
+ )[0]?.percentage;
333
+ });
334
+
335
+ setProduct(productTemp);
336
+ setActivePercentage(retailers[0]?.percentage);
337
+ }, [percentages]);
338
+
339
+ useEffect(() => {
340
+ if (services.length > 0) {
341
+ if (services[0][activeRetailer?.id]?.data)
342
+ services[0][activeRetailer.id].data = Object.values(
343
+ services[0][activeRetailer.id].data
344
+ );
345
+ setActivePercentage(Math.round(activeRetailer?.percentage, 0));
346
+
347
+ const datagroups = services[0][activeRetailer?.id];
348
+ const inputs = services[0]?.inputs;
349
+ const descriptions = services[1]?.filter(
350
+ (service) => service?.id === activeRetailer?.id
351
+ );
352
+ setDatasheets([datagroups, inputs]);
353
+ setDescriptions(descriptions);
354
+ }
355
+ }, [activeRetailer, services]);
356
+
357
+ const thumbs = () => {
358
+ const imageInputs = images?.inputs?.map((e) => ({
359
+ value: e?.id,
360
+ name: e?.name,
361
+ required: e?.required,
362
+ }));
363
+ const imageType = images?.imageType?.map((e) => ({
364
+ value: e?.id,
365
+ name: e?.name,
366
+ }));
367
+ const imagePackagingType = images?.imagePackagingType?.map((e) => ({
368
+ value: e?.id,
369
+ name: e?.name,
370
+ }));
371
+ return images?.values?.map((image, index) => (
372
+ <GalleryElement
373
+ setCheckAll={setCheckAll}
374
+ key={index}
375
+ image={image}
376
+ gridLayout={imageLayout}
377
+ id={"gallery-element-" + index}
378
+ index={index}
379
+ imageType={imageType}
380
+ imagePackagingType={imagePackagingType}
381
+ imageInputs={imageInputs}
382
+ changeImage={setImages}
383
+ selectedImages={selectedImages}
384
+ setSelectedImages={setSelectedImages}
385
+ />
386
+ ));
387
+ };
388
+
389
+ const saveDescriptions = async () => {
390
+ setLoading(true);
391
+ const productTemp = product;
392
+ const dataObject = {
393
+ articleId: product?.id_article,
394
+ articleData: updatedDescriptions,
395
+ };
396
+ if (product?.orderId) dataObject["orderId"] = product?.orderId;
397
+ try {
398
+ await axios.put(
399
+ `${process.env.REACT_APP_ARTICLE_DATA_ENDPOINT}?description=true&version=${version}`,
400
+ dataObject,
401
+ {
402
+ headers: {
403
+ Authorization: token,
404
+ },
405
+ }
406
+ );
407
+ if (productTemp.status === "ASSIGNED") {
408
+ productTemp.status = "IN_PROGRESS";
409
+ setProduct(productTemp);
410
+ sessionStorage.setItem("productSelected", JSON.stringify(productTemp));
411
+ }
412
+
413
+ setMessage("Descripciones guardadas con éxito");
414
+ loadData();
415
+ } catch (error) {
416
+ console.log(error);
417
+ }
418
+ };
419
+
420
+ const saveDatasheets = async () => {
421
+ setLoading(true);
422
+ const dataObject = {
423
+ articleId: product?.id_article,
424
+ articleData: updatedDatasheets,
425
+ };
426
+ if (product?.orderId) dataObject["orderId"] = product?.orderId;
427
+ try {
428
+ await axios.put(
429
+ `${process.env.REACT_APP_ARTICLE_DATA_ENDPOINT}?datasheet=true&version=${version}`,
430
+ dataObject,
431
+ {
432
+ headers: {
433
+ Authorization: token,
434
+ },
435
+ }
436
+ );
437
+ setMessage("Fichas técnicas guardadas");
438
+ if (productTemp.status === "ASSIGNED") {
439
+ productTemp.status = "IN_PROGRESS";
440
+ setProduct(productTemp);
441
+ sessionStorage.setItem("productSelected", JSON.stringify(productTemp));
442
+ }
443
+ loadData();
444
+ } catch (error) {
445
+ console.log(error);
446
+ }
447
+ };
448
+
449
+ const updateImages = useCallback(async () => {
450
+ const imagesList = images?.values?.slice();
451
+ const imagesListTemp = imagesList?.reduce((acc, image) => {
452
+ acc[image?.image_id] = ++acc[image?.image_id] || 0;
453
+ return acc;
454
+ }, {});
455
+
456
+ const duplicated = imagesList?.filter((image) => {
457
+ return imagesListTemp[image?.image_id];
458
+ });
459
+
460
+ const attrForImgs = Object.values(images?.attrForImgs);
461
+ attrForImgs.pop();
462
+ const data = {
463
+ articleId: product?.id_article,
464
+ attrReqImgs: attrForImgs?.map((e) => ({
465
+ attrId: e[0]?.id,
466
+ value: e[0]?.value,
467
+ })),
468
+ articleData: imagesList?.filter((e) => !e.id),
469
+ updateImages: imagesList?.filter((e) => e.id),
470
+ };
471
+ if (product?.orderId) data["orderId"] = product?.orderId;
472
+ let valid =
473
+ data?.articleData?.length === 0
474
+ ? true
475
+ : data?.articleData?.every((e, i) => {
476
+ if (e?.image_id && e?.packing_type && e?.image_type) {
477
+ return true;
478
+ }
479
+ return false;
480
+ });
481
+ if (valid && data?.updateImages?.length > 0 && duplicated?.length === 0) {
482
+ valid = data?.updateImages?.every((e, i) => {
483
+ if (e?.image_id && e?.packing_type && e?.image_type) {
484
+ return true;
485
+ }
486
+ return false;
487
+ });
488
+ }
489
+ if (valid && duplicated?.length === 0) {
490
+ try {
491
+ data?.articleData?.forEach((e) => {
492
+ e.uuid = uuidv4();
493
+ });
494
+ setDataImages(data);
495
+ if (data?.articleData?.length > 0) {
496
+ setImagesUploaded(false);
497
+ const promiseArray = [];
498
+ data?.articleData?.forEach((e) => {
499
+ const file = Buffer.from(
500
+ e.src.replace(/^data:image\/\w+;base64,/, ""),
501
+ "base64"
502
+ );
503
+ const params = {
504
+ ACL: "public-read",
505
+ Body: file,
506
+ Bucket: S3_BUCKET,
507
+ Key: `id-${data.articleId}/${version}/${e?.image_id}-${e?.uuid}.${e?.ext}`,
508
+ };
509
+ promiseArray.push(myBucket.putObject(params).promise());
510
+ });
511
+ await Promise.all(promiseArray);
512
+ setImagesUploaded(true);
513
+ } else {
514
+ setImagesUploaded(true);
515
+ }
516
+ } catch (err) {
517
+ console.log(err);
518
+ // setMainLoading(false);
519
+ }
520
+ } else {
521
+ // setMainLoading(false);
522
+ setMessage(
523
+ "Completa los campos que solicita cada una de la imágenes o hay imágenes con el mismo tipo de toma.\nRecuerda hay campos obligatorios y no podras avanzar si no estan completos."
524
+ );
525
+ }
526
+ // eslint-disable-next-line react-hooks/exhaustive-deps
527
+ }, [images, imagesUploaded]);
528
+
529
+ useEffect(async () => {
530
+ if (imagesUploaded) {
531
+ setLoading(true);
532
+ dataImages.articleData = dataImages?.articleData.map((e) => {
533
+ delete e.src;
534
+ e.imageID = e.image_id;
535
+ e.packingType = e.packing_type;
536
+ e.imageType = e.image_type;
537
+ if (product?.orderId) e["orderId"] = product?.orderId;
538
+ return e;
539
+ });
540
+ try {
541
+ await axios.put(
542
+ `${process.env.REACT_APP_ARTICLE_DATA_ENDPOINT}?image=true&version=${version}`,
543
+ dataImages,
544
+ {
545
+ headers: {
546
+ Authorization: token,
547
+ },
548
+ }
549
+ );
550
+ setMessage("Imágenes guardadas con éxito");
551
+ loadData();
552
+ } catch (error) {
553
+ console.log(error);
554
+ }
555
+ }
556
+ }, [dataImages, imagesUploaded]);
557
+
558
+ const evaluationFinished = (userId, tab, statusArray) => {
559
+ // const srv = servicesData.filter((serv) => serv.service === getConcept(tab));
560
+ // const [srvActive] = srv.filter(
561
+ // (serv) => serv.id_retailer === activeRetailer?.id
562
+ // );
563
+ // const unvalidated =
564
+ // product[`${getConcept(tab)}_status`] === "QF" ||
565
+ // product[`${getConcept(tab)}_status`] === "IN_PROGRESS";
566
+ // switch (userId) {
567
+ // case 7:
568
+ // case 8:
569
+ // return (
570
+ // (["RA", "RF"].includes(product?.status) &&
571
+ // statusArray.includes(srvActive?.status)) ||
572
+ // (statusArray.includes(product.status) &&
573
+ // srv.filter((serv) => statusArray.includes(serv.status)).length ===
574
+ // srv.length)
575
+ // );
576
+ // case 4:
577
+ // case 5:
578
+ // return (
579
+ // unvalidated &&
580
+ // ["IN_PROGRESS", "QF"].includes(product.status) &&
581
+ // srv.filter((serv) => statusArray.includes(serv.status)).length ===
582
+ // srv.length
583
+ // );
584
+ // case 6:
585
+ // return (
586
+ // statusArray.includes(product.status) &&
587
+ // servicesData.every((serv) => ["RA", "AA"].includes(serv.status))
588
+ // );
589
+ // default:
590
+ // break;
591
+ // }
592
+ };
593
+
594
+ const getConcept = (tab) => {
595
+ switch (tab) {
596
+ case "Descripción":
597
+ return "description";
598
+ case "Ficha técnica":
599
+ return "datasheet";
600
+ case "Imágenes":
601
+ return "images";
602
+ }
603
+ };
604
+
605
+ // const approveRejectButtons = (action) => {
606
+ // let concept = getConcept(activeTab);
607
+ // concept = action ? action : concept;
608
+
609
+ // const [retailerStatus] = servicesData.filter(
610
+ // (srv) => srv.id_retailer === activeRetailer?.id && srv.service === concept
611
+ // );
612
+
613
+ // return (
614
+ // (retailerStatus?.status === "QF" &&
615
+ // (user.id_role === 1 || user.id_role === 4 || user.id_role === 5)) ||
616
+ // (retailerStatus?.status === "AF" && //sessionStorage product
617
+ // (user.id_role === 1 || user.id_role === 6)) ||
618
+ // (retailerStatus?.status === "RP" &&
619
+ // (user.id_role === 1 || user.id_role === 6)) ||
620
+ // (retailerStatus?.status === "RC" &&
621
+ // (user.id_role === 1 || user.id_role === 6))
622
+ // );
623
+ // };
624
+
625
+ const getSectionIcon = () => {
626
+ switch (activeTab) {
627
+ case "Ficha técnica":
628
+ setIcon(attributesSent);
629
+ break;
630
+ case "Descripción":
631
+ setIcon(descriptionSent);
632
+ break;
633
+ case "Imágenes0,,":
634
+ setIcon(imagesSent);
635
+ break;
636
+ default:
637
+ break;
638
+ }
639
+ };
640
+
641
+ // const sendToFacilitator = async (result) => {
642
+ // setLoading(true);
643
+ // try {
644
+ // let concept = getConcept(activeTab);
645
+
646
+ // let productTemp = { ...product };
647
+ // let evalStatus = product[`${concept}_status`];
648
+
649
+ // let data = {};
650
+ // if (result) {
651
+ // //updateCompaniesList(evalStatus, result, activeRetailer.id, concept);
652
+ // data = {
653
+ // articleId: product.id_article,
654
+ // orderId: product.orderId,
655
+ // concept: concept,
656
+ // result: result,
657
+ // evalStatus: evalStatus,
658
+ // retailerId: activeRetailer.id,
659
+ // };
660
+
661
+ // await axios.put(`${process.env.REACT_APP_EVALUATION_ENDPOINT}`, data, {
662
+ // headers: {
663
+ // Authorization: token,
664
+ // },
665
+ // });
666
+ // getServices();
667
+ // } else {
668
+ // const specialistDone =
669
+ // evalStatus === "RF" ||
670
+ // evalStatus === "RA" ||
671
+ // evalStatus === "IN_PROGRESS";
672
+
673
+ // if (specialistDone) {
674
+ // setMessage(`${activeTab} enviada a facilitador`);
675
+ // getSectionIcon();
676
+ // } else if (evalStatus === "QF") {
677
+ // setMessage("Evaluación enviada");
678
+ // getSectionIcon();
679
+ // } else if (evalStatus === "AF") {
680
+ // setMessage("Evaluación enviada");
681
+ // getSectionIcon();
682
+ // } else if (evalStatus === "RP") {
683
+ // setMessage("Evaluación enviada");
684
+ // getSectionIcon();
685
+ // } else if (evalStatus === "RC") {
686
+ // setMessage("Evaluación enviada");
687
+ // getSectionIcon();
688
+ // }
689
+ // let statusArr = [];
690
+ // servicesData.forEach((srv) => {
691
+ // srv.service === concept && statusArr.push(srv.status);
692
+ // });
693
+
694
+ // productTemp[`${concept}_status`] = getNewStatus(statusArr);
695
+
696
+ // let newStatus = getNewStatus([
697
+ // productTemp.datasheet_status,
698
+ // productTemp.description_status,
699
+ // productTemp.images_status,
700
+ // ]);
701
+
702
+ // productTemp.status = newStatus;
703
+
704
+ // data = {
705
+ // articleId: product.id_article,
706
+ // orderId: product.orderId,
707
+ // concept: concept,
708
+ // evalStatus: evalStatus,
709
+ // retailerId: activeRetailer.id,
710
+ // };
711
+
712
+ // switch (user.id_role) {
713
+ // case 7:
714
+ // case 8:
715
+ // data.especialist = true;
716
+ // break;
717
+ // case 4:
718
+ // case 5:
719
+ // data.facilitator = true;
720
+ // break;
721
+ // default:
722
+ // break;
723
+ // }
724
+ // await axios.put(`${process.env.REACT_APP_SEND_EVAL}`, data, {
725
+ // headers: {
726
+ // Authorization: token,
727
+ // },
728
+ // });
729
+ // getServices();
730
+ // }
731
+ // sessionStorage.setItem("productSelected", JSON.stringify(productTemp));
732
+ // setProduct(productTemp);
733
+ // } catch (error) {
734
+ // console.log(error);
735
+ // }
736
+ // setLoading(false);
737
+ // };
738
+
739
+ const userAssigned = (tab, rol) => {
740
+ let concept = "";
741
+ switch (tab) {
742
+ case "Ficha técnica":
743
+ concept = "datasheet";
744
+ break;
745
+ case "Imágenes":
746
+ concept = "images";
747
+ break;
748
+
749
+ default:
750
+ concept = "description";
751
+ break;
752
+ }
753
+
754
+ const allowedRoles = [1, 4, 5, 6, 7, 8];
755
+ const validUser = allowedRoles.indexOf(user?.id_role) !== -1;
756
+
757
+ if (!rol) {
758
+ switch (user.id_role) {
759
+ case 4:
760
+ case 5:
761
+ rol = "facilitator";
762
+ break;
763
+ case 7:
764
+ case 8:
765
+ rol = "especialist";
766
+ break;
767
+ }
768
+ }
769
+
770
+ return true;
771
+ };
772
+
773
+ const createComment = async (e, body, tab) => {
774
+ let concept = "";
775
+ switch (activeTab) {
776
+ case "Ficha técnica":
777
+ concept = "datasheet";
778
+ break;
779
+ case "Imágenes":
780
+ concept = "images";
781
+ break;
782
+
783
+ default:
784
+ concept = "description";
785
+ break;
786
+ }
787
+ const data = {
788
+ articleId: product?.id_article,
789
+ orderId: product?.orderId,
790
+ message: body,
791
+ concept: concept,
792
+ version: version,
793
+ };
794
+ await axios.post(`${process.env.REACT_APP_COMMENTS_ENDPOINT}`, data, {
795
+ headers: {
796
+ Authorization: token,
797
+ },
798
+ });
799
+ };
800
+
801
+ const getRequired = (services) => {
802
+ const objetcTemp = {};
803
+ const datasheetServicesArray = Object.values(services[0]);
804
+ const dsInputs = datasheetServicesArray.pop();
805
+ const descriptionsServicesArray = services[1];
806
+
807
+ let dsInputsRequired = [];
808
+ let desInputsRequired = 0;
809
+ datasheetServicesArray.forEach((datasheet) => {
810
+ const [requested] = servicesData.filter(
811
+ (srv) =>
812
+ srv.id_retailer === datasheet.retailer.id &&
813
+ srv.service === getConcept(activeTab)
814
+ );
815
+ requested &&
816
+ Object.values(datasheet?.data).forEach((dataGroup) =>
817
+ dsInputsRequired.push(
818
+ ...dataGroup.inputs.filter(
819
+ (input) =>
820
+ dsInputs[input].required &&
821
+ (dsInputs[input].value === undefined || !dsInputs[input].value)
822
+ )
823
+ )
824
+ );
825
+ });
826
+
827
+ objetcTemp["Ficha técnica"] = dsInputsRequired.length;
828
+
829
+ descriptionsServicesArray.forEach((description) => {
830
+ const [requested] = servicesData.filter(
831
+ (srv) =>
832
+ srv.id_retailer === description.id &&
833
+ srv.service === getConcept(activeTab)
834
+ );
835
+ requested &&
836
+ description.inputs.forEach(
837
+ (input) =>
838
+ input.required &&
839
+ (!input.value ||
840
+ input.value.replace(/(<\/?p>)|(<\/?strong>)|(<br>)/gm, "") ===
841
+ "") &&
842
+ desInputsRequired++
843
+ );
844
+ });
845
+
846
+ objetcTemp["Descripción"] = desInputsRequired;
847
+ const requiredImages = services[2]?.inputs?.filter((e) => e.required);
848
+ let requiredCounter = 0;
849
+ requiredImages?.forEach(
850
+ (req) =>
851
+ services[2].values.filter((img) => img.image_id === req.id).length ===
852
+ 0 && requiredCounter++
853
+ );
854
+ objetcTemp["Imágenes"] = requiredCounter;
855
+ setRequiredNull(objetcTemp);
856
+ };
857
+
858
+ useEffect(() => {
859
+ setComment(comments[activeTab]);
860
+ }, [activeTab]);
861
+
862
+ const commentRevised = async () => {
863
+ const data = {
864
+ commentId: comment.id,
865
+ };
866
+ await axios.put(`${process.env.REACT_APP_COMMENTS_ENDPOINT}`, data, {
867
+ headers: {
868
+ Authorization: token,
869
+ },
870
+ });
871
+ setCrossComment(false);
872
+ };
873
+
874
+ const setAssignation = async (assignationType, assignationId) => {
875
+ let concept = "";
876
+ switch (activeTab) {
877
+ case "Ficha técnica":
878
+ concept = "datasheet";
879
+ break;
880
+ case "Imágenes":
881
+ concept = "images";
882
+ break;
883
+
884
+ default:
885
+ concept = "description";
886
+ break;
887
+ }
888
+ const productTemp = product;
889
+ productTemp.article[`id_${concept}_${assignationType}`] = assignationId;
890
+ const data = {
891
+ articleList: [
892
+ {
893
+ orderId: product.orderId,
894
+ articleId: product?.id_article,
895
+ },
896
+ ],
897
+ concept: concept,
898
+ [`${assignationType}Id`]: assignationId,
899
+ };
900
+ axios({
901
+ method: "post",
902
+ url: process.env.REACT_APP_ASSIGNATIONS_ENDPOINT,
903
+ data: data,
904
+ headers: {
905
+ Authorization: token,
906
+ },
907
+ });
908
+ loadAssignations(productTemp);
909
+ sessionStorage.setItem("productSelected", JSON.stringify(productTemp));
910
+ };
911
+
912
+ const evaluationComplete = () => {
913
+ const concept = getConcept(activeTab);
914
+ let serv = servicesData.filter((item) => item.service === concept);
915
+ if (
916
+ ["RequestWithContentoh", "RequestWithoutContentoh"].includes(
917
+ origin[concept]
918
+ )
919
+ ) {
920
+ serv = serv.filter((f) => f.id_retailer === product.retailer_id);
921
+ }
922
+ const approved = user.is_retailer ? "AC" : "AP";
923
+ const rejected = user.is_retailer ? "RC" : "RP";
924
+ return (
925
+ serv.filter(
926
+ (item) => item.status === approved || item.status === rejected
927
+ ).length === serv.length
928
+ );
929
+ };
930
+
931
+ const downloadImages = () => {
932
+ selectedImages.forEach((e) => {
933
+ if (e.id) {
934
+ saveAs(
935
+ `https://${process.env.REACT_APP_IMAGES_BUCKET}.s3.amazonaws.com/${e.srcDB}`,
936
+ `${product.article.upc}_${e.name}.${e.ext}`
937
+ );
938
+ }
939
+ });
940
+ };
941
+
942
+ const deleteImages = () => {
943
+ const data = {
944
+ articleId: product.id_article,
945
+ deleteImages: selectedImages,
946
+ };
947
+ try {
948
+ axios.put(
949
+ `${process.env.REACT_APP_ARTICLE_DATA_ENDPOINT}?image=true&version=${version}`,
950
+ data,
951
+ {
952
+ headers: { Authorization: token },
953
+ }
954
+ );
955
+ loadData();
956
+ } catch (err) {
957
+ console.log(err);
958
+ }
959
+ setMessage("");
960
+ };
961
+
962
+ const askToDeleteImages = () => {
963
+ if (selectedImages.length > 0) {
964
+ setMessage("¿Está seguro de eliminar las imágenes seleccionadas?");
965
+ setComponentsArray([
966
+ <ScreenHeader
967
+ key={"1"}
968
+ text={"¿Está seguro de eliminar las imágenes seleccionadas?"}
969
+ headerType="retailer-name-header"
970
+ color={"white"}
971
+ />,
972
+ <Button
973
+ key={"2"}
974
+ buttonType="general-white-button"
975
+ label={"Cancelar"}
976
+ onClick={() => setMessage("")}
977
+ />,
978
+ <Button
979
+ key={"3"}
980
+ buttonType="general-button-default"
981
+ label={"Aceptar"}
982
+ onClick={() => deleteImages()}
983
+ />,
984
+ ]);
985
+ }
986
+ };
987
+
988
+ const specialistValid = (tab) => {
989
+ let concept = "";
990
+ switch (tab) {
991
+ case "Ficha técnica":
992
+ concept = "datasheet";
993
+ break;
994
+ case "Imágenes":
995
+ concept = "images";
996
+ break;
997
+ case "Descripción":
998
+ concept = "description";
999
+ break;
1000
+ }
1001
+ return (
1002
+ product[`${concept}_status`] === "IN_PROGRESS" ||
1003
+ product[`${concept}_status`] === "RF" ||
1004
+ product[`${concept}_status`] === "RA"
1005
+ );
1006
+ };
1007
+
1008
+ // const getRetailerStatus = (servicesData, tab) => {
1009
+ // const arr = servicesData?.slice();
1010
+ // let concept = getConcept(tab);
1011
+
1012
+ // let retailerService = {};
1013
+ // [retailerService] = arr?.filter(
1014
+ // (service) =>
1015
+ // service.id_retailer === activeRetailer?.id &&
1016
+ // service.service === concept
1017
+ // );
1018
+ // return retailerService ? retailerService.status : "NA";
1019
+ // };
1020
+
1021
+ // useEffect(() => {
1022
+ // let status = getRetailerStatus(servicesData, activeTab);
1023
+ // setRetailerStatus(status);
1024
+ // }, [activeTab, servicesData, activeRetailer]);
1025
+
1026
+ // useEffect(() => {
1027
+ // services.length > 0 && getRequired(services);
1028
+ // }, [services, servicesData, activeTab]);
1029
+ const confirmStatusComplete = () => {
1030
+ const { datasheet_status, description_status, images_status } = product;
1031
+ const completionStates = ["AP", "Evaluated", "NS"];
1032
+ const dsEvaluated = completionStates.includes(datasheet_status);
1033
+ const descsEvaluated = completionStates.includes(description_status);
1034
+ const imgsEvaluated = completionStates.includes(images_status);
1035
+
1036
+ const AllEvaluated = dsEvaluated && descsEvaluated && imgsEvaluated;
1037
+
1038
+ return AllEvaluated;
1039
+ };
1040
+
1041
+ const sendEvaluation = async (result) => {
1042
+ let data = {};
1043
+ const retailerId = activeRetailer?.id;
1044
+ if (result) {
1045
+ data = {
1046
+ articleId: product.id_article,
1047
+ orderId: product.id_order ?? product.orderId,
1048
+ concept: getConcept(activeTab),
1049
+ result: result,
1050
+ retailerId,
1051
+ };
1052
+ await axios.put(`${process.env.REACT_APP_EVALUATION_ENDPOINT}`, data, {
1053
+ headers: {
1054
+ Authorization: token,
1055
+ },
1056
+ });
1057
+ } else {
1058
+ const concept = getConcept(activeTab);
1059
+ const productTemp = product;
1060
+ productTemp[`${concept}_status`] = "Evaluated";
1061
+ data = {
1062
+ articleId: product.id_article,
1063
+ orderId: product.id_order ?? product.orderId,
1064
+ concept,
1065
+ retailerId,
1066
+ };
1067
+ axios.put(`${process.env.REACT_APP_SEND_EVAL}`, data, {
1068
+ headers: {
1069
+ Authorization: token,
1070
+ },
1071
+ });
1072
+ setProduct(productTemp);
1073
+ setProductEdit({
1074
+ ArticleId: productTemp.id_article,
1075
+ idCategory: productTemp.article.id_category,
1076
+ product: productTemp,
1077
+ });
1078
+ sessionStorage.setItem(
1079
+ "productEdit",
1080
+ JSON.stringify({
1081
+ ArticleId: productTemp.id_article,
1082
+ idCategory: productTemp.article.id_category,
1083
+ product: productTemp,
1084
+ })
1085
+ );
1086
+ setOrigin((prev) => ({ ...prev, [concept]: "Evaluated" }));
1087
+ }
1088
+ loadData();
1089
+ showSurvey && showSurvey(confirmStatusComplete());
1090
+ };
1091
+
1092
+ const evaluationToRetailer = async (result) => {
1093
+ const data = {
1094
+ articleId: product.id_article,
1095
+ companyId: user.is_retailer
1096
+ ? product.provider_company_id
1097
+ : product.retailer_company_id,
1098
+ versionId: product.version,
1099
+ status: result,
1100
+ };
1101
+ await axios.put(`${process.env.REACT_APP_RETAILER_REQUEST}`, data, {
1102
+ headers: {
1103
+ Authorization: token,
1104
+ },
1105
+ });
1106
+ const prod = productEdit;
1107
+ const statusComplete = user.is_retailer ? `${result}C` : `${result}P`;
1108
+ prod.product.datasheet_status = statusComplete;
1109
+ prod.product.description_status = statusComplete;
1110
+ prod.product.images_status = statusComplete;
1111
+ prod.product.article_status = statusComplete;
1112
+ prod.product.services_status = `["${statusComplete}","${statusComplete}","${statusComplete}"]`;
1113
+ sessionStorage.setItem("productEdit", JSON.stringify(prod));
1114
+ setProduct(prod);
1115
+ setShowGenericModal && setShowGenericModal(false);
1116
+ };
1117
+
1118
+ const getSectionStatus = () => {
1119
+ const concept = getConcept(activeTab);
1120
+ return ["AA", "AP", "RECEIVED", "IN_PROGRESS", "RC"].includes(
1121
+ productEdit.product[`${concept}_status`]
1122
+ );
1123
+ };
1124
+
1125
+ const enableActions = (versionStatus) => {
1126
+ if (versionStatus) {
1127
+ return ["AP", "AC", "RC"].includes(versionStatus);
1128
+ }
1129
+ return true;
1130
+ };
1131
+
1132
+ return (
1133
+ <Container headerTop={headerTop}>
1134
+ <HeaderTop setHeaderTop={setHeaderTop} />
1135
+ <div className="data-container">
1136
+ <div className="image-data-panel">
1137
+ <ImagePreviewer
1138
+ activeImage={images?.values ? images?.values[activeImage] : {}}
1139
+ imagesArray={images}
1140
+ setActiveImage={setActiveImage}
1141
+ setShowModal={setShowModal}
1142
+ />
1143
+ <ImageDataTable
1144
+ lists={images}
1145
+ activeImage={images?.values ? images?.values[activeImage] : {}}
1146
+ retailerSelected={activeRetailer?.id}
1147
+ setImages={setImages}
1148
+ assignationsImages={assig}
1149
+ imagesStatus={product?.images_status}
1150
+ setAssignation={setAssignation}
1151
+ isRetailer={isRetailer}
1152
+ onClickSave={() =>
1153
+ product?.services?.images === 1 && updateImages()
1154
+ }
1155
+ />
1156
+ </div>
1157
+ <div className="product-information">
1158
+ <FullProductNameHeader
1159
+ headerData={product}
1160
+ percent={activePercentage}
1161
+ activeRetailer={activeRetailer}
1162
+ setActiveRetailer={setActiveRetailer}
1163
+ showValidationButtons={isRevision() && getSectionStatus()}
1164
+ approve={() => {
1165
+ if (
1166
+ origin[getConcept(activeTab)] === "RequestWithoutContentoh" &&
1167
+ !user.is_retailer &&
1168
+ (!product.id_order || !product.orderId)
1169
+ ) {
1170
+ setDataGenericModal((prev) => ({
1171
+ ...prev,
1172
+ button2: {
1173
+ name: "Continuar",
1174
+ action: () => evaluationToRetailer("A"),
1175
+ },
1176
+ }));
1177
+ setShowGenericModal(true);
1178
+ } else {
1179
+ if (user.is_retailer) {
1180
+ if (product.id_order || product.orderId) {
1181
+ sendEvaluation("A");
1182
+ } else {
1183
+ setDataGenericModal((prev) => ({
1184
+ ...prev,
1185
+ button2: {
1186
+ name: "Continuar",
1187
+ action: () => evaluationToRetailer("A"),
1188
+ },
1189
+ }));
1190
+ setShowGenericModal(true);
1191
+ }
1192
+ } else {
1193
+ sendEvaluation("A");
1194
+ }
1195
+ }
1196
+ }}
1197
+ reject={() => {
1198
+ if (
1199
+ origin[getConcept(activeTab)] === "RequestWithoutContentoh" &&
1200
+ !user.is_retailer &&
1201
+ (!product.id_order || !product.orderId)
1202
+ ) {
1203
+ return;
1204
+ } else {
1205
+ if (user.is_retailer) {
1206
+ if (product.id_order || product.orderId) {
1207
+ sendEvaluation("R");
1208
+ setModalViewError(true);
1209
+ } else {
1210
+ setDataGenericModal((prev) => ({
1211
+ ...prev,
1212
+ button2: {
1213
+ name: "Continuar",
1214
+ action: () => evaluationToRetailer("R"),
1215
+ },
1216
+ }));
1217
+ setShowGenericModal(true);
1218
+ }
1219
+ } else {
1220
+ sendEvaluation("R");
1221
+ setModalViewError(true);
1222
+ }
1223
+ }
1224
+ }}
1225
+ />
1226
+ <FullTabsMenu
1227
+ tabsSections={tabsSections}
1228
+ status={product?.version_status}
1229
+ activeTab={activeTab}
1230
+ setActiveTab={setActiveTab}
1231
+ setImageLayout={setImageLayout}
1232
+ downloadImages={downloadImages}
1233
+ askToDeleteImages={askToDeleteImages}
1234
+ assig={assig}
1235
+ setAssignation={setAssignation}
1236
+ isRetailer={isRetailer}
1237
+ onClickSave={() => {
1238
+ switch (activeTab) {
1239
+ case "Descripción":
1240
+ saveDescriptions();
1241
+ break;
1242
+ case "Ficha técnica":
1243
+ saveDatasheets();
1244
+ break;
1245
+ case "Imágenes":
1246
+ updateImages();
1247
+ break;
1248
+ default:
1249
+ break;
1250
+ }
1251
+ }}
1252
+ />
1253
+ <div
1254
+ className={
1255
+ "services-information-container " +
1256
+ (imageLayout && activeTab === "Imágenes" ? "image-services" : "")
1257
+ }
1258
+ >
1259
+ {loading ? (
1260
+ <Loading />
1261
+ ) : (
1262
+ <>
1263
+ {!imageLayout &&
1264
+ activeTab === "Imágenes" &&
1265
+ product?.services?.images === 1 && (
1266
+ <GalleryHeader
1267
+ setSelectedImages={setSelectedImages}
1268
+ checkAll={checkAll}
1269
+ setCheckAll={setCheckAll}
1270
+ />
1271
+ )}
1272
+ {activeTab === "Ficha técnica" &&
1273
+ (product?.datasheet_status !== "NS" ? (
1274
+ datasheets[0]?.data?.map((dataGroup, index) => (
1275
+ <InputGroup
1276
+ key={index + "-" + activeRetailer.name}
1277
+ articleId={product.id_article}
1278
+ version={version}
1279
+ activeSection={activeTab}
1280
+ inputGroup={dataGroup}
1281
+ dataInputs={datasheets[1]}
1282
+ updatedDatasheets={updatedDatasheets}
1283
+ setUpdatedDatasheets={setUpdatedDatasheets}
1284
+ //enableActions={enableActions(product.version_status)} ADD THIS VALIDATION
1285
+ />
1286
+ ))
1287
+ ) : (
1288
+ <ScreenHeader
1289
+ text={"No cuentas con este servicio"}
1290
+ headerType={"input-name-header"}
1291
+ />
1292
+ ))}
1293
+ {activeTab === "Descripción" &&
1294
+ (product?.description_status !== "NS" ? (
1295
+ <InputGroup
1296
+ activeSection={activeTab}
1297
+ inputGroup={descriptions[0]}
1298
+ updatedDescriptions={updatedDescriptions}
1299
+ setUpdatedDescriptions={setUpdatedDescriptions}
1300
+ articleId={product?.id_article}
1301
+ version={version}
1302
+ dinamicHeight={true}
1303
+ />
1304
+ ) : (
1305
+ <ScreenHeader
1306
+ text={"No cuentas con este servicio"}
1307
+ headerType={"input-name-header"}
1308
+ />
1309
+ ))}
1310
+
1311
+ {activeTab === "Imágenes" &&
1312
+ (product?.images_status !== "NS" ? (
1313
+ <section className="container">
1314
+ <div {...getRootProps({ className: "dropzone" })}>
1315
+ <input {...getInputProps()} />
1316
+ <aside>{thumbs()}</aside>
1317
+ </div>
1318
+ </section>
1319
+ ) : (
1320
+ <ScreenHeader
1321
+ text={"No cuentas con este servicio"}
1322
+ headerType={"input-name-header"}
1323
+ />
1324
+ ))}
1325
+ </>
1326
+ )}
1327
+ </div>
1328
+ {isRevision() && getSectionStatus() ? (
1329
+ <div className="commentary-box">
1330
+ {!comment ? (
1331
+ <div className="commentary">
1332
+ <TagAndInput
1333
+ label={"Caja de Comentario"}
1334
+ inputType={"textarea"}
1335
+ inputCols={80}
1336
+ inputRows={4}
1337
+ inputId={"commentary-box"}
1338
+ index={0}
1339
+ />
1340
+ <div className="buttons-box">
1341
+ <Button
1342
+ buttonType={"general-transparent-button"}
1343
+ label={"Enviar comentario"}
1344
+ onClick={(e) =>
1345
+ createComment(
1346
+ e,
1347
+ document.querySelector(
1348
+ "#description-commentary-box-0 .ql-container .ql-editor > p"
1349
+ ).innerHTML,
1350
+ activeTab
1351
+ )
1352
+ }
1353
+ />
1354
+ </div>
1355
+ </div>
1356
+ ) : (
1357
+ <div className="feedback-box">
1358
+ <Commentary
1359
+ comment={comment.message}
1360
+ reviewed={crossComment}
1361
+ />
1362
+ <Button
1363
+ buttonType={"circular-button accept-button"}
1364
+ onClick={async () => {
1365
+ setCrossComment(true);
1366
+ commentRevised();
1367
+ }}
1368
+ />
1369
+ </div>
1370
+ )}
1371
+ <Button
1372
+ buttonType={
1373
+ evaluationComplete() &&
1374
+ (productEdit.product.id_order || productEdit.product.orderId)
1375
+ ? "general-green-button"
1376
+ : "general-button-disabled"
1377
+ }
1378
+ label={"Enviar evaluación"}
1379
+ onClick={() => {
1380
+ setModalSent(true);
1381
+ sendEvaluation();
1382
+ setMessage(
1383
+ `¡Evaluación de ${translateConcept()} completada!`
1384
+ );
1385
+ }}
1386
+ />
1387
+ </div>
1388
+ ) : revision ? null : (
1389
+ <div className="required-inputs-message">
1390
+ <div>
1391
+ <p>
1392
+ Los atributos son requeridos por las plataformas de las
1393
+ cadenas, es muy importante completar los campos requeridos ya
1394
+ que pueden rechazar el producto por falta de información.
1395
+ </p>
1396
+ </div>
1397
+ {inCart ? (
1398
+ <button type="button">
1399
+ <Link to="/checkout">
1400
+ <p>Articulo en carrito</p>
1401
+ <p>Ir a checkout</p>
1402
+ </Link>
1403
+ </button>
1404
+ ) : (
1405
+ <Button
1406
+ onClick={() => {
1407
+ setShowContentohRequestModal &&
1408
+ setShowContentohRequestModal(true);
1409
+ }}
1410
+ buttonType="general-default-button"
1411
+ label="Enviar a Content-oh!"
1412
+ />
1413
+ )}
1414
+ </div>
1415
+ )}
1416
+ </div>
1417
+ </div>
1418
+ {showModal && (
1419
+ <ProductImageModal images={images} setShowModal={setShowModal} />
1420
+ )}
1421
+ {message.length > 0 && (
1422
+ <GenericModal
1423
+ buttonType={componentsArray.length > 0 && "delete-product"}
1424
+ componentsArray={
1425
+ componentsArray.length > 0
1426
+ ? componentsArray
1427
+ : [
1428
+ <img key="1" src={succes} alt="success icon" />,
1429
+ <ScreenHeader
1430
+ key="2"
1431
+ headerType={"retailer-name-header"}
1432
+ text={message}
1433
+ color={"white"}
1434
+ />,
1435
+ ]
1436
+ }
1437
+ onClick={() => setMessage("")}
1438
+ />
1439
+ )}
1440
+ {modalSent && (
1441
+ <GlobalModal
1442
+ close={() => setModalSent(false)}
1443
+ message={message}
1444
+ detail={detail}
1445
+ bold={!evaluationComplete() && "Aprueba / Rechaza"}
1446
+ widthImg={!evaluationComplete() ? "160px" : "354px"}
1447
+ heightImg={!evaluationComplete() ? "84px" : "354px"}
1448
+ img={getSectionIcon()}
1449
+ />
1450
+ )}
1451
+ {modalViewError && (
1452
+ <GlobalModal
1453
+ close={() => setModalViewError(false)}
1454
+ message={`${activeTab} rechazada`}
1455
+ detail={"Agrega tu comentarios para enviar el rechazo"}
1456
+ button1={{
1457
+ name: "Enviar",
1458
+ action: (e) => {
1459
+ createComment(e, document.querySelector("#area").value);
1460
+ setModalViewError(false);
1461
+ setModalViewTextArea(true);
1462
+ },
1463
+ }}
1464
+ img={errorModal}
1465
+ textArea={true}
1466
+ />
1467
+ )}
1468
+ {showGenericModal && (
1469
+ <GlobalModal
1470
+ close={() => setShowGenericModal(false)}
1471
+ message={dataGenericModal.message}
1472
+ detail={dataGenericModal.detail}
1473
+ button1={dataGenericModal.button1}
1474
+ button2={dataGenericModal.button2}
1475
+ img={dataGenericModal.img}
1476
+ />
1477
+ )}
1478
+ {modalViewTextArea && (
1479
+ <GlobalModal
1480
+ close={() => setModalViewTextArea(false)}
1481
+ message={`Gracias, tus comentarios fueron entregados.`}
1482
+ detail={"Trabajaremos en conjunto para resolverlo."}
1483
+ button1={{
1484
+ name: "Cerrar",
1485
+ action: () => setModalViewTextArea(false),
1486
+ }}
1487
+ img={face}
1488
+ textArea={false}
1489
+ />
1490
+ )}
1491
+ </Container>
1492
+ );
1493
+ };