contentoh-components-library 21.0.28 → 21.0.31

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