contentoh-components-library 21.5.94 → 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 +413 -396
  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 +496 -475
  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,48 +143,19 @@ 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",
155
153
  payload: productNormalized,
156
154
  });
157
-
158
- if (
159
- productNormalized.categoryRetailerInOrder.length > 0 &&
160
- productNormalized.statusByRetailer
161
- ) {
162
- dispatch({
163
- type: "SET_ACTIVE_RETAILER",
164
- payload: productNormalized.categoryRetailerInOrder[0],
165
- });
166
- const firstRetailerStatus =
167
- productNormalized.statusByRetailer[
168
- productNormalized.categoryRetailerInOrder[0].id_retailer
169
- ];
170
- const initialTab = firstRetailerStatus.description
171
- ? "Descripción"
172
- : firstRetailerStatus.datasheet
173
- ? "Ficha técnica"
174
- : firstRetailerStatus.images
175
- ? "Imágenes"
176
- : "Imágenes";
177
- dispatch({
178
- type: "SET_ACTIVE_TAB",
179
- payload: initialTab,
180
- });
181
- } else {
182
- dispatch({
183
- type: "SET_ACTIVE_RETAILER",
184
- payload: productNormalized.categoryRetailer[0],
185
- });
186
- }
155
+ dispatch({
156
+ type: "SET_ACTIVE_RETAILER",
157
+ payload: productNormalized.categoryRetailer[0],
158
+ });
187
159
  } catch (error) {
188
160
  console.log("Error setting product data: ", error);
189
161
  }
