contentoh-components-library 21.5.93 → 21.5.95

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 (70) hide show
  1. package/dist/ai/utils/compare-strings.js +45 -0
  2. package/dist/components/atoms/GeneralButton/styles.js +1 -1
  3. package/dist/components/atoms/GeneralInput/index.js +245 -54
  4. package/dist/components/atoms/GeneralInput/styles.js +7 -3
  5. package/dist/components/atoms/InputFormatter/index.js +223 -68
  6. package/dist/components/atoms/InputFormatter/styles.js +20 -4
  7. package/dist/components/molecules/StatusAsignationInfo/index.js +11 -1
  8. package/dist/components/molecules/TabsMenu/index.js +13 -12
  9. package/dist/components/molecules/TagAndInput/index.js +361 -24
  10. package/dist/components/molecules/TagAndInput/styles.js +2 -2
  11. package/dist/components/organisms/ChangeStatusModal/index.js +531 -0
  12. package/dist/components/organisms/ChangeStatusModal/styles.js +85 -0
  13. package/dist/components/organisms/FullProductNameHeader/index.js +6 -22
  14. package/dist/components/organisms/InputGroup/index.js +22 -18
  15. package/dist/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +150 -337
  16. package/dist/components/pages/ProviderProductEdition/context/provider-product-edition.context.js +15 -15
  17. package/dist/components/pages/ProviderProductEdition/index.js +408 -381
  18. package/dist/components/pages/ProviderProductEdition/utils.js +1 -0
  19. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +179 -196
  20. package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.context.js +59 -260
  21. package/dist/components/pages/RetailerProductEdition/context/reducers/product.js +50 -38
  22. package/dist/components/pages/RetailerProductEdition/index.js +1719 -2237
  23. package/dist/components/pages/RetailerProductEdition/styles.js +4 -2
  24. package/dist/components/pages/RetailerProductEdition/utils.js +251 -2
  25. package/dist/contexts/AiProductEdition.js +230 -158
  26. package/dist/global-files/statusDictionary.js +103 -0
  27. package/package.json +4 -2
  28. package/src/ai/utils/compare-strings.js +45 -0
  29. package/src/assets/images/Icons/arrow.png +0 -0
  30. package/src/assets/images/Icons/cancel.png +0 -0
  31. package/src/assets/images/Icons/ia-icon.png +0 -0
  32. package/src/assets/images/Icons/loading.svg +5 -0
  33. package/src/assets/images/Icons/reload.png +0 -0
  34. package/src/components/atoms/GeneralButton/styles.js +4 -0
  35. package/src/components/atoms/GeneralInput/index.js +237 -60
  36. package/src/components/atoms/GeneralInput/styles.js +81 -0
  37. package/src/components/atoms/InputFormatter/index.js +200 -51
  38. package/src/components/atoms/InputFormatter/styles.js +284 -0
  39. package/src/components/atoms/RetailerSelector/RetailerSelector.stories.js +10 -0
  40. package/src/components/atoms/RetailerSelector/index.js +3 -0
  41. package/src/components/atoms/RetailerSelector/styles.js +0 -0
  42. package/src/components/molecules/StatusAsignationInfo/index.js +9 -1
  43. package/src/components/molecules/TabsMenu/index.js +12 -11
  44. package/src/components/molecules/TagAndInput/index.js +286 -21
  45. package/src/components/molecules/TagAndInput/styles.js +59 -17
  46. package/src/components/organisms/ChangeStatusModal/index.jsx +488 -0
  47. package/src/components/organisms/ChangeStatusModal/styles.js +333 -0
  48. package/src/components/organisms/FullProductNameHeader/index.js +4 -28
  49. package/src/components/organisms/FullTabsMenu/index.js +1 -1
  50. package/src/components/organisms/InputGroup/index.js +12 -4
  51. package/src/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +174 -202
  52. package/src/components/pages/ProviderProductEdition/context/provider-product-edition.context.jsx +14 -14
  53. package/src/components/pages/ProviderProductEdition/index.js +489 -457
  54. package/src/components/pages/ProviderProductEdition/utils.js +2 -2
  55. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +201 -224
  56. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +575 -0
  57. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +62 -0
  58. package/src/components/pages/RetailerProductEdition/context/reducers/active-state.js +344 -0
  59. package/src/components/pages/RetailerProductEdition/context/reducers/inputs.js +155 -0
  60. package/src/components/pages/RetailerProductEdition/context/reducers/product.js +114 -0
  61. package/src/components/pages/RetailerProductEdition/context/reducers/system.js +60 -0
  62. package/src/components/pages/RetailerProductEdition/index.js +1545 -1718
  63. package/src/components/pages/RetailerProductEdition/index_old.js +1979 -0
  64. package/src/components/pages/RetailerProductEdition/stories/Auditor.stories.js +101 -0
  65. package/src/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +115 -0
  66. package/src/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +174 -0
  67. package/src/components/pages/RetailerProductEdition/styles.js +67 -2
  68. package/src/components/pages/RetailerProductEdition/utils.js +240 -0
  69. package/src/contexts/AiProductEdition.jsx +339 -0
  70. package/src/global-files/statusDictionary.js +103 -0
@@ -42,6 +42,7 @@ import errorIcon from "../../../assets/images/genericModal/errorModal.svg";
42
42
  import warningIcon from "../../../assets/images/genericModal/genericModalWarning.svg";
43
43
 
44
44
  import { Container } from "./styles";
45
+ import { AiProductEditionProvider } from "../../../contexts/AiProductEdition";
45
46
 
