contentoh-components-library 21.5.86 → 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.
- package/dist/components/molecules/TagAndInput/index.js +55 -14
- package/dist/components/molecules/TagAndInput/styles.js +1 -1
- package/dist/contexts/AiProductEdition.js +75 -22
- package/package.json +1 -1
- package/src/components/molecules/TagAndInput/index.js +32 -2
- package/src/components/molecules/TagAndInput/styles.js +11 -0
- package/src/contexts/AiProductEdition.jsx +45 -0
|
@@ -117,13 +117,18 @@ var TagAndInput = function TagAndInput(_ref) {
|
|
|
117
117
|
isAiGenerated = _useState10[0],
|
|
118
118
|
setIsAiGenerated = _useState10[1];
|
|
119
119
|
|
|
120
|
+
var _useState11 = (0, _react.useState)(""),
|
|
121
|
+
_useState12 = (0, _slicedToArray2.default)(_useState11, 2),
|
|
122
|
+
errorMessage = _useState12[0],
|
|
123
|
+
setErrorMessage = _useState12[1];
|
|
124
|
+
|
|
120
125
|
function handlerAiGeneration(_x) {
|
|
121
126
|
return _handlerAiGeneration.apply(this, arguments);
|
|
122
127
|
}
|
|
123
128
|
|
|
124
129
|
function _handlerAiGeneration() {
|
|
125
130
|
_handlerAiGeneration = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee(_ref2) {
|
|
126
|
-
var type, currentSuggestions, aiSuggestions;
|
|
131
|
+
var type, currentSuggestions, aiSuggestions, errorMsg;
|
|
127
132
|
return _regenerator.default.wrap(function _callee$(_context) {
|
|
128
133
|
while (1) {
|
|
129
134
|
switch (_context.prev = _context.next) {
|
|
@@ -158,8 +163,9 @@ var TagAndInput = function TagAndInput(_ref) {
|
|
|
158
163
|
return _context.abrupt("return", setIsAiActive(true));
|
|
159
164
|
|
|
160
165
|
case 9:
|
|
166
|
+
setErrorMessage("");
|
|
161
167
|
setIsAiGenerationLoading(true);
|
|
162
|
-
_context.next =
|
|
168
|
+
_context.next = 13;
|
|
163
169
|
return generateProductSuggestions({
|
|
164
170
|
inputName: label,
|
|
165
171
|
currentValue: value,
|
|
@@ -173,26 +179,38 @@ var TagAndInput = function TagAndInput(_ref) {
|
|
|
173
179
|
attributeId: isBenefitInput ? inputId : null
|
|
174
180
|
});
|
|
175
181
|
|
|
176
|
-
case
|
|
182
|
+
case 13:
|
|
177
183
|
aiSuggestions = _context.sent;
|
|
178
184
|
|
|
179
185
|
if (!(!aiSuggestions && aiSuggestions.length === 0)) {
|
|
180
|
-
_context.next =
|
|
186
|
+
_context.next = 19;
|
|
187
|
+
break;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
errorMsg = "Error: No se recibieron sugerencias de IA";
|
|
191
|
+
console.log(errorMsg);
|
|
192
|
+
setIsAiGenerationLoading(false);
|
|
193
|
+
return _context.abrupt("return");
|
|
194
|
+
|
|
195
|
+
case 19:
|
|
196
|
+
if (!(aiSuggestions !== null && aiSuggestions !== void 0 && aiSuggestions.error)) {
|
|
197
|
+
_context.next = 24;
|
|
181
198
|
break;
|
|
182
199
|
}
|
|
183
200
|
|
|
184
|
-
console.log(
|
|
201
|
+
console.log('Error: ', aiSuggestions.error);
|
|
202
|
+
setErrorMessage(aiSuggestions.error);
|
|
185
203
|
setIsAiGenerationLoading(false);
|
|
186
204
|
return _context.abrupt("return");
|
|
187
205
|
|
|
188
|
-
case
|
|
206
|
+
case 24:
|
|
189
207
|
setSuggestions(function (prev) {
|
|
190
208
|
return (0, _objectSpread6.default)((0, _objectSpread6.default)({}, prev), {}, (0, _defineProperty2.default)({}, inputId, aiSuggestions));
|
|
191
209
|
});
|
|
192
210
|
setIsAiActive(true);
|
|
193
211
|
setIsAiGenerationLoading(false);
|
|
194
212
|
|
|
195
|
-
case
|
|
213
|
+
case 27:
|
|
196
214
|
case "end":
|
|
197
215
|
return _context.stop();
|
|
198
216
|
}
|
|
@@ -208,7 +226,7 @@ var TagAndInput = function TagAndInput(_ref) {
|
|
|
208
226
|
|
|
209
227
|
function _handlerRegenerateSuggestions() {
|
|
210
228
|
_handlerRegenerateSuggestions = (0, _asyncToGenerator2.default)( /*#__PURE__*/_regenerator.default.mark(function _callee2(_ref3) {
|
|
211
|
-
var _ref3$type, type, currentSuggestions, aiSuggestions;
|
|
229
|
+
var _ref3$type, type, currentSuggestions, aiSuggestions, errorMsg;
|
|
212
230
|
|
|
213
231
|
return _regenerator.default.wrap(function _callee2$(_context2) {
|
|
214
232
|
while (1) {
|
|
@@ -224,9 +242,10 @@ var TagAndInput = function TagAndInput(_ref) {
|
|
|
224
242
|
return _context2.abrupt("return");
|
|
225
243
|
|
|
226
244
|
case 3:
|
|
245
|
+
setErrorMessage("");
|
|
227
246
|
setIsAiRegenerationLoading(true);
|
|
228
247
|
currentSuggestions = suggestions === null || suggestions === void 0 ? void 0 : suggestions[inputId];
|
|
229
|
-
_context2.next =
|
|
248
|
+
_context2.next = 8;
|
|
230
249
|
return regenerateProductSuggestions({
|
|
231
250
|
inputName: label,
|
|
232
251
|
currentValue: value,
|
|
@@ -240,25 +259,42 @@ var TagAndInput = function TagAndInput(_ref) {
|
|
|
240
259
|
attributeId: isBenefitInput ? inputId : null
|
|
241
260
|
});
|
|
242
261
|
|
|
243
|
-
case
|
|
262
|
+
case 8:
|
|
244
263
|
aiSuggestions = _context2.sent;
|
|
245
264
|
|
|
246
265
|
if (!(!aiSuggestions && aiSuggestions.length === 0)) {
|
|
247
|
-
_context2.next =
|
|
266
|
+
_context2.next = 15;
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
errorMsg = "Error: No se recibieron sugerencias de IA";
|
|
271
|
+
console.log(errorMsg);
|
|
272
|
+
setErrorMessage(errorMsg);
|
|
273
|
+
setIsAiRegenerationLoading(false);
|
|
274
|
+
return _context2.abrupt("return");
|
|
275
|
+
|
|
276
|
+
case 15:
|
|
277
|
+
console.log({
|
|
278
|
+
aiSuggestionsRenew: aiSuggestions
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
if (!(aiSuggestions !== null && aiSuggestions !== void 0 && aiSuggestions.error)) {
|
|
282
|
+
_context2.next = 21;
|
|
248
283
|
break;
|
|
249
284
|
}
|
|
250
285
|
|
|
251
|
-
console.log(
|
|
286
|
+
console.log('Error: ', aiSuggestions.error);
|
|
287
|
+
setErrorMessage(aiSuggestions.error);
|
|
252
288
|
setIsAiRegenerationLoading(false);
|
|
253
289
|
return _context2.abrupt("return");
|
|
254
290
|
|
|
255
|
-
case
|
|
291
|
+
case 21:
|
|
256
292
|
setSuggestions(function (prev) {
|
|
257
293
|
return (0, _objectSpread6.default)((0, _objectSpread6.default)({}, prev), {}, (0, _defineProperty2.default)({}, inputId, [].concat((0, _toConsumableArray2.default)(currentSuggestions), (0, _toConsumableArray2.default)(aiSuggestions))));
|
|
258
294
|
});
|
|
259
295
|
setIsAiRegenerationLoading(false);
|
|
260
296
|
|
|
261
|
-
case
|
|
297
|
+
case 23:
|
|
262
298
|
case "end":
|
|
263
299
|
return _context2.stop();
|
|
264
300
|
}
|
|
@@ -403,6 +439,11 @@ var TagAndInput = function TagAndInput(_ref) {
|
|
|
403
439
|
children: "Atributo generado con IA"
|
|
404
440
|
})]
|
|
405
441
|
}) : null]
|
|
442
|
+
}), errorMessage && /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
|
|
443
|
+
className: "error-message-container",
|
|
444
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("p", {
|
|
445
|
+
children: errorMessage
|
|
446
|
+
})
|
|
406
447
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_index2.GeneralInput, {
|
|
407
448
|
inputId: inputId,
|
|
408
449
|
inputType: inputType,
|
|
@@ -15,7 +15,7 @@ var _variables = require("../../../global-files/variables");
|
|
|
15
15
|
|
|
16
16
|
var _templateObject;
|
|
17
17
|
|
|
18
|
-
var Container = _styledComponents.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n .title-container {\n position: relative;\n\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n font-family: ", ";\n\n .titles{\n display: flex;\n gap: .5rem;\n align-items: center;\n }\n\n .icon_information{\n width: 1.35rem;\n height: 1.35rem;\n filter: brightness(.35);\n margin-top: 10px;\n }\n\n .tooltip {\n display: none;\n position: absolute;\n background-color: ", ";\n color: ", ";\n font-size: 14px;\n line-height: 19px;\n left: 0;\n top: 0;\n height: fit-content;\n transition: display 2s;\n }\n\n .ai-generated{\n\n display: flex;\n align-items: items-center;\n gap: .5rem;\n font-size: 11px;\n background-color: rgba(224, 57, 167, 0.025);\n border: 1px solid rgba(224, 57, 167, 0.1);\n padding: .25rem .5rem;\n border-radius: 5px;\n margin-left: 0.5rem;\n margin-top: 7px;\n cursor: default;\n\n > img {\n width: 0.75rem;\n height: 0.75rem;\n }\n\n }\n\n &:hover {\n .tooltip {\n display: block;\n }\n }\n\n\n }\n\n & > :first-child {\n & + * {\n margin-top: ", "px;\n }\n }\n & + * {\n margin-top: ", "px;\n }\n"])), _variables.FontFamily.Raleway, _variables.GlobalColors.white, function (_ref) {
|
|
18
|
+
var Container = _styledComponents.default.div(_templateObject || (_templateObject = (0, _taggedTemplateLiteral2.default)(["\n .title-container {\n position: relative;\n\n display: flex;\n align-items: center;\n justify-content: space-between;\n\n font-family: ", ";\n\n .titles{\n display: flex;\n gap: .5rem;\n align-items: center;\n }\n\n .icon_information{\n width: 1.35rem;\n height: 1.35rem;\n filter: brightness(.35);\n margin-top: 10px;\n }\n\n .tooltip {\n display: none;\n position: absolute;\n background-color: ", ";\n color: ", ";\n font-size: 14px;\n line-height: 19px;\n left: 0;\n top: 0;\n height: fit-content;\n transition: display 2s;\n }\n\n .ai-generated{\n\n display: flex;\n align-items: items-center;\n gap: .5rem;\n font-size: 11px;\n background-color: rgba(224, 57, 167, 0.025);\n border: 1px solid rgba(224, 57, 167, 0.1);\n padding: .25rem .5rem;\n border-radius: 5px;\n margin-left: 0.5rem;\n margin-top: 7px;\n cursor: default;\n\n > img {\n width: 0.75rem;\n height: 0.75rem;\n }\n\n }\n\n &:hover {\n .tooltip {\n display: block;\n }\n }\n\n\n }\n\n & > :first-child {\n & + * {\n margin-top: ", "px;\n }\n }\n & + * {\n margin-top: ", "px;\n }\n\n .error-message-container {\n\n font-family: \"Raleway\";\n font-size: 12px;\n font-weight: 500;\n color: #E1251B;\n margin-bottom: 8px;\n margin-top: 0;\n\n }\n"])), _variables.FontFamily.Raleway, _variables.GlobalColors.white, function (_ref) {
|
|
19
19
|
var color = _ref.color;
|
|
20
20
|
return color ? color : _variables.GlobalColors.s5;
|
|
21
21
|
}, function (_ref2) {
|
|
@@ -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 (!(
|
|
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",
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
264
|
+
case 9:
|
|
212
265
|
if (!(!Array.isArray(parsedDatasheet) || parsedDatasheet.length === 0)) {
|
|
213
|
-
_context2.next =
|
|
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
|
|
272
|
+
case 11:
|
|
220
273
|
if (!(!Array.isArray(parsedImages) || parsedImages.length === 0)) {
|
|
221
|
-
_context2.next =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
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
|
|
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 =
|
|
322
|
+
_context2.next = 25;
|
|
270
323
|
break;
|
|
271
324
|
}
|
|
272
325
|
|
|
273
326
|
throw new Error("No se encontraron resultados");
|
|
274
327
|
|
|
275
|
-
case
|
|
328
|
+
case 25:
|
|
276
329
|
return _context2.abrupt("return", results);
|
|
277
330
|
|
|
278
|
-
case
|
|
279
|
-
_context2.prev =
|
|
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
|
|
339
|
+
case 32:
|
|
287
340
|
case "end":
|
|
288
341
|
return _context2.stop();
|
|
289
342
|
}
|
|
290
343
|
}
|
|
291
|
-
}, _callee2, null, [[1,
|
|
344
|
+
}, _callee2, null, [[1, 28]]);
|
|
292
345
|
}));
|
|
293
346
|
return _generateProductSuggestions.apply(this, arguments);
|
|
294
347
|
}
|
package/package.json
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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
|
`;
|
|
@@ -45,7 +45,39 @@ export const AiProductEditionProvider = ({
|
|
|
45
45
|
const [inputsGeneratedWithAi, setInputsGeneratedWithAi] = useState({});
|
|
46
46
|
const [inputsUsingAi, setInputsUsingAi] = useState({});
|
|
47
47
|
|
|
48
|
+
const MAX_CREDITS = 10;
|
|
49
|
+
const COOLDOWN_MS = 5 * 60 * 1000;
|
|
50
|
+
const RATE_LIMIT_KEY = "ai_generation_limit_data";
|
|
48
51
|
|
|
52
|
+
const checkAndManageRateLimit = (currentArticleId) => {
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
const storedData = localStorage.getItem(RATE_LIMIT_KEY);
|
|
55
|
+
|
|
56
|
+
let allRateData = storedData ? JSON.parse(storedData) : {};
|
|
57
|
+
|
|
58
|
+
let productTimestamps = allRateData[currentArticleId] || [];
|
|
59
|
+
|
|
60
|
+
productTimestamps = productTimestamps.filter(timestamp => (now - timestamp) < COOLDOWN_MS);
|
|
61
|
+
|
|
62
|
+
if (productTimestamps.length >= MAX_CREDITS) {
|
|
63
|
+
|
|
64
|
+
allRateData[currentArticleId] = productTimestamps;
|
|
65
|
+
localStorage.setItem(RATE_LIMIT_KEY, JSON.stringify(allRateData));
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
allowed: false,
|
|
69
|
+
message: "Has alcanzado el limite de intentos frecuentes para este producto. Por favor, espera unos minutos."
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
productTimestamps.push(now);
|
|
75
|
+
allRateData[currentArticleId] = productTimestamps;
|
|
76
|
+
|
|
77
|
+
localStorage.setItem(RATE_LIMIT_KEY, JSON.stringify(allRateData));
|
|
78
|
+
|
|
79
|
+
return { allowed: true };
|
|
80
|
+
};
|
|
49
81
|
|
|
50
82
|
function setCurrentSuggestionValue({
|
|
51
83
|
inputId,
|
|
@@ -93,6 +125,10 @@ export const AiProductEditionProvider = ({
|
|
|
93
125
|
attributeId
|
|
94
126
|
});
|
|
95
127
|
|
|
128
|
+
if(newSuggestions?.error) return {
|
|
129
|
+
error: newSuggestions.error
|
|
130
|
+
}
|
|
131
|
+
|
|
96
132
|
if(!Array.isArray(newSuggestions) || newSuggestions.length === 0)
|
|
97
133
|
return console.log("Error: No se obtuvieron nuevas sugerencias");
|
|
98
134
|
|
|
@@ -119,6 +155,15 @@ export const AiProductEditionProvider = ({
|
|
|
119
155
|
|
|
120
156
|
if(!isAiAvailable) return;
|
|
121
157
|
|
|
158
|
+
const rateLimitStatus = checkAndManageRateLimit(articleId);
|
|
159
|
+
|
|
160
|
+
if (!rateLimitStatus.allowed) {
|
|
161
|
+
return {
|
|
162
|
+
error: rateLimitStatus.message,
|
|
163
|
+
isRateLimitInfo: true
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
122
167
|
if(!product)
|
|
123
168
|
throw new Error("El producto no está definido");
|
|
124
169
|
|