@@ -227,7 +199,7 @@ const ProviderProductEditionView = ({
227
199
  id_category,
228
200
  version,
229
201
  token,
230
- id_retailer,
202
+ id_retailer
231
203
  ),
232
204
  getPercentage({ data, headers }),
233
205
  getServicesData({
@@ -241,20 +213,39 @@ const ProviderProductEditionView = ({
241
213
  const percentages =
242
214
  JSON.parse(percentageRes?.[0]?.body)?.[0]?.relations ?? [];
243
215
 
244
- const orderMap =
245
- services[2].inputsByRetailer ??
246
- [].flat().reduce((acc, item) => {
216
+ const orderMap = services[2].inputsByRetailer
217
+ .flat()
218
+ .reduce((acc, item) => {
247
219
  acc[item.id_image] = item.order;
248
220
  return acc;
249
221
  }, {});
250
222
 
251
- const orderedValues = [...(services[2].values ?? [])].sort((a, b) => {
223
+ const orderedValues = [...services[2].values].sort((a, b) => {
252
224
  const orderA = orderMap[a.image_id] ?? Number.MAX_SAFE_INTEGER;
253
225
  const orderB = orderMap[b.image_id] ?? Number.MAX_SAFE_INTEGER;
254
226
 
255
227
  return orderA - orderB;
256
228
  });
257
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
+
258
249
  dispatch({
259
250
  type: "SET_SERVICES",
260
251
  payload: {
@@ -274,7 +265,7 @@ const ProviderProductEditionView = ({
274
265
  dispatch({
275
266
  type: "SET_ACTIVE_PERCENTAGES",
276
267
  payload: percentages.find(
277
- ({ id_retailer: rId }) => rId === id_retailer,
268
+ ({ id_retailer: rId }) => rId === id_retailer
278
269
  ),
279
270
  });
280
271
  } catch (error) {
@@ -286,7 +277,16 @@ const ProviderProductEditionView = ({
286
277
  };
287
278
 
288
279
  fetchData();
289
- }, [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
+ ]);
290
290
 
291
291
  // Actualizador de campos del ui para que coincidan con el retailer activo
292
292
  useEffect(() => {
@@ -294,51 +294,46 @@ const ProviderProductEditionView = ({
294
294
  console.log("Actualizar inputs del retailer activo");
295
295
  const updateInputsActiveRetailer = () => {
296
296
  if (!state.services) return;
297
- if (state.services.datasheets) {
298
- const retailerDatasheets =
299
- state.services.datasheets[state.active_retailer.id_retailer];
300
297
 
301
- const datasheetsActiveRetailer = {
302
- ...retailerDatasheets,
303
- data: Object.values(retailerDatasheets.data),
304
- };
298
+ const retailerDatasheets =
299
+ state.services.datasheets[state.active_retailer.id_retailer];
305
300
 
306
- dispatch({
307
- type: "SET_DATASHEETS_INPUTS",
308
- payload: [datasheetsActiveRetailer, state.services.datasheets.inputs],
309
- });
310
- }
301
+ const datasheetsActiveRetailer = {
302
+ ...retailerDatasheets,
303
+ data: Object.values(retailerDatasheets.data),
304
+ };
311
305
 
312
- if (state.services.descriptions) {
313
- const descriptionsActiveRetailer = state.services.descriptions.filter(
314
- (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
+ )
315
317
  );
318
+ });
316
319
 
317
- dispatch({
318
- type: "SET_DESCRIPTIONS_INPUTS",
319
- payload: descriptionsActiveRetailer,
320
- });
321
- }
320
+ dispatch({
321
+ type: "SET_DATASHEETS_INPUTS",
322
+ payload: [datasheetsActiveRetailer, state.services.datasheets.inputs],
323
+ });
322
324
 
323
- if (state.services.images) {
324
- const filteredValues = state.services.images.values.filter((value) => {
325
- return state.services.images.inputsByRetailer.some((retailerInput) =>
326
- retailerInput.some(
327
- (input) =>
328
- input.id_retailer === state.active_retailer.id_retailer &&
329
- input.id_image === value.image_id,
330
- ),
331
- );
332
- });
325
+ dispatch({
326
+ type: "SET_DESCRIPTIONS_INPUTS",
327
+ payload: descriptionsActiveRetailer,
328
+ });
333
329
 
334
- dispatch({
335
- type: "SET_IMAGES_VALUES",
336
- payload: {
337
- ...state.services.images,
338
- values: filteredValues,
339
- },
340
- });
341
- }
330
+ dispatch({
331
+ type: "SET_IMAGES_VALUES",
332
+ payload: {
333
+ ...state.services.images,
334
+ values: filteredValues,
335
+ },
336
+ });
342
337
  };
343
338
 
344
339
  updateInputsActiveRetailer();
@@ -349,7 +344,14 @@ const ProviderProductEditionView = ({
349
344
  if (!state.product?.statusByRetailer) return false;
350
345
 
351
346
  const currentService = getConceptByTab(state.active_tab);
352
- 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
+
353
355
  const originTab = origin[state.active_tab];
354
356
  const isRetailerUser = user?.is_retailer === 1;
355
357
 
@@ -372,13 +374,17 @@ const ProviderProductEditionView = ({
372
374
  // No retailer
373
375
  const hasNoOrder = !state.product.id_order && !state.product.orderId;
374
376
 
375
- return (
376
- (originTab === "RequestWithoutContentoh" &&
377
- (["R", "CA"].includes(currentStatus) ||
378
- (currentStatus === "RCA" && hasNoOrder))) ||
379
- (["RequestWithContentoh", "Contentoh"].includes(originTab) &&
380
- currentStatus === "AA")
381
- );
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;
382
388
  };
383
389
 
384
390
  const canShowSaveButton = (version_status) => {
@@ -399,6 +405,7 @@ const ProviderProductEditionView = ({
399
405
 
400
406
  const currentService = getConceptByTab(state.active_tab);
401
407
  const currentRetailer = state.active_retailer.id_retailer;
408
+
402
409
  const currentStatus =
403
410
  statusByRetailer[currentRetailer][currentService] || "ERR";
404
411
  return currentStatus;
@@ -410,7 +417,7 @@ const ProviderProductEditionView = ({
410
417
  name: e?.name,
411
418
  required: e?.required,
412
419
  active: state.images_values?.values?.some(
413
- (value) => value?.image_id === e?.id,
420
+ (value) => value?.image_id === e?.id
414
421
  ),
415
422
  }));
416
423
  const imageType = state.images_values?.imageType?.map((e) => ({
@@ -421,7 +428,7 @@ const ProviderProductEditionView = ({
421
428
  (e) => ({
422
429
  value: e?.id,
423
430
  name: e?.name,
424
- }),
431
+ })
425
432
  );
426
433
 
427
434
  return state.images_values?.values?.map((image, index) => (
@@ -662,6 +669,7 @@ const ProviderProductEditionView = ({
662
669
  state.product[sectionStatusKey] || state.product?.version_status;
663
670
 
664
671
  let data = { articleId, orderId, concept, evalStatus };
672
+
665
673
  const retailerId = state.active_retailer?.id_retailer;
666
674
 
667
675
  try {
@@ -676,13 +684,15 @@ const ProviderProductEditionView = ({
676
684
  headers: {
677
685
  Authorization: token,
678
686
  },
679
- },
687
+ }
680
688
  );
681
689
 
682
690
  const newStatuses = JSON.parse(res.data.body);
683
691
  const serviceStatus =
684
692
  newStatuses.newServiceStatus[articleId][`${concept}Status`];
685
693
 
694
+ console.log({product: state.product, newStatuses, serviceStatus, servicesData: state.services_data});
695
+
686
696
  // Actualizar el producto con los nuevos estados
687
697
  const updatedProduct = {
688
698
  ...state.product,
@@ -690,12 +700,19 @@ const ProviderProductEditionView = ({
690
700
  ...state.product.statusByRetailer,
691
701
  [retailerId]: {
692
702
  ...state.product.statusByRetailer[retailerId],
693
- [concept]: serviceStatus,
703
+ [concept]: newStatuses?.newStatus ?? serviceStatus,
694
704
  },
695
705
  },
696
706
  };
697
707
 
698
- 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 });
699
716
 
700
717
  dispatch({ type: "SET_PRODUCT", payload: updatedProduct });
701
718
 
@@ -924,7 +941,7 @@ const ProviderProductEditionView = ({
924
941
  headers: {
925
942
  Authorization: token,
926
943
  },
927
- }),
944
+ })
928
945
  );
929
946
  });
930
947
 
@@ -969,7 +986,7 @@ const ProviderProductEditionView = ({
969
986
  ArticleId: updatedProduct.id_article,
970
987
  idCategory: updatedProduct.id_category,
971
988
  product: updatedProduct,
972
- }),
989
+ })
973
990
  );
974
991
 
975
992
  // Mostrar modal de éxito
@@ -1035,418 +1052,422 @@ const ProviderProductEditionView = ({
1035
1052
  if (state.loading || !state.services || !state.product) return <Loading />;
1036
1053
 
1037
1054
  return (
1038
- <Container headerTop={headerTop}>
1039
- {/* <button onClick={() => console.log(state)}>log</button> */}
1040
- {showVersionSelector && (
1041
- <VersionSelector
1042
- modalId={"version-selector"}
1043
- articleId={state.product.id_article}
1044
- setVersion={handleOnChangeProductVersion}
1045
- companyName={company.company_name}
1046
- currentVersion={state.product.version}
1047
- setShowVersionSelector={setShowVersionSelector}
1048
- jwt={token}
1049
- />
1050
- )}
1051
- {showModal && (
1052
- <ProductImageModal
1053
- images={state.images_values}
1054
- setShowModal={setShowModal}
1055
- approveRejectButtons={canShowValidationButtons()}
1056
- sendToFacilitator={handleOnSendEvaluation}
1057
- />
1058
- )}
1059
- {state.modal.show && (
1060
- <GenericModal
1061
- componentsArray={[
1062
- state.modal.image && (
1063
- <img key="1" src={state.modal.image} alt="modal icon" />
1064
- ),
1065
- state.modal.title && (
1066
- <ScreenHeader
1067
- key="2"
1068
- headerType={"retailer-name-header"}
1069
- text={state.modal.title}
1070
- color={"white"}
1071
- />
1072
- ),
1073
- state.modal.message && (
1074
- <ScreenHeader
1075
- key="3"
1076
- headerType={"retailer-name-header"}
1077
- 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}
1078
1135
  color={"white"}
1079
1136
  />
1080
- ),
1081
- state.modal.buttons && (
1082
- <div key="4" style={{ marginTop: "16px" }}>
1083
- {state.modal.buttons.map((button, index) => (
1084
- <Button
1085
- key={index}
1086
- buttonType={button.buttonType}
1087
- label={button.text}
1088
- onClick={button.action}
1089
- />
1090
- ))}
1091
- </div>
1092
- ),
1093
- ].filter(Boolean)}
1094
- onClick={() =>
1095
- dispatch({
1096
- type: "SET_MODAL",
1097
- payload: { show: false, title: "", message: "", image: null },
1098
- })
1099
- }
1100
- />
1101
- )}
1102
- {showRejectModal && (
1103
- <Modal
1104
- title={
1105
- rejectAll
1106
- ? "Agregar mensaje para rechazar todo"
1107
- : "Agregar mensaje de rechazo"
1108
- }
1109
- show={showRejectModal}
1110
- customComponent={
1111
- <TagAndInput
1112
- inputType={"textarea"}
1113
- inputId={"modal-message-box"}
1114
- index={0}
1115
- color={"white"}
1116
- />
1117
- }
1118
- buttons={[
1119
- <ButtonV2
1120
- key={"btn-Cancelar"}
1121
- type={"white"}
1122
- label={"Cancelar"}
1123
- size={12}
1124
- onClick={() => {
1125
- setShowRejectModal(false);
1126
- }}
1127
- />,
1128
- <ButtonV2
1129
- key={"btn-Aceptar"}
1130
- type={"pink"}
1131
- label={"Aceptar"}
1132
- size={12}
1133
- onClick={async () => {
1134
- const elements = document.querySelectorAll(
1135
- "#modal-message-box .ql-container .ql-editor > p",
1136
- );
1137
-
1138
- if (!elements || elements.length === 0) {
1139
- console.error("Elemento no encontrado");
1140
- return;
1141
- }
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
+ );
1142
1157
 
1143
- const isMessageEmpty = Array.from(elements).every((el) => {
1144
- const body = el.innerHTML;
1145
- return !body || body.replace(/<.*?\/?>/gm, "").trim() === "";
1146
- });
1158
+ if (!elements || elements.length === 0) {
1159
+ console.error("Elemento no encontrado");
1160
+ return;
1161
+ }
1147
1162
 
1148
- if (isMessageEmpty) {
1149
- const container = document.querySelector(
1150
- ".container-customComponent",
1151
- );
1152
- const existingAlert = container.querySelector(".alert-error");
1153
-
1154
- if (!existingAlert) {
1155
- const alert = document.createElement("div");
1156
- alert.className = "alert-error";
1157
- alert.style.cssText = `
1158
- color: #d32f2f;
1159
- background-color: #ffebee;
1160
- border: 1px solid #ef5350;
1161
- border-radius: 4px;
1162
- padding: 12px 16px;
1163
- margin-top: 10px;
1164
- font-size: 14px;
1165
- display: flex;
1166
- align-items: center;
1167
- gap: 8px;
1168
- font-family: 'Roboto', sans-serif;
1169
- text-align: center;
1170
- `;
1171
- alert.innerHTML = `<span>El mensaje no puede estar vacío.</span>`;
1172
- 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;
1173
1195
  }
1174
- return;
1175
- }
1176
1196
 
1177
- const fullMessage = Array.from(elements)
1178
- .map((element) => element.innerHTML)
1179
- .join("")
1180
- .replace(/<br\s*\/?>/gi, "\n");
1197
+ const fullMessage = Array.from(elements)
1198
+ .map((element) => element.innerHTML)
1199
+ .join("")
1200
+ .replace(/<br\s*\/?>/gi, "\n");
1181
1201
 
1182
- await createComment(fullMessage);
1202
+ await createComment(fullMessage, token);
1183
1203
 
1184
- rejectAll
1185
- ? handleOnEvaluateAll("R")
1186
- : handleOnSendEvaluation("R");
1187
- setShowRejectModal(false);
1188
- }}
1189
- />,
1190
- ]}
1191
- />
1192
- )}
1193
- <HeaderTop
1194
- setHeaderTop={setHeaderTop}
1195
- withChat={location?.state?.withChat}
1196
- chatType={location?.state?.chatType}
1197
- productSelected={state.product}
1198
- token={token}
1199
- activeRetailer={{
1200
- id: state.active_retailer?.id_retailer,
1201
- name: state.active_retailer?.retailer,
1202
- }}
1203
- />
1204
- <div className="data-container">
1205
- <div className="image-data-panel">
1206
- <ImagePreviewer
1207
- activeImage={state.images_values.values[state.current_image] ?? {}}
1208
- imagesArray={state.images_values || []}
1209
- setActiveImage={handleOnChangeCurrentImage}
1210
- setShowModal={handleOnShowModalGalery}
1211
- />
1212
- <ImageDataTable
1213
- lists={state.images_values || []}
1214
- activeImage={
1215
- state.images_values?.values
1216
- ? state.images_values?.values[state.current_image]
1217
- : {}
1218
- }
1219
- assignationsImages={assig}
1220
- retailerSelected={state.active_retailer?.id_retailer}
1221
- imagesStatus={state.product?.images_status || "-"}
1222
- isRetailer={isRetailer}
1223
- setShowVersionSelector={setShowVersionSelector}
1224
- version={state.product.version}
1225
- setImages={handleOnChangeCurrentImage}
1226
- onClickSave={handleOnClickSaveImages}
1227
- setAssignation={handleOnChangeAssignations} // No se usa?
1204
+ rejectAll
1205
+ ? handleOnEvaluateAll("R")
1206
+ : handleOnSendEvaluation("R");
1207
+ setShowRejectModal(false);
1208
+ }}
1209
+ />,
1210
+ ]}
1228
1211
  />
1229
- </div>
1230
- <div className="product-information">
1231
- <div className="product-information">
1232
- <FullProductNameHeader
1233
- headerData={state.product}
1234
- percent={state.active_percentage.percentagesGeneral.required}
1235
- activeRetailer={{
1236
- id: state.active_retailer?.id_retailer,
1237
- name: state.active_retailer?.retailer,
1238
- image: state.active_retailer?.image,
1239
- }}
1240
- showValidationButtons={canShowValidationButtons()}
1241
- showApproveRejectAll={canShowValidationButtons()}
1242
- servicesData={state.services_data ? state.services_data : null}
1243
- approveAll={handleOnApproveAll}
1244
- rejectAll={handleOnRejectAll}
1245
- approve={() => handleOnSendEvaluation("A")}
1246
- reject={handleOnReject}
1247
- 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}
1248
1231
  />
1249
- <FullTabsMenu
1250
- tabsSections={tabsSections}
1251
- status={getStatusByCurrentServiceAndRetailer()}
1252
- activeTab={state.active_tab}
1253
- 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 || "-"}
1254
1242
  isRetailer={isRetailer}
1255
- assig={assig}
1256
- version={state.product.version}
1257
- updatedDescriptions={state.updated_descriptions_inputs}
1258
- updatedDatasheets={state.updated_datasheets_inputs}
1259
- updatedImages={state.updated_images_values}
1260
- images={state.services.images}
1261
- // actions
1262
- downloadImages={handleOnDownloadImages}
1263
- askToDeleteImages={handleOnAskToDeleteImages}
1264
- showSaveButton={canShowSaveButton(state.product.version_status)}
1265
- onClickSave={handleOnClickSave}
1266
- // setters
1267
- setActiveTab={handleOnChangeActiveTab}
1268
- setImageLayout={handleOnSetImageLayout}
1269
- setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1270
- setUpdatedDatasheets={handleOnSetUpdatedDatasheets}
1271
- setAssignation={handleOnSetAssignation} // No se usa?
1272
- setImages={handleOnSetImages} // No se usa?
1273
- // setSelectedImages={handleOnSetSelectedImages} // Se pasa hasta TabsMenu, pero no se usa
1274
1243
  setShowVersionSelector={setShowVersionSelector}
1244
+ version={state.product.version}
1245
+ setImages={handleOnChangeCurrentImage}
1246
+ onClickSave={handleOnClickSaveImages}
1247
+ setAssignation={handleOnChangeAssignations} // No se usa?
1275
1248
  />
1276
- <div
1277
- className={
1278
- "services-information-container " +
1279
- (imageLayout && state.active_tab === "Imágenes"
1280
- ? "image-services"
1281
- : "")
1282
- }
1283
- >
1284
- {state.saving ? (
1285
- <Loading />
1286
- ) : (
1287
- <>
1288
- {state.active_tab === "Descripción" &&
1289
- (state.product?.description_status !== "NS" ? (
1290
- <InputGroup
1291
- activeSection={state.active_tab}
1292
- inputGroup={state.descriptions_inputs[0]}
1293
- updatedDescriptions={state.updated_descriptions_inputs}
1294
- articleId={state.product?.id_article}
1295
- version={state.product.version}
1296
- isShowbox={false}
1297
- dinamicHeight={true}
1298
- setUpdatedDescriptions={handleOnSetUpdatedDescriptions}
1299
- updateApprovedInputs={handleOnUpdateApprovedInputs} // No se usa?
1300
- />
1301
- ) : (
1302
- <ScreenHeader
1303
- text={"No cuentas con este servicio"}
1304
- headerType={"input-name-header"}
1305
- />
1306
- ))}
1307
-
1308
- {state.active_tab === "Ficha técnica" &&
1309
- (state.product?.datasheet_status !== "NS" ? (
1310
- <>
1311
- {state.datasheets_inputs[0].data?.map(
1312
- (dataGroup, index) => (
1313
- <InputGroup
1314
- index={index}
1315
- key={index + "-" + state.active_retailer.retailer}
1316
- articleId={state.product.id_article}
1317
- version={state.version}
1318
- activeSection={state.active_tab}
1319
- inputGroup={dataGroup}
1320
- dataInputs={state.datasheets_inputs[1] ?? []}
1321
- activeRetailer={
1322
- state.services.datasheets[
1323
- state.active_retailer.id_retailer
1324
- ]
1325
- }
1326
- groupData={
1327
- state.services.datasheets[
1328
- state.active_retailer.id_retailer
1329
- ].data
1330
- }
1331
- updatedDatasheets={
1332
- state.updated_datasheets_inputs
1333
- }
1334
- setUpdatedDatasheets={
1335
- handleOnSetUpdatedDatasheets
1336
- }
1337
- isShowbox={true}
1338
- setUpdatedBoxData={(e) => {
1339
- setBoxData(e);
1340
- }}
1341
- updateApprovedInputs={
1342
- handleOnUpdateApprovedInputs // No se usa?
1343
- }
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}
1344
1383
  />
1345
- ),
1346
- )}
1347
- </>
1348
- ) : (
1349
- <ScreenHeader
1350
- text={"No cuentas con este servicio"}
1351
- headerType={"input-name-header"}
1352
- />
1353
- ))}
1354
-
1355
- {state.active_tab === "Imágenes" &&
1356
- (state.product?.images_status !== "NS" ? (
1357
- <>
1358
- {!imageLayout && (
1359
- <GalleryHeader
1360
- checkAll={state.all_image_checked} // Determina si el checkbox "Seleccionar todo" está marcado
1361
- setCheckAll={handleOnSetCheckAll} // Toggler de true o false para el checkbox "Seleccionar todo"
1362
- setSelectedImages={handleOnSetSelectedImages}
1363
- />
1364
- )}
1365
- <section
1366
- className="container"
1367
- style={{ position: "relative" }}
1368
- >
1369
- <div
1370
- {...getRootProps({
1371
- className: `dropzone ${
1372
- isDragActive ? "drag-active" : ""
1373
- }`,
1374
- })}
1384
+ )}
1385
+ <section
1386
+ className="container"
1387
+ style={{ position: "relative" }}
1375
1388
  >
1376
- <input {...getInputProps()} />
1377
- {isDragActive && (
1378
- <div className="drag-overlay">
1379
- <p>Suelta las imágenes aquí</p>
1380
- </div>
1381
- )}
1382
- <aside>{thumbs()}</aside>
1383
- </div>
1384
- {state.images_values?.values.length === 0 && (
1385
1389
  <div
1386
- style={{
1387
- position: "absolute",
1388
- top: "50%",
1389
- left: "50%",
1390
- transform: "translate(-50%, -50%)",
1391
- textAlign: "center",
1392
- padding: "40px",
1393
- width: "80%",
1394
- maxWidth: "500px",
1395
- fontFamily: "Arial, sans-serif",
1396
- }}
1390
+ {...getRootProps({
1391
+ className: `dropzone ${
1392
+ isDragActive ? "drag-active" : ""
1393
+ }`,
1394
+ })}
1397
1395
  >
1398
- <p
1399
- style={{
1400
- fontSize: "18px",
1401
- color: "#666",
1402
- marginBottom: "16px",
1403
- }}
1404
- >
1405
- Este producto no tiene imágenes
1406
- </p>
1407
- <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
1408
1406
  style={{
1409
- fontSize: "14px",
1410
- color: "#999",
1411
- 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",
1412
1416
  }}
1413
1417
  >
1414
- Arrastra las imágenes aquí o{" "}
1415
- <span
1416
- onClick={open}
1418
+ <p
1417
1419
  style={{
1418
- color: "#007bff",
1419
- cursor: "pointer",
1420
- textDecoration: "underline",
1420
+ fontSize: "18px",
1421
+ color: "#666",
1422
+ marginBottom: "16px",
1421
1423
  }}
1422
1424
  >
1423
- haz clic para abrir el explorador de archivos
1424
- </span>
1425
- </p>
1426
- </div>
1427
- )}
1428
- </section>
1429
- </>
1430
- ) : (
1431
- <ScreenHeader
1432
- text={"No cuentas con este servicio"}
1433
- headerType={"input-name-header"}
1434
- />
1435
- ))}
1436
- </>
1437
- )}
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>
1438
1459
  </div>
1439
1460
  </div>
1440
1461
  </div>
1441
- </div>
1442
- </Container>
1462
+ </Container>
1463
+ </AiProductEditionProvider>
1443
1464
  );
1444
1465
  };
1445
1466
 
1446
1467
  export const ProviderProductEdition = (props) => {
1447
1468
  return (
1448
1469
  <ProviderProductEditionProvider>
1449
- <ProviderProductEditionView {...props} />
1470
+ <ProviderProductEditionView {...props} />
1450
1471
  </ProviderProductEditionProvider>
1451
1472
  );
1452
1473
  };