contentoh-components-library 21.5.85 → 21.5.87

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 (23) hide show
  1. package/dist/components/atoms/GeneralButton/styles.js +1 -1
  2. package/dist/components/molecules/TagAndInput/index.js +55 -14
  3. package/dist/components/molecules/TagAndInput/styles.js +1 -1
  4. package/dist/components/organisms/ChangeStatusModal/index.js +531 -0
  5. package/dist/components/organisms/ChangeStatusModal/styles.js +85 -0
  6. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +108 -231
  7. package/dist/components/pages/RetailerProductEdition/context/reducers/product.js +48 -2
  8. package/dist/components/pages/RetailerProductEdition/index.js +329 -101
  9. package/dist/components/pages/RetailerProductEdition/styles.js +1 -1
  10. package/dist/contexts/AiProductEdition.js +75 -22
  11. package/dist/global-files/statusDictionary.js +103 -0
  12. package/package.json +1 -1
  13. package/src/components/atoms/GeneralButton/styles.js +4 -0
  14. package/src/components/molecules/TagAndInput/index.js +32 -2
  15. package/src/components/molecules/TagAndInput/styles.js +11 -0
  16. package/src/components/organisms/ChangeStatusModal/index.jsx +488 -0
  17. package/src/components/organisms/ChangeStatusModal/styles.js +333 -0
  18. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +107 -259
  19. package/src/components/pages/RetailerProductEdition/context/reducers/product.js +55 -0
  20. package/src/components/pages/RetailerProductEdition/index.js +236 -78
  21. package/src/components/pages/RetailerProductEdition/styles.js +6 -0
  22. package/src/contexts/AiProductEdition.jsx +46 -0
  23. package/src/global-files/statusDictionary.js +103 -0
