contentoh-components-library 21.5.85 → 21.5.86

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.
@@ -61,6 +61,9 @@ import { Container } from "./styles";
61
61
  import { Commentary } from "../../atoms/Commentary";
62
62
 
63
63
  import { AiProductEditionProvider } from "../../../contexts/AiProductEdition";
64
+ import ChangeStatusModal from "../../organisms/ChangeStatusModal";
65
+
66
+ import { Skeleton, Box, Stack } from "@mui/material";
64
67
 
65
68
  const RetailerProductEditionView = ({
66
69
  tabsSections,
@@ -149,6 +152,8 @@ const RetailerProductEditionView = ({
149
152
  },
150
153
  });
151
154
 
155
+ const [openChangeStatusModal, setOpenChangeStatusModal] = useState(false);
156
+
152
157
  const thumbs = () => {
153
158
  const imageInputs = state.images_values?.inputs?.map((e) => ({
154
159
  value: e?.id,
@@ -195,68 +200,68 @@ const RetailerProductEditionView = ({
195
200
  ));
196
201
  };
197
202
 
198
- // Setter del producto y carga inicial (optimizado para evitar cascada)
199
- useEffect(() => {
200
- const initializeProduct = async () => {
201
- try {
202
- const product = JSON.parse(sessionStorage.getItem("productSelected"))
203
- ? JSON.parse(sessionStorage.getItem("productSelected"))
204
- : productSelected;
203
+ const initializeProduct = async () => {
204
+ try {
205
+ const product = JSON.parse(sessionStorage.getItem("productSelected"))
206
+ ? JSON.parse(sessionStorage.getItem("productSelected"))
207
+ : productSelected;
205
208
 
206
- const productNormalized = normalizeProduct(product);
209
+ const productNormalized = normalizeProduct(product);
207
210
 
208
- dispatch({
209
- type: "SET_PRODUCT",
210
- payload: productNormalized,
211
- });
212
- dispatch({
213
- type: "SET_ACTIVE_RETAILER",
214
- payload: productNormalized.categoryRetailerInOrder[0],
215
- });
216
- setShotThd(
217
- [58, 59, 60, 61].includes(
218
- productNormalized.categoryRetailerInOrder[0].id_retailer,
219
- ),
220
- );
211
+ dispatch({
212
+ type: "SET_PRODUCT",
213
+ payload: productNormalized,
214
+ });
215
+ dispatch({
216
+ type: "SET_ACTIVE_RETAILER",
217
+ payload: productNormalized.categoryRetailerInOrder[0],
218
+ });
219
+ setShotThd(
220
+ [58, 59, 60, 61].includes(
221
+ productNormalized.categoryRetailerInOrder[0].id_retailer,
222
+ ),
223
+ );
221
224
 
222
- // Configurar statusArray según el rol del usuario
223
- setStatusArray(getStatusArrayByRole(user.id_role));
225
+ // Configurar statusArray según el rol del usuario
226
+ setStatusArray(getStatusArrayByRole(user.id_role));
224
227
 
225
- // Cargar usuarios y asignaciones
226
- const users = await fetchUsers(token);
227
- if (users.length > 0) {
228
- dispatch({
229
- type: "SET_COLLABORATOR_ASSIGNATIONS",
230
- payload: buildCollaboratorAssignations(productNormalized, users),
231
- });
232
- }
228
+ // Cargar usuarios y asignaciones
229
+ const users = await fetchUsers(token);
230
+ if (users.length > 0) {
231
+ dispatch({
232
+ type: "SET_COLLABORATOR_ASSIGNATIONS",
233
+ payload: buildCollaboratorAssignations(productNormalized, users),
234
+ });
235
+ }
233
236
 
234
- const { id_article } = productNormalized;
235
- if (id_article) {
236
- await getAuditVersion(id_article, setAuditableVersion, token);
237
- }
237
+ const { id_article } = productNormalized;
238
+ if (id_article) {
239
+ await getAuditVersion(id_article, setAuditableVersion, token);
240
+ }
238
241
 
239
- if (id_article && productNormalized.id_order) {
240
- const response = await axios.get(
241
- process.env.REACT_APP_READ_OBSERVATION,
242
- {
243
- params: {
244
- articleId: id_article,
245
- orderId: productNormalized.id_order,
246
- },
247
- headers: {
248
- Authorization: sessionStorage.getItem("jwt"),
249
- },
242
+ if (id_article && productNormalized.id_order) {
243
+ const response = await axios.get(
244
+ process.env.REACT_APP_READ_OBSERVATION,
245
+ {
246
+ params: {
247
+ articleId: id_article,
248
+ orderId: productNormalized.id_order,
250
249
  },
251
- );
252
- const parseData = JSON.parse(response.data.body).data[0];
253
- setObservation(parseData.observations);
254
- }
255
- } catch (error) {
256
- console.log("Error setting product data: ", error);
250
+ headers: {
251
+ Authorization: sessionStorage.getItem("jwt"),
252
+ },
253
+ },
254
+ );
255
+ const parseData = JSON.parse(response.data.body).data[0];
256
+ setObservation(parseData.observations);
257
257
  }
258
- };
258
+ } catch (error) {
259
+ console.log("Error setting product data: ", error);
260
+ }
261
+ };
259
262
 
263
+ // Setter del producto y carga inicial (optimizado para evitar cascada)
264
+ useEffect(() => {
260
265
  initializeProduct();
261
266
  }, []);
262
267
 
@@ -284,10 +289,9 @@ const RetailerProductEditionView = ({
284
289
  }
285
290
  }, [auditableVersion]);
286
291
 
287
- const loadData = async (enableLoading = true) => {
292
+ const loadData = async (enableLoading = true, versionSelected = null) => {
288
293
  try {
289
-
290
- if(enableLoading) dispatch({ type: "SET_LOADING", payload: true });
294
+ if (enableLoading) dispatch({ type: "SET_LOADING", payload: true });
291
295
 
292
296
  const { id_article, version, id_order } = state.product;
293
297
  const { category, id_category, id_retailer } = state.active_retailer;
@@ -296,7 +300,7 @@ const RetailerProductEditionView = ({
296
300
  const data = [
297
301
  {
298
302
  id_article,
299
- version,
303
+ version: versionSelected ? versionSelected : version,
300
304
  relations: [
301
305
  {
302
306
  id_retailer,
@@ -314,7 +318,7 @@ const RetailerProductEditionView = ({
314
318
  id_article,
315
319
  category,
316
320
  id_category,
317
- version,
321
+ versionSelected ?? version,
318
322
  token,
319
323
  id_retailer,
320
324
  ),
@@ -332,7 +336,7 @@ const RetailerProductEditionView = ({
332
336
  articleId: id_article,
333
337
  concept: "description",
334
338
  orderIdColab: id_order,
335
- version: version,
339
+ version: versionSelected ?? version,
336
340
  },
337
341
  }),
338
342
  axios.get(process.env.REACT_APP_COMMENTS_ENDPOINT, {
@@ -340,7 +344,7 @@ const RetailerProductEditionView = ({
340
344
  articleId: id_article,
341
345
  concept: "datasheet",
342
346
  orderIdColab: id_order,
343
- version: version,
347
+ version: versionSelected ?? version,
344
348
  },
345
349
  }),
346
350
  axios.get(process.env.REACT_APP_COMMENTS_ENDPOINT, {
@@ -348,12 +352,22 @@ const RetailerProductEditionView = ({
348
352
  articleId: id_article,
349
353
  concept: "images",
350
354
  orderIdColab: id_order,
351
- version: version,
355
+ version: versionSelected ?? version,
352
356
  },
353
357
  }),
354
358
  ]),
355
359
  ]);
356
360
 
361
+ dispatch({
362
+ type: "SET_RETAILER_STATUS",
363
+ payload: servicesDataRes.map((service) => ({
364
+ retailer_id: service?.id_retailer,
365
+ service: service?.service,
366
+ status: service?.status,
367
+ task_user_group_id: service?.task_user_group_id,
368
+ })),
369
+ });
370
+
357
371
  // Extraer relaciones del response
358
372
  const percentages =
359
373
  JSON.parse(percentagesRes?.[0]?.body)?.[0]?.relations ?? [];
@@ -599,8 +613,6 @@ const RetailerProductEditionView = ({
599
613
  const handleOnClickSave = async () => {
600
614
  if (state.saving) return;
601
615
 
602
-
603
-
604
616
  switch (state.active_tab) {
605
617
  case "Descripción":
606
618
  await saveDescriptions(token);
@@ -1121,12 +1133,139 @@ const RetailerProductEditionView = ({
1121
1133
  type: "SET_PRODUCT_VERSION",
1122
1134
  payload: version,
1123
1135
  });
1136
+
1137
+ loadData(true, version);
1138
+ };
1139
+
1140
+ const ProductEditionSkeleton = () => {
1141
+ return (
1142
+ <Container headerTop={0}>
1143
+ <Box
1144
+ px={1.5}
1145
+ py={1}
1146
+ pb={0}
1147
+ display="flex"
1148
+ alignItems="center"
1149
+ justifyContent="space-between"
1150
+ >
1151
+ <Skeleton variant="text" width={300} height={40} />
1152
+ <Stack direction="row" spacing={2}>
1153
+ <Skeleton variant="circular" width={32} height={32} />
1154
+ </Stack>
1155
+ </Box>
1156
+
1157
+ <div
1158
+ className="data-container"
1159
+ style={{ display: "flex", gap: "8px", padding: "0 12px 12px" }}
1160
+ >
1161
+ <div
1162
+ className="image-data-panel"
1163
+ style={{
1164
+ flex: "0 0 320px",
1165
+ display: "flex",
1166
+ flexDirection: "column",
1167
+ gap: "20px",
1168
+ }}
1169
+ >
1170
+ <Skeleton variant="rounded" width="100%" height={400} />
1171
+
1172
+ <Stack direction="row" spacing={2} justifyContent="center">
1173
+ {[1, 2, 3, 4].map((item) => (
1174
+ <Skeleton key={item} variant="rounded" width={60} height={80} />
1175
+ ))}
1176
+ </Stack>
1177
+
1178
+ <Box mt={2}>
1179
+ {[1, 2, 3, 4].map((item) => (
1180
+ <Box
1181
+ key={item}
1182
+ display="flex"
1183
+ justifyContent="space-between"
1184
+ py={1}
1185
+ borderBottom="1px solid #f0f0f0"
1186
+ >
1187
+ <Skeleton variant="text" width="40%" />
1188
+ <Skeleton variant="text" width="20%" />
1189
+ </Box>
1190
+ ))}
1191
+ </Box>
1192
+ </div>
1193
+
1194
+ <div
1195
+ className="product-information"
1196
+ style={{
1197
+ flex: 1,
1198
+ display: "flex",
1199
+ flexDirection: "column",
1200
+ gap: "14px",
1201
+ }}
1202
+ >
1203
+ <Box>
1204
+ <Skeleton variant="text" width="80%" height={50} />
1205
+ <Stack direction="row" spacing={2} alignItems="center">
1206
+ <Skeleton variant="rounded" width={180} height={24} />
1207
+ <Skeleton variant="rounded" width={300} height={24} />
1208
+ </Stack>
1209
+ </Box>
1210
+
1211
+ <Box display="flex" gap={4} pb={1}>
1212
+ <Skeleton variant="text" width={140} height={45} />
1213
+ <Skeleton variant="text" width={140} height={45} />
1214
+ <Skeleton variant="text" width={140} height={45} />
1215
+ </Box>
1216
+
1217
+ <Box display="flex" flexDirection="column" gap={4}>
1218
+ {[1, 2, 3].map((item) => (
1219
+ <Box key={item}>
1220
+ <Box
1221
+ display="flex"
1222
+ justifyContent="space-between"
1223
+ alignItems="center"
1224
+ mb={1}
1225
+ >
1226
+ <Skeleton variant="text" width="30%" height={24} />
1227
+ <Skeleton
1228
+ variant="rounded"
1229
+ width={175}
1230
+ height={25}
1231
+ sx={{ borderRadius: "7.5px" }}
1232
+ />
1233
+ </Box>
1234
+ <Skeleton variant="rounded" width="100%" height={70} />
1235
+ <Box display="flex" justifyContent="flex-end" mt={0.5}>
1236
+ <Skeleton variant="text" width={60} />
1237
+ </Box>
1238
+ </Box>
1239
+ ))}
1240
+ </Box>
1241
+
1242
+ <Box mt="auto" pt={4}>
1243
+ <Skeleton variant="rounded" width="100%" height={120} />
1244
+ <Box display="flex" justifyContent="flex-end" gap={2} mt={2}>
1245
+ <Skeleton
1246
+ variant="rounded"
1247
+ width={180}
1248
+ height={45}
1249
+ sx={{ borderRadius: "24px" }}
1250
+ />
1251
+ <Skeleton
1252
+ variant="rounded"
1253
+ width={180}
1254
+ height={45}
1255
+ sx={{ borderRadius: "24px" }}
1256
+ />
1257
+ </Box>
1258
+ </Box>
1259
+ </div>
1260
+ </div>
1261
+ </Container>
1262
+ );
1124
1263
  };
1125
1264
 
1126
1265
  if (state.loading || !state.services || !state.product)
1127
1266
  return (
1128
1267
  <>
1129
- <Loading />
1268
+ <ProductEditionSkeleton />
1130
1269
  </>
1131
1270
  );
1132
1271
 
@@ -1590,27 +1729,46 @@ const RetailerProductEditionView = ({
1590
1729
  />
1591
1730
  </div>
1592
1731
  )}
1593
- {[7, 8].includes(user.id_role) && (
1732
+
1733
+ <div className="action-buttons">
1594
1734
  <Button
1595
- buttonType={
1596
- isEvaluationFinished(
1597
- user.id_role,
1598
- state.active_tab,
1599
- statusArray,
1600
- ) &&
1601
- state.missing_required_fields[state.active_tab] === 0
1602
- ? "general-green-button"
1603
- : "general-button-disabled"
1604
- }
1605
- label={"Enviar evaluación"}
1606
- onClick={handleOnSendEvaluationToFacilitator}
1735
+ buttonType={"general-pink-button"}
1736
+ label={"Cambio de Estatus"}
1737
+ onClick={() => setOpenChangeStatusModal(true)}
1738
+ id="button-change-status"
1607
1739
  />
1608
- )}
1740
+ {[7, 8].includes(user.id_role) && (
1741
+ <Button
1742
+ buttonType={
1743
+ isEvaluationFinished(
1744
+ user.id_role,
1745
+ state.active_tab,
1746
+ statusArray,
1747
+ ) &&
1748
+ state.missing_required_fields[state.active_tab] === 0
1749
+ ? "general-green-button"
1750
+ : "general-button-disabled"
1751
+ }
1752
+ label={"Enviar evaluación"}
1753
+ onClick={handleOnSendEvaluationToFacilitator}
1754
+ />
1755
+ )}
1756
+ </div>
1609
1757
  </div>
1610
1758
  )}
1611
1759
  </div>
1612
1760
  </div>
1613
1761
  </Container>
1762
+
1763
+ <ChangeStatusModal
1764
+ state={state}
1765
+ open={openChangeStatusModal}
1766
+ onClose={() => {
1767
+ setOpenChangeStatusModal(false);
1768
+ }}
1769
+ reloadData={loadData}
1770
+ token={token}
1771
+ />
1614
1772
  </AiProductEditionProvider>
1615
1773
  );
1616
1774
  };
@@ -48,6 +48,12 @@ export const Container = styled.div`
48
48
  padding: 10px;
49
49
  padding-left: 0;
50
50
 
51
+ .action-buttons{
52
+ display: flex;
53
+ flex-direction: column;
54
+ gap: 1rem;
55
+ }
56
+
51
57
  .commentary {
52
58
  display: flex;
53
59
  align-items: flex-end;
@@ -204,6 +204,7 @@ export const AiProductEditionProvider = ({
204
204
  } = currentCategory;
205
205
 
206
206
  //Checamos si el servicio de ficha técnica e imagenes esta completo
207
+
207
208
  const currentRetailerPercentages = productSelected?.percentages?.find(retailer => retailer?.id_retailer === activeRetailer?.id_retailer);
208
209
 
209
210
  if(!currentRetailerPercentages) return console.log("Error: No hay porcentajes disponibles");
@@ -0,0 +1,103 @@
1
+ const STATUS_DICTIONARY = {
2
+ // R: {
3
+ // status: "R",
4
+ // name: "Recepción",
5
+ // weight: 1
6
+ // },
7
+ PA: {
8
+ status: "PA",
9
+ name: "Por Asignar",
10
+ weight: 2
11
+ },
12
+ AS: {
13
+ status: "AS",
14
+ name: "Asignado",
15
+ weight: 3
16
+ },
17
+ CA: {
18
+ status: "CA",
19
+ name: "Capturando",
20
+ weight: 4
21
+ },
22
+ // IE: {
23
+ // status: "IE",
24
+ // name: "Información Enviada",
25
+ // weight: 5
26
+ // },
27
+ RCA: {
28
+ status: "RCA",
29
+ name: "Rechazado Cadena",
30
+ weight: 6
31
+ },
32
+ RP: {
33
+ status: "RP",
34
+ name: "Rechazado Proveedor",
35
+ weight: 7
36
+ },
37
+ RA: {
38
+ status: "RA",
39
+ name: "Rechazado Auditor",
40
+ weight: 8
41
+ },
42
+ RC: {
43
+ status: "RC",
44
+ name: "Rechazo Coordinador",
45
+ weight: 9
46
+ },
47
+ AC: {
48
+ status: "AC",
49
+ name: "Aprobado Coordinador",
50
+ weight: 10
51
+ },
52
+ AA: {
53
+ status: "AA",
54
+ name: "Aprobado Auditor",
55
+ weight: 11
56
+ },
57
+ AP: {
58
+ status: "AP",
59
+ name: "Aprobado Proveedor",
60
+ weight: 12
61
+ },
62
+ ACA: {
63
+ status: "ACA",
64
+ name: "Aprobado Cadena",
65
+ weight: 13
66
+ },
67
+ Ex: {
68
+ status: "Ex",
69
+ name: "Exportado",
70
+ weight: 14
71
+ },
72
+ // RAC: {
73
+ // status: "RAC",
74
+ // name: "Rechazo de Auditoría Content-oh!",
75
+ // weight: 15
76
+ // },
77
+ // SAC: {
78
+ // status: "SAC",
79
+ // name: "Solicitud de Auditoría Content-oh!",
80
+ // weight: 16
81
+ // },
82
+ // AAC: {
83
+ // status: "AAC",
84
+ // name: "Aprobado Auditoría Content-oh!",
85
+ // weight: 17
86
+ // },
87
+ // FAP: {
88
+ // status: "FAP",
89
+ // name: "Finalización de Auditoría por Proveedor",
90
+ // weight: 18
91
+ // },
92
+
93
+ //El status NS necesita ser el mayor de todos
94
+ NS: {
95
+ status: "NS",
96
+ name: "No Solicitado",
97
+ weight: 100
98
+ },
99
+ };
100
+
101
+ module.exports = {
102
+ STATUS_DICTIONARY
103
+ }