46
47
  const ProviderProductEditionView = ({
47
48
  tabsSections,
@@ -142,13 +143,10 @@ const ProviderProductEditionView = ({
142
143
  useEffect(() => {
143
144
  const setProductData = () => {
144
145
  try {
145
- const product = JSON.parse(sessionStorage.getItem("productSelected"))
146
- ? JSON.parse(sessionStorage.getItem("productSelected"))
147
- : productSelected;
148
146
 
149
- const productNormalized = normalizeProduct(product);
147
+ const product = productSelected ? productSelected : JSON.parse(sessionStorage.getItem("productSelected"));
150
148
 
151
- console.log({ productNormalized });
149
+ const productNormalized = normalizeProduct(product);
152
150
 
153
151
  dispatch({
154
152
  type: "SET_PRODUCT",
@@ -156,22 +154,7 @@ const ProviderProductEditionView = ({
156
154
  });
157
155
  dispatch({
158
156
  type: "SET_ACTIVE_RETAILER",
159
- payload: productNormalized.categoryRetailerInOrder[0],
160
- });
161
- const firstRetailerStatus =
162
- productNormalized.statusByRetailer[
163
- productNormalized.categoryRetailerInOrder[0].id_retailer
164
- ];
165
- const initialTab = firstRetailerStatus.description
166
- ? "Descripción"
167
- : firstRetailerStatus.datasheet
168
- ? "Ficha técnica"
169
- : firstRetailerStatus.images
170
- ? "Imágenes"
171
- : "Imágenes";
172
- dispatch({
173
- type: "SET_ACTIVE_TAB",
174
- payload: initialTab,
157
+ payload: productNormalized.categoryRetailer[0],
175
158
  });
176
159
  } catch (error) {
177
160
  console.log("Error setting product data: ", error);
@@ -216,7 +199,7 @@ const ProviderProductEditionView = ({
216
199
  id_category,
217
200
  version,
218
201
  token,
219
- id_retailer,
202
+ id_retailer
220
203
  ),
221
204
  getPercentage({ data, headers }),
222
205
  getServicesData({
@@ -244,6 +227,25 @@ const ProviderProductEditionView = ({
244
227
  return orderA - orderB;
245
228
  });
246
229
 
230
+ //Cuando carguemos la información de los servicios, las actualizamos en el estado del producto
231
+
232
+ const updatedStatusByRetailer = servicesDataRes.reduce((acc, current, idx) => {
233
+
234
+ const { id_retailer, service, status } = current;
235
+
236
+ if(!acc[id_retailer]) acc[id_retailer] = {};
237
+
238
+ acc[id_retailer][service] = status;
239
+
240
+ return acc;
241
+
242
+ }, {});
243
+
244
+ dispatch({ type: "SET_PRODUCT", payload: {
245
+ ...state.product,
246
+ statusByRetailer: updatedStatusByRetailer
247
+ }});
248
+
247
249
  dispatch({
248
250
  type: "SET_SERVICES",
249
251
  payload: {
@@ -263,7 +265,7 @@ const ProviderProductEditionView = ({
263
265
  dispatch({
264
266
  type: "SET_ACTIVE_PERCENTAGES",
265
267
  payload: percentages.find(
266
- ({ id_retailer: rId }) => rId === id_retailer,
268
+ ({ id_retailer: rId }) => rId === id_retailer
267
269
  ),
268
270
  });
269
271
  } catch (error) {
@@ -275,7 +277,16 @@ const ProviderProductEditionView = ({
275
277
  };
276
278
 
277
279
  fetchData();
278
- }, [state.product, state.active_retailer, token]);
280
+ }, [
281
+ state.product?.datasheet_status,
282
+ state.product?.description_status,
283
+ state.product?.images_status,
284
+ state.product?.status,
285
+ state.product?.percentages,
286
+ state.product?.version,
287
+ state.active_retailer,
288
+ token
289
+ ]);
279
290
 
280
291
  // Actualizador de campos del ui para que coincidan con el retailer activo
281
292
  useEffect(() => {
@@ -283,51 +294,46 @@ const ProviderProductEditionView = ({
283
294
  console.log("Actualizar inputs del retailer activo");
284
295
  const updateInputsActiveRetailer = () => {
285
296
  if (!state.services) return;
286
- if (state.services.datasheets) {
287
- const retailerDatasheets =
288
- state.services.datasheets[state.active_retailer.id_retailer];
289
297
 
290
- const datasheetsActiveRetailer = {
291
- ...retailerDatasheets,
292
- data: Object.values(retailerDatasheets.data),
293
- };
298
+ const retailerDatasheets =
299
+ state.services.datasheets[state.active_retailer.id_retailer];
294
300
 
295
- dispatch({
296
- type: "SET_DATASHEETS_INPUTS",
297
- payload: [datasheetsActiveRetailer, state.services.datasheets.inputs],
298
- });
299
- }
301
+ const datasheetsActiveRetailer = {
302
+ ...retailerDatasheets,
303
+ data: Object.values(retailerDatasheets.data),
304
+ };
300
305
 
301
- if (state.services.descriptions) {
302
- const descriptionsActiveRetailer = state.services.descriptions.filter(
303
- (item) => item.id === state.active_retailer.id_retailer,
306
+ const descriptionsActiveRetailer = state.services.descriptions.filter(
307
+ (item) => item.id === state.active_retailer.id_retailer
308
+ );
309
+
310
+ const filteredValues = state.services.images.values.filter((value) => {
311
+ return state.services.images.inputsByRetailer.some((retailerInput) =>
312
+ retailerInput.some(
313
+ (input) =>
314
+ input.id_retailer === state.active_retailer.id_retailer &&
315
+ input.id_image === value.image_id
316
+ )
304
317
  );
318
+ });
305
319
 
306
- dispatch({
307
- type: "SET_DESCRIPTIONS_INPUTS",
308
- payload: descriptionsActiveRetailer,
309
- });
310
- }
320
+ dispatch({
321
+ type: "SET_DATASHEETS_INPUTS",
322
+ payload: [datasheetsActiveRetailer, state.services.datasheets.inputs],
323
+ });
311
324
 
312
- if (state.services.images) {
313
- const filteredValues = state.services.images.values.filter((value) => {
314
- return state.services.images.inputsByRetailer.some((retailerInput) =>
315
- retailerInput.some(
316
- (input) =>
317
- input.id_retailer === state.active_retailer.id_retailer &&
318
- input.id_image === value.image_id,
319
- ),
320
- );
321
- });
325
+ dispatch({
326
+ type: "SET_DESCRIPTIONS_INPUTS",
327
+ payload: descriptionsActiveRetailer,
328
+ });
322
329
 
323
- dispatch({
324
- type: "SET_IMAGES_VALUES",
325
- payload: {
326
- ...state.services.images,
327
- values: filteredValues,
328
- },
329
- });
330
- }
330
+ dispatch({
331
+ type: "SET_IMAGES_VALUES",
332
+ payload: {
333
+ ...state.services.images,
334
+ values: filteredValues,
335
+ },
336
+ });
331
337
  };
332
338
 
333
339
  updateInputsActiveRetailer();
@@ -338,7 +344,14 @@ const ProviderProductEditionView = ({
338
344
  if (!state.product?.statusByRetailer) return false;
339
345
 
340
346
  const currentService = getConceptByTab(state.active_tab);
341
- const currentStatus = state.product[`${currentService}_status`];
347
+ // const currentStatus = state.product[`${currentService}_status`];
348
+ const currentRetailer = state.active_retailer.id_retailer;
349
+
350
+ //Información del servicio de la cadena seleccionada
351
+ const {
352
+ status: currentStatus
353
+ } = state.services_data.find(service => service.service === currentService && service.id_retailer === currentRetailer);
354
+
342
355
  const originTab = origin[state.active_tab];
343
356
  const isRetailerUser = user?.is_retailer === 1;
344
357
 
@@ -361,13 +374,17 @@ const ProviderProductEditionView = ({
361
374
  // No retailer
362
375
  const hasNoOrder = !state.product.id_order && !state.product.orderId;
363
376
 
364
- return (
365
- (originTab === "RequestWithoutContentoh" &&
366
- (["R", "CA"].includes(currentStatus) ||
367
- (currentStatus === "RCA" && hasNoOrder))) ||
368
- (["RequestWithContentoh", "Contentoh"].includes(originTab) &&
369
- currentStatus === "AA")
370
- );
377
+ const condition =
378
+ (
379
+ originTab === "RequestWithoutContentoh" && (
380
+ ["R", "CA"].includes(currentStatus) || (currentStatus === "RCA" && hasNoOrder)
381
+ )
382
+ ) ||
383
+ (
384
+ ["RequestWithContentoh", "Contentoh"].includes(originTab) && currentStatus === "AA"
385
+ )
386
+
387
+ return condition;
371
388
  };
372
389
 
373
390
  const canShowSaveButton = (version_status) => {
@@ -388,6 +405,7 @@ const ProviderProductEditionView = ({
388
405
 
389
406
  const currentService = getConceptByTab(state.active_tab);
390
407
  const currentRetailer = state.active_retailer.id_retailer;
408
+
391
409
  const currentStatus =
392
410
  statusByRetailer[currentRetailer][currentService] || "ERR";
393
411
  return currentStatus;
@@ -399,7 +417,7 @@ const ProviderProductEditionView = ({
399
417
  name: e?.name,
400
418
  required: e?.required,
401
419
  active: state.images_values?.values?.some(
402
- (value) => value?.image_id === e?.id,
420
+ (value) => value?.image_id === e?.id
403
421
  ),
404
422
  }));
405
423
  const imageType = state.images_values?.imageType?.map((e) => ({
@@ -410,7 +428,7 @@ const ProviderProductEditionView = ({
410
428
  (e) => ({
411
429
  value: e?.id,
412
430
  name: e?.name,
413
- }),
431
+ })
414
432
  );
415
433
 
416
434
  return state.images_values?.values?.map((image, index) => (
@@ -651,6 +669,7 @@ const ProviderProductEditionView = ({
651
669
  state.product[sectionStatusKey] || state.product?.version_status;
652
670
 
653
671
  let data = { articleId, orderId, concept, evalStatus };
672
+
654
673
  const retailerId = state.active_retailer?.id_retailer;
655
674
 
656
675
  try {
@@ -665,13 +684,15 @@ const ProviderProductEditionView = ({
665
684
  headers: {
666
685
  Authorization: token,
667
686
  },
668
- },
687
+ }
669
688
  );
670
689
 
671
690
  const newStatuses = JSON.parse(res.data.body);
672
691
  const serviceStatus =
673
692
  newStatuses.newServiceStatus[articleId][`${concept}Status`];
674
693
 
694
+ console.log({product: state.product, newStatuses, serviceStatus, servicesData: state.services_data});
695
+
675
696
  // Actualizar el producto con los nuevos estados
676
697
  const updatedProduct = {
677
698
  ...state.product,
@@ -679,12 +700,19 @@ const ProviderProductEditionView = ({
679
700
  ...state.product.statusByRetailer,
680
701
  [retailerId]: {
681
702
  ...state.product.statusByRetailer[retailerId],
682
- [concept]: serviceStatus,
703
+ [concept]: newStatuses?.newStatus ?? serviceStatus,
683
704
  },
684
705
  },
685
706
  };
686
707
 
687
- console.log({ updatedProduct });
708
+ const updatedServicesData = state.services_data?.map(service => ({
709
+ ...service,
710
+ status: service?.id_retailer === retailerId && service?.service === concept ? (newStatuses?.newStatus ?? serviceStatus) : service?.status
711
+ }));
712
+
713
+ dispatch({ type: "SET_SERVICES_DATA", payload: updatedServicesData });
714
+
715
+ // console.log({ updatedProduct });
688
716
 
689
717
  dispatch({ type: "SET_PRODUCT", payload: updatedProduct });
690
718
 
@@ -913,7 +941,7 @@ const ProviderProductEditionView = ({
913
941
  headers: {
914
942
  Authorization: token,
915
943
  },
916
- }),
944
+ })
917
945
  );
918
946
  });
919
947
 
@@ -958,7 +986,7 @@ const ProviderProductEditionView = ({
958
986
  ArticleId: updatedProduct.id_article,
959
987
  idCategory: updatedProduct.id_category,
960
988
  product: updatedProduct,
961
- }),
989
+ })
962
990
  );
963
991
 
964
992
  // Mostrar modal de éxito
@@ -1024,418 +1052,422 @@ const ProviderProductEditionView = ({
1024
1052
  if (state.loading || !state.services || !state.product) return <Loading />;
1025
1053
 
1026
1054
  return (
1027
- <Container headerTop={headerTop}>
1028
- {/* <button onClick={() => console.log(state)}>log</button> */}
1029
- {showVersionSelector && (
1030
- <VersionSelector
1031
- modalId={"version-selector"}
1032
- articleId={state.product.id_article}
1033
- setVersion={handleOnChangeProductVersion}
1034
- companyName={company.company_name}
1035
- currentVersion={state.product.version}
1036
- setShowVersionSelector={setShowVersionSelector}
1037
- jwt={token}
1038
- />
1039
- )}
1040
- {showModal && (
1041
- <ProductImageModal
1042
- images={state.images_values}
1043
- setShowModal={setShowModal}
1044
- approveRejectButtons={canShowValidationButtons()}
1045
- sendToFacilitator={handleOnSendEvaluation}
1046
- />
1047
- )}
1048
- {state.modal.show && (
1049
- <GenericModal
1050
- componentsArray={[
1051
- state.modal.image && (
1052
- <img key="1" src={state.modal.image} alt="modal icon" />
1053
- ),
1054
- state.modal.title && (
1055
- <ScreenHeader
1056
- key="2"
1057
- headerType={"retailer-name-header"}
1058
- text={state.modal.title}
1059
- color={"white"}
1060
- />
1061
- ),
1062
- state.modal.message && (
1063
- <ScreenHeader
1064
- key="3"
1065
- headerType={"retailer-name-header"}
1066
- text={state.modal.message}
1055
+ <AiProductEditionProvider
1056
+ isCreatorsEdition={false}
1057
+ state={state}
1058
+ >
1059
+ <Container headerTop={headerTop}>
1060
+ {showVersionSelector && (
1061
+ <VersionSelector
1062
+ modalId={"version-selector"}
1063
+ articleId={state.product.id_article}
1064
+ setVersion={handleOnChangeProductVersion}
1065
+ companyName={company.company_name}
1066
+ currentVersion={state.product.version}
1067
+ setShowVersionSelector={setShowVersionSelector}
1068
+ jwt={token}
1069
+ />
1070
+ )}
1071
+ {showModal && (
1072
+ <ProductImageModal
1073
+ images={state.images_values}
1074
+ setShowModal={setShowModal}
1075
+ approveRejectButtons={canShowValidationButtons()}
1076
+ sendToFacilitator={handleOnSendEvaluation}
1077
+ />
1078
+ )}
1079
+ {state.modal.show && (
1080
+ <GenericModal
1081
+ componentsArray={[
1082
+ state.modal.image && (
1083
+ <img key="1" src={state.modal.image} alt="modal icon" />
1084
+ ),
1085
+ state.modal.title && (
1086
+ <ScreenHeader
1087
+ key="2"
1088
+ headerType={"retailer-name-header"}
1089
+ text={state.modal.title}
1090
+ color={"white"}
1091
+ />
1092
+ ),
1093
+ state.modal.message && (
1094
+ <ScreenHeader
1095
+ key="3"
1096
+ headerType={"retailer-name-header"}
1097
+ text={state.modal.message}
1098
+ color={"white"}
1099
+ />
1100
+ ),
1101
+ state.modal.buttons && (
1102
+ <div key="4" style={{ marginTop: "16px" }}>
1103
+ {state.modal.buttons.map((button, index) => (
1104
+ <Button
1105
+ key={index}
1106
+ buttonType={button.buttonType}
1107
+ label={button.text}
1108
+ onClick={button.action}
1109
+ />
1110
+ ))}
1111
+ </div>
1112
+ ),
1113
+ ].filter(Boolean)}
1114
+ onClick={() =>
1115
+ dispatch({
1116
+ type: "SET_MODAL",
1117
+ payload: { show: false, title: "", message: "", image: null },
1118
+ })
1119
+ }
1120
+ />
1121
+ )}
1122
+ {showRejectModal && (
1123
+ <Modal
1124
+ title={
1125
+ rejectAll
1126
+ ? "Agregar mensaje para rechazar todo"
1127
+ : "Agregar mensaje de rechazo"
1128
+ }
1129
+ show={showRejectModal}
1130
+ customComponent={
1131
+ <TagAndInput
1132
+ inputType={"textarea"}
1133
+ inputId={"modal-message-box"}
1134
+ index={0}
1067
1135
  color={"white"}
1068
1136
  />
1069
- ),
1070
- state.modal.buttons && (
1071
- <div key="4" style={{ marginTop: "16px" }}>
1072
- {state.modal.buttons.map((button, index) => (
1073
- <Button
1074
- key={index}
1075
- buttonType={button.buttonType}
1076
- label={button.text}
1077
- onClick={button.action}
1078
- />
1079
- ))}
1080
- </div>
1081
- ),
1082
- ].filter(Boolean)}
1083
- onClick={() =>
1084
- dispatch({
1085
- type: "SET_MODAL",
1086
- payload: { show: false, title: "", message: "", image: null },
1087
- })
1088
- }
1089
- />
1090
- )}
1091
- {showRejectModal && (
1092
- <Modal
1093
- title={
1094
- rejectAll
1095
- ? "Agregar mensaje para rechazar todo"
1096
- : "Agregar mensaje de rechazo"
1097
- }
1098
- show={showRejectModal}
1099
- customComponent={
1100
- <TagAndInput
1101
- inputType={"textarea"}
1102
- inputId={"modal-message-box"}
1103
- index={0}
1104
- color={"white"}
1105
- />
1106
- }
1107
- buttons={[
1108
- <ButtonV2
1109
- key={"btn-Cancelar"}
1110
- type={"white"}
1111
- label={"Cancelar"}
1112
- size={12}
1113
- onClick={() => {
1114
- setShowRejectModal(false);
1115
- }}
1116
- />,
1117
- <ButtonV2
1118
- key={"btn-Aceptar"}
1119
- type={"pink"}
1120
- label={"Aceptar"}
1121
- size={12}
1122
- onClick={async () => {
1123
- const elements = document.querySelectorAll(
1124
- "#modal-message-box .ql-container .ql-editor > p",
1125
- );
1126
-
1127
- if (!elements || elements.length === 0) {
1128
- console.error("Elemento no encontrado");
1129
- return;
1130
- }
1137
+ }
1138
+ buttons={[
1139
+ <ButtonV2
1140
+ key={"btn-Cancelar"}
1141
+ type={"white"}
1142
+ label={"Cancelar"}
1143
+ size={12}
1144
+ onClick={() => {
1145
+ setShowRejectModal(false);
1146
+ }}
1147
+ />,
1148
+ <ButtonV2
1149
+ key={"btn-Aceptar"}
1150
+ type={"pink"}
1151
+ label={"Aceptar"}
1152
+ size={12}
1153
+ onClick={async () => {
1154
+ const elements = document.querySelectorAll(
1155
+ "#modal-message-box .ql-container .ql-editor > p"
1156
+ );
1131
1157
 
1132
- const isMessageEmpty = Array.from(elements).every((el) => {
1133
- const body = el.innerHTML;
1134
- return !body || body.replace(/<.*?\/?>/gm, "").trim() === "";
1135
- });
1158
+ if (!elements || elements.length === 0) {
1159
+ console.error("Elemento no encontrado");
1160
+ return;
1161
+ }
1136
1162
 
1137
- if (isMessageEmpty) {
1138
- const container = document.querySelector(
1139
- ".container-customComponent",
1140
- );
1141
- const existingAlert = container.querySelector(".alert-error");
1142
-
1143
- if (!existingAlert) {
1144
- const alert = document.createElement("div");
1145
- alert.className = "alert-error";
1146
- alert.style.cssText = `
1147
- color: #d32f2f;
1148
- background-color: #ffebee;
1149
- border: 1px solid #ef5350;
1150
- border-radius: 4px;
1151
- padding: 12px 16px;
1152
- margin-top: 10px;
1153
- font-size: 14px;
1154
- display: flex;
1155
- align-items: center;
1156
- gap: 8px;
1157
- font-family: 'Roboto', sans-serif;
1158
- text-align: center;
1159
- `;
1160
- alert.innerHTML = `<span>El mensaje no puede estar vacío.</span>`;
1161
- container.appendChild(alert);
1163
+ const isMessageEmpty = Array.from(elements).every((el) => {
1164
+ const body = el.innerHTML;
1165
+ return !body || body.replace(/<.*?\/?>/gm, "").trim() === "";
1166
+ });
1167
+
1168
+ if (isMessageEmpty) {
1169
+ const container = document.querySelector(
1170
+ ".container-customComponent"
1171
+ );
1172
+ const existingAlert = container.querySelector(".alert-error");
1173
+
1174
+ if (!existingAlert) {
1175
+ const alert = document.createElement("div");
1176
+ alert.className = "alert-error";
1177
+ alert.style.cssText = `
1178
+ color: #d32f2f;
1179
+ background-color: #ffebee;
1180
+ border: 1px solid #ef5350;
1181
+ border-radius: 4px;
1182
+ padding: 12px 16px;
1183
+ margin-top: 10px;
1184
+ font-size: 14px;
1185
+ display: flex;
1186
+ align-items: center;
1187
+ gap: 8px;
1188
+ font-family: 'Roboto', sans-serif;
1189
+ text-align: center;
1190
+ `;
1191
+ alert.innerHTML = `<span>El mensaje no puede estar vacío.</span>`;
1192
+ container.appendChild(alert);
1193
+ }
1194
+ return;
1162
1195
  }
1163
- return;
1164
- }
1165
1196
 
1166
- const fullMessage = Array.from(elements)
1167
- .map((element) => element.innerHTML)
1168
- .join("")
1169
- .replace(/<br\s*\/?>/gi, "\n");
1197
+ const fullMessage = Array.from(elements)
1198
+ .map((element) => element.innerHTML)
1199
+ .join("")
1200
+ .replace(/<br\s*\/?>/gi, "\n");
1170
1201
 
1171
- await createComment(fullMessage);
1202
+ await createComment(fullMessage, token);
1172
1203
 
1173
- rejectAll
1174
- ? handleOnEvaluateAll("R")
1175
- : handleOnSendEvaluation("R");
1176
- setShowRejectModal(false);
1177
- }}
1178
- />,
1179
- ]}
1180
- />
1181
- )}
1182
- <HeaderTop
1183
- setHeaderTop={setHeaderTop}
1184
- withChat={location?.state?.withChat}
1185
- chatType={location?.state?.chatType}
1186
- productSelected={state.product}
1187
- token={token}
1188
- activeRetailer={{
1189
- id: state.active_retailer?.id_retailer,
1190
- name: state.active_retailer?.retailer,
1191
- }}
1192
- />
1193
- <div className="data-container">
1194
- <div className="image-data-panel">
1195
- <ImagePreviewer
1196
- activeImage={state.images_values.values[state.current_image] ?? {}}
1197
- imagesArray={state.images_values || []}
1198
- setActiveImage={handleOnChangeCurrentImage}
1199
- setShowModal={handleOnShowModalGalery}
1200
- />
1201
- <ImageDataTable
1202
- lists={state.images_values || []}
1203
- activeImage={
1204
- state.images_values?.values
1205
- ? state.images_values?.values[state.current_image]
1206
- : {}
1207
- }
1208
- assignationsImages={assig}
1209
- retailerSelected={state.active_retailer?.id_retailer}
1210
- imagesStatus={state.product?.images_status || "-"}
1211
- isRetailer={isRetailer}
1212
- setShowVersionSelector={setShowVersionSelector}
1213
- version={state.product.version}
1214
- setImages={handleOnChangeCurrentImage}
1215
- onClickSave={handleOnClickSaveImages}
1216
- setAssignation={handleOnChangeAssignations} // No se usa?
1204
+ rejectAll
1205
+ ? handleOnEvaluateAll("R")
1206
+ : handleOnSendEvaluation("R");
1207
+ setShowRejectModal(false);
1208
+ }}
1209
+ />,
1210
+ ]}
1217
1211
  />
1218
- </div>
1219
- <div className="product-information">
1220
- <div className="product-information">
1221
- <FullProductNameHeader
1222
- headerData={state.product}
1223
- percent={state.active_percentage.percentagesGeneral.required}
1224
- activeRetailer={{
1225
- id: state.active_retailer?.id_retailer,
1226
- name: state.active_retailer?.retailer,
1227
- image: state.active_retailer?.image,
1228
- }}
1229
- showValidationButtons={canShowValidationButtons()}
1230
- showApproveRejectAll={canShowValidationButtons()}
1231
- servicesData={state.services_data ? state.services_data : null}
1232
- approveAll={handleOnApproveAll}
1233
- rejectAll={handleOnRejectAll}
1234
- approve={() => handleOnSendEvaluation("A")}
1235
- reject={handleOnReject}
1236
- setActiveRetailer={handleOnChangeActiveRetailer}
1212
+ )}
1213
+ <HeaderTop
1214
+ setHeaderTop={setHeaderTop}
1215
+ withChat={location?.state?.withChat}
1216
+ chatType={location?.state?.chatType}
1217
+ productSelected={state.product}
1218
+ token={token}
1219
+ activeRetailer={{
1220
+ id: state.active_retailer?.id_retailer,
1221
+ name: state.active_retailer?.retailer,
1222
+ }}
1223
+ />
1224
+ <div className="data-container">
1225
+ <div className="image-data-panel">
1226
+ <ImagePreviewer
1227
+ activeImage={state.images_values.values[state.current_image] ?? {}}
1228
+ imagesArray={state.images_values || []}
1229
+ setActiveImage={handleOnChangeCurrentImage}
1230
+ setShowModal={handleOnShowModalGalery}
1237
1231
  />
1238
- <FullTabsMenu
1239
- tabsSections={tabsSections}
1240
- status={getStatusByCurrentServiceAndRetailer()}
1241
- activeTab={state.active_tab}
1242
- user={user}
1232
+ <ImageDataTable
1233
+ lists={state.images_values || []}
1234
+ activeImage={
1235
+ state.images_values?.values
1236
+ ? state.images_values?.values[state.current_image]
1237
+ : {}
1238
+ }
1239
+ assignationsImages={assig}
1240
+ retailerSelected={state.active_retailer?.id_retailer}
1241
+ imagesStatus={state.product?.images_status || "-"}
1243
1242
  isRetailer={isRetailer}
1244
- assig={assig}
1245
- version={state.product.version}
1246
- updatedDescriptions={state.updated_descriptions_inputs}
1247
- updatedDatasheets={state.updated_datasheets_inputs}
1248
- updatedImages={state.updated_images_values}
1249
- images={state.services.images}
1250
- // actions
1251
- downloadImages={handleOnDownloadImages}
1252
- askToDeleteImages={handleOnAskToDeleteImages}
1253
- showSaveButton={canShowSaveButton(state.product.version_status)}
1254
- onClickSave={handleOnClickSave}
1255
- // setters
1256
- setActiveTab={handleOnChangeActiveTab}
1257
- setImageLayout={handleOnSetImageLayout}
1258
- setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1259
- setUpdatedDatasheets={handleOnSetUpdatedDatasheets}
1260
- setAssignation={handleOnSetAssignation} // No se usa?
1261
- setImages={handleOnSetImages} // No se usa?
1262
- // setSelectedImages={handleOnSetSelectedImages} // Se pasa hasta TabsMenu, pero no se usa
1263
1243
  setShowVersionSelector={setShowVersionSelector}
1244
+ version={state.product.version}
1245
+ setImages={handleOnChangeCurrentImage}
1246
+ onClickSave={handleOnClickSaveImages}
1247
+ setAssignation={handleOnChangeAssignations} // No se usa?
1264
1248
  />
1265
- <div
1266
- className={
1267
- "services-information-container " +
1268
- (imageLayout && state.active_tab === "Imágenes"
1269
- ? "image-services"
1270
- : "")
1271
- }
1272
- >
1273
- {state.saving ? (
1274
- <Loading />
1275
- ) : (
1276
- <>
1277
- {state.active_tab === "Descripción" &&
1278
- (state.product?.description_status !== "NS" ? (
1279
- <InputGroup
1280
- activeSection={state.active_tab}
1281
- inputGroup={state.descriptions_inputs[0]}
1282
- updatedDescriptions={state.updated_descriptions_inputs}
1283
- articleId={state.product?.id_article}
1284
- version={state.product.version}
1285
- isShowbox={false}
1286
- dinamicHeight={true}
1287
- setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1288
- updateApprovedInputs={handleOnUpdateApprovedInputs} // No se usa?
1289
- />
1290
- ) : (
1291
- <ScreenHeader
1292
- text={"No cuentas con este servicio"}
1293
- headerType={"input-name-header"}
1294
- />
1295
- ))}
1296
-
1297
- {state.active_tab === "Ficha técnica" &&
1298
- (state.product?.datasheet_status !== "NS" ? (
1299
- <>
1300
- {state.datasheets_inputs[0]?.data?.map(
1301
- (dataGroup, index) => (
1302
- <InputGroup
1303
- index={index}
1304
- key={index + "-" + state.active_retailer.retailer}
1305
- articleId={state.product.id_article}
1306
- version={state.version}
1307
- activeSection={state.active_tab}
1308
- inputGroup={dataGroup}
1309
- dataInputs={state.datasheets_inputs[1]}
1310
- activeRetailer={
1311
- state.services.datasheets[
1312
- state.active_retailer.id_retailer
1313
- ]
1314
- }
1315
- groupData={
1316
- state.services.datasheets[
1317
- state.active_retailer.id_retailer
1318
- ].data
1319
- }
1320
- updatedDatasheets={
1321
- state.updated_datasheets_inputs
1322
- }
1323
- setUpdatedDatasheets={
1324
- handleOnSetUpdatedDatasheets
1325
- }
1326
- isShowbox={true}
1327
- setUpdatedBoxData={(e) => {
1328
- setBoxData(e);
1329
- }}
1330
- updateApprovedInputs={
1331
- handleOnUpdateApprovedInputs // No se usa?
1332
- }
1249
+ </div>
1250
+ <div className="product-information">
1251
+ <div className="product-information">
1252
+ <FullProductNameHeader
1253
+ headerData={state.product}
1254
+ percent={state.active_percentage.percentagesGeneral.required}
1255
+ activeRetailer={{
1256
+ id: state.active_retailer?.id_retailer,
1257
+ name: state.active_retailer?.retailer,
1258
+ image: state.active_retailer?.image,
1259
+ }}
1260
+ showValidationButtons={canShowValidationButtons()}
1261
+ showApproveRejectAll={canShowValidationButtons()}
1262
+ servicesData={state.services_data ? state.services_data : null}
1263
+ approveAll={handleOnApproveAll}
1264
+ rejectAll={handleOnRejectAll}
1265
+ approve={() => handleOnSendEvaluation("A")}
1266
+ reject={handleOnReject}
1267
+ setActiveRetailer={handleOnChangeActiveRetailer}
1268
+ />
1269
+ <FullTabsMenu
1270
+ tabsSections={tabsSections}
1271
+ status={getStatusByCurrentServiceAndRetailer()}
1272
+ activeTab={state.active_tab}
1273
+ user={user}
1274
+ isRetailer={isRetailer}
1275
+ assig={assig}
1276
+ version={state.product.version}
1277
+ updatedDescriptions={state.updated_descriptions_inputs}
1278
+ updatedDatasheets={state.updated_datasheets_inputs}
1279
+ updatedImages={state.updated_images_values}
1280
+ images={state.services.images}
1281
+ // actions
1282
+ downloadImages={handleOnDownloadImages}
1283
+ askToDeleteImages={handleOnAskToDeleteImages}
1284
+ showSaveButton={canShowSaveButton(state.product.version_status)}
1285
+ onClickSave={handleOnClickSave}
1286
+ // setters
1287
+ setActiveTab={handleOnChangeActiveTab}
1288
+ setImageLayout={handleOnSetImageLayout}
1289
+ setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1290
+ setUpdatedDatasheets={handleOnSetUpdatedDatasheets}
1291
+ setAssignation={handleOnSetAssignation} // No se usa?
1292
+ setImages={handleOnSetImages} // No se usa?
1293
+ // setSelectedImages={handleOnSetSelectedImages} // Se pasa hasta TabsMenu, pero no se usa
1294
+ setShowVersionSelector={setShowVersionSelector}
1295
+ />
1296
+ <div
1297
+ className={
1298
+ "services-information-container " +
1299
+ (imageLayout && state.active_tab === "Imágenes"
1300
+ ? "image-services"
1301
+ : "")
1302
+ }
1303
+ >
1304
+ {state.saving ? (
1305
+ <Loading />
1306
+ ) : (
1307
+ <>
1308
+ {state.active_tab === "Descripción" &&
1309
+ (state.product?.description_status !== "NS" ? (
1310
+ <InputGroup
1311
+ activeSection={state.active_tab}
1312
+ inputGroup={state.descriptions_inputs[0]}
1313
+ updatedDescriptions={state.updated_descriptions_inputs}
1314
+ articleId={state.product?.id_article}
1315
+ version={state.product.version}
1316
+ isShowbox={false}
1317
+ dinamicHeight={true}
1318
+ setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1319
+ updateApprovedInputs={handleOnUpdateApprovedInputs} // No se usa?
1320
+ />
1321
+ ) : (
1322
+ <ScreenHeader
1323
+ text={"No cuentas con este servicio"}
1324
+ headerType={"input-name-header"}
1325
+ />
1326
+ ))}
1327
+
1328
+ {state.active_tab === "Ficha técnica" &&
1329
+ (state.product?.datasheet_status !== "NS" ? (
1330
+ <>
1331
+ {state.datasheets_inputs[0]?.data?.map(
1332
+ (dataGroup, index) => (
1333
+ <InputGroup
1334
+ index={index}
1335
+ key={index + "-" + state.active_retailer.retailer}
1336
+ articleId={state.product.id_article}
1337
+ version={state.version}
1338
+ activeSection={state.active_tab}
1339
+ inputGroup={dataGroup}
1340
+ dataInputs={state.datasheets_inputs[1]}
1341
+ activeRetailer={
1342
+ state.services.datasheets[
1343
+ state.active_retailer.id_retailer
1344
+ ]
1345
+ }
1346
+ groupData={
1347
+ state.services.datasheets[
1348
+ state.active_retailer.id_retailer
1349
+ ].data
1350
+ }
1351
+ updatedDatasheets={
1352
+ state.updated_datasheets_inputs
1353
+ }
1354
+ setUpdatedDatasheets={
1355
+ handleOnSetUpdatedDatasheets
1356
+ }
1357
+ isShowbox={true}
1358
+ setUpdatedBoxData={(e) => {
1359
+ setBoxData(e);
1360
+ }}
1361
+ updateApprovedInputs={
1362
+ handleOnUpdateApprovedInputs // No se usa?
1363
+ }
1364
+ />
1365
+ )
1366
+ )}
1367
+ </>
1368
+ ) : (
1369
+ <ScreenHeader
1370
+ text={"No cuentas con este servicio"}
1371
+ headerType={"input-name-header"}
1372
+ />
1373
+ ))}
1374
+
1375
+ {state.active_tab === "Imágenes" &&
1376
+ (state.product?.images_status !== "NS" ? (
1377
+ <>
1378
+ {!imageLayout && (
1379
+ <GalleryHeader
1380
+ checkAll={state.all_image_checked} // Determina si el checkbox "Seleccionar todo" está marcado
1381
+ setCheckAll={handleOnSetCheckAll} // Toggler de true o false para el checkbox "Seleccionar todo"
1382
+ setSelectedImages={handleOnSetSelectedImages}
1333
1383
  />
1334
- ),
1335
- )}
1336
- </>
1337
- ) : (
1338
- <ScreenHeader
1339
- text={"No cuentas con este servicio"}
1340
- headerType={"input-name-header"}
1341
- />
1342
- ))}
1343
-
1344
- {state.active_tab === "Imágenes" &&
1345
- (state.product?.images_status !== "NS" ? (
1346
- <>
1347
- {!imageLayout && (
1348
- <GalleryHeader
1349
- checkAll={state.all_image_checked} // Determina si el checkbox "Seleccionar todo" está marcado
1350
- setCheckAll={handleOnSetCheckAll} // Toggler de true o false para el checkbox "Seleccionar todo"
1351
- setSelectedImages={handleOnSetSelectedImages}
1352
- />
1353
- )}
1354
- <section
1355
- className="container"
1356
- style={{ position: "relative" }}
1357
- >
1358
- <div
1359
- {...getRootProps({
1360
- className: `dropzone ${
1361
- isDragActive ? "drag-active" : ""
1362
- }`,
1363
- })}
1384
+ )}
1385
+ <section
1386
+ className="container"
1387
+ style={{ position: "relative" }}
1364
1388
  >
1365
- <input {...getInputProps()} />
1366
- {isDragActive && (
1367
- <div className="drag-overlay">
1368
- <p>Suelta las imágenes aquí</p>
1369
- </div>
1370
- )}
1371
- <aside>{thumbs()}</aside>
1372
- </div>
1373
- {state.images_values?.values.length === 0 && (
1374
1389
  <div
1375
- style={{
1376
- position: "absolute",
1377
- top: "50%",
1378
- left: "50%",
1379
- transform: "translate(-50%, -50%)",
1380
- textAlign: "center",
1381
- padding: "40px",
1382
- width: "80%",
1383
- maxWidth: "500px",
1384
- fontFamily: "Arial, sans-serif",
1385
- }}
1390
+ {...getRootProps({
1391
+ className: `dropzone ${
1392
+ isDragActive ? "drag-active" : ""
1393
+ }`,
1394
+ })}
1386
1395
  >
1387
- <p
1388
- style={{
1389
- fontSize: "18px",
1390
- color: "#666",
1391
- marginBottom: "16px",
1392
- }}
1393
- >
1394
- Este producto no tiene imágenes
1395
- </p>
1396
- <p
1396
+ <input {...getInputProps()} />
1397
+ {isDragActive && (
1398
+ <div className="drag-overlay">
1399
+ <p>Suelta las imágenes aquí</p>
1400
+ </div>
1401
+ )}
1402
+ <aside>{thumbs()}</aside>
1403
+ </div>
1404
+ {state.images_values?.values.length === 0 && (
1405
+ <div
1397
1406
  style={{
1398
- fontSize: "14px",
1399
- color: "#999",
1400
- marginBottom: "20px",
1407
+ position: "absolute",
1408
+ top: "50%",
1409
+ left: "50%",
1410
+ transform: "translate(-50%, -50%)",
1411
+ textAlign: "center",
1412
+ padding: "40px",
1413
+ width: "80%",
1414
+ maxWidth: "500px",
1415
+ fontFamily: "Arial, sans-serif",
1401
1416
  }}
1402
1417
  >
1403
- Arrastra las imágenes aquí o{" "}
1404
- <span
1405
- onClick={open}
1418
+ <p
1406
1419
  style={{
1407
- color: "#007bff",
1408
- cursor: "pointer",
1409
- textDecoration: "underline",
1420
+ fontSize: "18px",
1421
+ color: "#666",
1422
+ marginBottom: "16px",
1410
1423
  }}
1411
1424
  >
1412
- haz clic para abrir el explorador de archivos
1413
- </span>
1414
- </p>
1415
- </div>
1416
- )}
1417
- </section>
1418
- </>
1419
- ) : (
1420
- <ScreenHeader
1421
- text={"No cuentas con este servicio"}
1422
- headerType={"input-name-header"}
1423
- />
1424
- ))}
1425
- </>
1426
- )}
1425
+ Este producto no tiene imágenes
1426
+ </p>
1427
+ <p
1428
+ style={{
1429
+ fontSize: "14px",
1430
+ color: "#999",
1431
+ marginBottom: "20px",
1432
+ }}
1433
+ >
1434
+ Arrastra las imágenes aquí o{" "}
1435
+ <span
1436
+ onClick={open}
1437
+ style={{
1438
+ color: "#007bff",
1439
+ cursor: "pointer",
1440
+ textDecoration: "underline",
1441
+ }}
1442
+ >
1443
+ haz clic para abrir el explorador de archivos
1444
+ </span>
1445
+ </p>
1446
+ </div>
1447
+ )}
1448
+ </section>
1449
+ </>
1450
+ ) : (
1451
+ <ScreenHeader
1452
+ text={"No cuentas con este servicio"}
1453
+ headerType={"input-name-header"}
1454
+ />
1455
+ ))}
1456
+ </>
1457
+ )}
1458
+ </div>
1427
1459
  </div>
1428
1460
  </div>
1429
1461
  </div>
1430
- </div>
1431
- </Container>
1462
+ </Container>
1463
+ </AiProductEditionProvider>
1432
1464
  );
1433
1465
  };
1434
1466
 
1435
1467
  export const ProviderProductEdition = (props) => {
1436
1468
  return (
1437
1469
  <ProviderProductEditionProvider>
1438
- <ProviderProductEditionView {...props} />
1470
+ <ProviderProductEditionView {...props} />
1439
1471
  </ProviderProductEditionProvider>
1440
1472
  );
1441
1473
  };