@@ -96,6 +96,36 @@ var AiProductEditionProvider = function AiProductEditionProvider(_ref) {
96
96
  inputsUsingAi = _useState16[0],
97
97
  setInputsUsingAi = _useState16[1];
98
98
 
99
+ var MAX_CREDITS = 10;
100
+ var COOLDOWN_MS = 5 * 60 * 1000;
101
+ var RATE_LIMIT_KEY = "ai_generation_limit_data";
102
+
103
+ var checkAndManageRateLimit = function checkAndManageRateLimit(currentArticleId) {
104
+ var now = Date.now();
105
+ var storedData = localStorage.getItem(RATE_LIMIT_KEY);
106
+ var allRateData = storedData ? JSON.parse(storedData) : {};
107
+ var productTimestamps = allRateData[currentArticleId] || [];
108
+ productTimestamps = productTimestamps.filter(function (timestamp) {
109
+ return now - timestamp < COOLDOWN_MS;
110
+ });
111
+
112
+ if (productTimestamps.length >= MAX_CREDITS) {
113
+ allRateData[currentArticleId] = productTimestamps;
114
+ localStorage.setItem(RATE_LIMIT_KEY, JSON.stringify(allRateData));
115
+ return {
116
+ allowed: false,
117
+ message: "Has alcanzado el limite de intentos frecuentes para este producto. Por favor, espera unos minutos."
118
+ };
119
+ }
120
+
121
+ productTimestamps.push(now);
122
+ allRateData[currentArticleId] = productTimestamps;
123
+ localStorage.setItem(RATE_LIMIT_KEY, JSON.stringify(allRateData));
124
+ return {
125
+ allowed: true
126
+ };
127
+ };
128
+
99
129
  function setCurrentSuggestionValue(_ref2) {
100
130
  var inputId = _ref2.inputId,
101
131
  index = _ref2.index,
@@ -149,25 +179,35 @@ var AiProductEditionProvider = function AiProductEditionProvider(_ref) {
149
179
  case 5:
150
180
  newSuggestions = _context.sent;
151
181
 
152
- if (!(!Array.isArray(newSuggestions) || newSuggestions.length === 0)) {
182
+ if (!(newSuggestions !== null && newSuggestions !== void 0 && newSuggestions.error)) {
153
183
  _context.next = 8;
154
184
  break;
155
185
  }
156
186
 
157
- return _context.abrupt("return", console.log("Error: No se obtuvieron nuevas sugerencias"));
187
+ return _context.abrupt("return", {
188
+ error: newSuggestions.error
189
+ });
158
190
 
159
191
  case 8:
160
- if (newSuggestions) {
192
+ if (!(!Array.isArray(newSuggestions) || newSuggestions.length === 0)) {
161
193
  _context.next = 10;
162
194
  break;
163
195
  }
164
196
 
165
- return _context.abrupt("return", console.log("Error: No exiten resultados nuevos"));
197
+ return _context.abrupt("return", console.log("Error: No se obtuvieron nuevas sugerencias"));
166
198
 
167
199
  case 10:
200
+ if (newSuggestions) {
201
+ _context.next = 12;
202
+ break;
203
+ }
204
+
205
+ return _context.abrupt("return", console.log("Error: No exiten resultados nuevos"));
206
+
207
+ case 12:
168
208
  return _context.abrupt("return", newSuggestions);
169
209
 
170
- case 11:
210
+ case 13:
171
211
  case "end":
172
212
  return _context.stop();
173
213
  }
@@ -184,7 +224,7 @@ var AiProductEditionProvider = function AiProductEditionProvider(_ref) {
184
224
 
185
225
  function _generateProductSuggestions() {
186
226
  _generateProductSuggestions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref4) {
187
- var _ref4$inputName, inputName, _ref4$currentValue, currentValue, _ref4$description, description, _ref4$maxChar, maxChar, _ref4$type, type, articleId, versionId, descriptionId, attributeId, _state$product, _JSON$parse$data, _JSON$parse, upc, productName, retailer, category, version, payload, _yield$axios$post, data, results, _error$message;
227
+ var _ref4$inputName, inputName, _ref4$currentValue, currentValue, _ref4$description, description, _ref4$maxChar, maxChar, _ref4$type, type, articleId, versionId, descriptionId, attributeId, _state$product, _JSON$parse$data, _JSON$parse, rateLimitStatus, upc, productName, retailer, category, version, payload, _yield$axios$post, data, results, _error$message;
188
228
 
189
229
  return _regenerator.default.wrap(function _callee2$(_context2) {
190
230
  while (1) {
@@ -201,41 +241,54 @@ var AiProductEditionProvider = function AiProductEditionProvider(_ref) {
201
241
  return _context2.abrupt("return");
202
242
 
203
243
  case 4:
244
+ rateLimitStatus = checkAndManageRateLimit(articleId);
245
+
246
+ if (rateLimitStatus.allowed) {
247
+ _context2.next = 7;
248
+ break;
249
+ }
250
+
251
+ return _context2.abrupt("return", {
252
+ error: rateLimitStatus.message,
253
+ isRateLimitInfo: true
254
+ });
255
+
256
+ case 7:
204
257
  if (product) {
205
- _context2.next = 6;
258
+ _context2.next = 9;
206
259
  break;
207
260
  }
208
261
 
209
262
  throw new Error("El producto no está definido");
210
263
 
211
- case 6:
264
+ case 9:
212
265
  if (!(!Array.isArray(parsedDatasheet) || parsedDatasheet.length === 0)) {
213
- _context2.next = 8;
266
+ _context2.next = 11;
214
267
  break;
215
268
  }
216
269
 
217
270
  throw new Error("No es encontró la ficha técnica");
218
271
 
219
- case 8:
272
+ case 11:
220
273
  if (!(!Array.isArray(parsedImages) || parsedImages.length === 0)) {
221
- _context2.next = 10;
274
+ _context2.next = 13;
222
275
  break;
223
276
  }
224
277
 
225
278
  throw new Error("No se encontraron imágenes para la cadena seleccionada");
226
279
 
227
- case 10:
280
+ case 13:
228
281
  upc = product.upc, productName = product.productName, retailer = product.retailer, category = product.category;
229
282
  version = state === null || state === void 0 ? void 0 : (_state$product = state.product) === null || _state$product === void 0 ? void 0 : _state$product.version;
230
283
 
231
284
  if (!(!upc || !description || !productName || !category || !retailer || !articleId || !version || !descriptionId && !attributeId)) {
232
- _context2.next = 14;
285
+ _context2.next = 17;
233
286
  break;
234
287
  }
235
288
 
236
289
  throw new Error("Faltan parámetros obligatorios para generar sugerencias de IA");
237
290
 
238
- case 14:
291
+ case 17:
239
292
  payload = {
240
293
  upc: upc,
241
294
  attributeTitle: inputName,
@@ -253,42 +306,42 @@ var AiProductEditionProvider = function AiProductEditionProvider(_ref) {
253
306
  descriptionId: descriptionId,
254
307
  attributeId: attributeId
255
308
  };
256
- _context2.next = 17;
309
+ _context2.next = 20;
257
310
  return _axios.default.post(process.env.REACT_APP_GENERATE_AI_ATTRIBUTES, payload, {
258
311
  headers: {
259
312
  Authorization: token
260
313
  }
261
314
  });
262
315
 
263
- case 17:
316
+ case 20:
264
317
  _yield$axios$post = _context2.sent;
265
318
  data = _yield$axios$post.data;
266
319
  results = (_JSON$parse$data = (_JSON$parse = JSON.parse(data === null || data === void 0 ? void 0 : data.body)) === null || _JSON$parse === void 0 ? void 0 : _JSON$parse.data) !== null && _JSON$parse$data !== void 0 ? _JSON$parse$data : [];
267
320
 
268
321
  if (results) {
269
- _context2.next = 22;
322
+ _context2.next = 25;
270
323
  break;
271
324
  }
272
325
 
273
326
  throw new Error("No se encontraron resultados");
274
327
 
275
- case 22:
328
+ case 25:
276
329
  return _context2.abrupt("return", results);
277
330
 
278
- case 25:
279
- _context2.prev = 25;
331
+ case 28:
332
+ _context2.prev = 28;
280
333
  _context2.t0 = _context2["catch"](1);
281
334
  console.log("Error generating AI suggestions:", _context2.t0);
282
335
  return _context2.abrupt("return", {
283
336
  error: (_error$message = _context2.t0 === null || _context2.t0 === void 0 ? void 0 : _context2.t0.message) !== null && _error$message !== void 0 ? _error$message : "Error generating AI suggestions"
284
337
  });
285
338
 
286
- case 29:
339
+ case 32:
287
340
  case "end":
288
341
  return _context2.stop();
289
342
  }
290
343
  }
291
- }, _callee2, null, [[1, 25]]);
344
+ }, _callee2, null, [[1, 28]]);
292
345
  }));
293
346
  return _generateProductSuggestions.apply(this, arguments);
294
347
  }
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+
3
+ var STATUS_DICTIONARY = {
4
+ // R: {
5
+ // status: "R",
6
+ // name: "Recepción",
7
+ // weight: 1
8
+ // },
9
+ PA: {
10
+ status: "PA",
11
+ name: "Por Asignar",
12
+ weight: 2
13
+ },
14
+ AS: {
15
+ status: "AS",
16
+ name: "Asignado",
17
+ weight: 3
18
+ },
19
+ CA: {
20
+ status: "CA",
21
+ name: "Capturando",
22
+ weight: 4
23
+ },
24
+ // IE: {
25
+ // status: "IE",
26
+ // name: "Información Enviada",
27
+ // weight: 5
28
+ // },
29
+ RCA: {
30
+ status: "RCA",
31
+ name: "Rechazado Cadena",
32
+ weight: 6
33
+ },
34
+ RP: {
35
+ status: "RP",
36
+ name: "Rechazado Proveedor",
37
+ weight: 7
38
+ },
39
+ RA: {
40
+ status: "RA",
41
+ name: "Rechazado Auditor",
42
+ weight: 8
43
+ },
44
+ RC: {
45
+ status: "RC",
46
+ name: "Rechazo Coordinador",
47
+ weight: 9
48
+ },
49
+ AC: {
50
+ status: "AC",
51
+ name: "Aprobado Coordinador",
52
+ weight: 10
53
+ },
54
+ AA: {
55
+ status: "AA",
56
+ name: "Aprobado Auditor",
57
+ weight: 11
58
+ },
59
+ AP: {
60
+ status: "AP",
61
+ name: "Aprobado Proveedor",
62
+ weight: 12
63
+ },
64
+ ACA: {
65
+ status: "ACA",
66
+ name: "Aprobado Cadena",
67
+ weight: 13
68
+ },
69
+ Ex: {
70
+ status: "Ex",
71
+ name: "Exportado",
72
+ weight: 14
73
+ },
74
+ // RAC: {
75
+ // status: "RAC",
76
+ // name: "Rechazo de Auditoría Content-oh!",
77
+ // weight: 15
78
+ // },
79
+ // SAC: {
80
+ // status: "SAC",
81
+ // name: "Solicitud de Auditoría Content-oh!",
82
+ // weight: 16
83
+ // },
84
+ // AAC: {
85
+ // status: "AAC",
86
+ // name: "Aprobado Auditoría Content-oh!",
87
+ // weight: 17
88
+ // },
89
+ // FAP: {
90
+ // status: "FAP",
91
+ // name: "Finalización de Auditoría por Proveedor",
92
+ // weight: 18
93
+ // },
94
+ //El status NS necesita ser el mayor de todos
95
+ NS: {
96
+ status: "NS",
97
+ name: "No Solicitado",
98
+ weight: 100
99
+ }
100
+ };
101
+ module.exports = {
102
+ STATUS_DICTIONARY: STATUS_DICTIONARY
103
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contentoh-components-library",
3
- "version": "21.5.85",
3
+ "version": "21.5.87",
4
4
  "dependencies": {
5
5
  "@aws-amplify/auth": "^4.5.3",
6
6
  "@aws-amplify/datastore": "^3.11.0",
@@ -38,6 +38,10 @@ export const Container = styled.button`
38
38
  background-color: #603888;
39
39
  }
40
40
 
41
+ &.general-pink-button {
42
+ background-color: #E33AA9;
43
+ }
44
+
41
45
  &.general-transparent-button {
42
46
  background-color: transparent;
43
47
  border: 1px solid #503d66;
@@ -71,6 +71,8 @@ export const TagAndInput = ({
71
71
  const [isAiRegenerationLoading, setIsAiRegenerationLoading] = useState(false);
72
72
  const [isAiGenerated, setIsAiGenerated] = useState(false);
73
73
 
74
+ const [errorMessage, setErrorMessage] = useState("");
75
+
74
76
  async function handlerAiGeneration({
75
77
  type
76
78
  }) {
@@ -88,6 +90,7 @@ export const TagAndInput = ({
88
90
  if(Array.isArray(currentSuggestions) && currentSuggestions.length > 0)
89
91
  return setIsAiActive(true);
90
92
 
93
+ setErrorMessage("");
91
94
  setIsAiGenerationLoading(true);
92
95
 
93
96
  const aiSuggestions = await generateProductSuggestions({
@@ -104,7 +107,15 @@ export const TagAndInput = ({
104
107
  });
105
108
 
106
109
  if(!aiSuggestions && aiSuggestions.length === 0) {
107
- console.log("Error: No se recibieron sugerencias de IA");
110
+ const errorMsg = "Error: No se recibieron sugerencias de IA";
111
+ console.log(errorMsg);
112
+ setIsAiGenerationLoading(false);
113
+ return;
114
+ }
115
+
116
+ if(aiSuggestions?.error) {
117
+ console.log('Error: ', aiSuggestions.error);
118
+ setErrorMessage(aiSuggestions.error);
108
119
  setIsAiGenerationLoading(false);
109
120
  return;
110
121
  }
@@ -126,6 +137,7 @@ export const TagAndInput = ({
126
137
 
127
138
  if(isAiRegenerationLoading) return;
128
139
 
140
+ setErrorMessage("");
129
141
  setIsAiRegenerationLoading(true);
130
142
 
131
143
  const currentSuggestions = suggestions?.[inputId];
@@ -144,7 +156,18 @@ export const TagAndInput = ({
144
156
  });
145
157
 
146
158
  if(!aiSuggestions && aiSuggestions.length === 0) {
147
- console.log("Error: No se recibieron sugerencias de IA");
159
+ const errorMsg = "Error: No se recibieron sugerencias de IA";
160
+ console.log(errorMsg);
161
+ setErrorMessage(errorMsg);
162
+ setIsAiRegenerationLoading(false);
163
+ return;
164
+ }
165
+
166
+ console.log({aiSuggestionsRenew: aiSuggestions})
167
+
168
+ if(aiSuggestions?.error) {
169
+ console.log('Error: ', aiSuggestions.error);
170
+ setErrorMessage(aiSuggestions.error);
148
171
  setIsAiRegenerationLoading(false);
149
172
  return;
150
173
  }
@@ -320,6 +343,13 @@ export const TagAndInput = ({
320
343
  }
321
344
  </div>
322
345
  )}
346
+ {errorMessage && (
347
+ <div
348
+ className="error-message-container"
349
+ >
350
+ <p>{errorMessage}</p>
351
+ </div>
352
+ )}
323
353
  <GeneralInput
324
354
  inputId={inputId}
325
355
  inputType={inputType}
@@ -75,4 +75,15 @@ export const Container = styled.div`
75
75
  & + * {
76
76
  margin-top: ${({ inputType }) => (inputType !== "textarea" ? 0 : 10)}px;
77
77
  }
78
+
79
+ .error-message-container {
80
+
81
+ font-family: "Raleway";
82
+ font-size: 12px;
83
+ font-weight: 500;
84
+ color: #E1251B;
85
+ margin-bottom: 8px;
86
+ margin-top: 0;
87
+
88
+ }
78
89
  `;