contentoh-components-library 21.5.78 → 21.5.81
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/ai/utils/compare-strings.js +43 -0
- package/dist/components/atoms/GeneralInput/index.js +64 -36
- package/dist/components/atoms/GeneralInput/styles.js +1 -1
- package/dist/components/atoms/InputFormatter/index.js +45 -21
- package/dist/components/atoms/InputFormatter/styles.js +1 -1
- package/dist/components/molecules/StatusAsignationInfo/index.js +11 -1
- package/dist/components/molecules/TagAndInput/index.js +110 -29
- package/dist/components/molecules/TagAndInput/styles.js +2 -2
- package/dist/components/organisms/InputGroup/index.js +22 -18
- package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +92 -785
- package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.context.js +59 -260
- package/dist/components/pages/RetailerProductEdition/context/reducers/product.js +3 -41
- package/dist/components/pages/RetailerProductEdition/index.js +191 -123
- package/dist/contexts/AiProductEdition.js +179 -155
- package/package.json +1 -1
- package/src/ai/utils/compare-strings.js +43 -0
- package/src/components/atoms/GeneralInput/index.js +63 -42
- package/src/components/atoms/GeneralInput/styles.js +7 -0
- package/src/components/atoms/InputFormatter/index.js +51 -23
- package/src/components/atoms/InputFormatter/styles.js +62 -10
- package/src/components/molecules/StatusAsignationInfo/index.js +9 -1
- package/src/components/molecules/TagAndInput/index.js +113 -28
- package/src/components/molecules/TagAndInput/styles.js +48 -17
- package/src/components/organisms/FullTabsMenu/index.js +1 -1
- package/src/components/organisms/InputGroup/index.js +4 -0
- package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +111 -832
- package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +3 -221
- package/src/components/pages/RetailerProductEdition/context/reducers/product.js +3 -43
- package/src/components/pages/RetailerProductEdition/index.js +17 -15
- package/src/contexts/AiProductEdition.jsx +138 -96
- package/src/ai/prompts/attribute.prompt.js +0 -46
- package/src/ai/prompts/description.prompt.js +0 -52
- package/src/ai/schemas/attribute.schema.js +0 -23
- package/src/ai/schemas/description.schema.js +0 -19
|
@@ -11,6 +11,7 @@ import ReloadIcon from "../../../assets/images/Icons/reload.png";
|
|
|
11
11
|
|
|
12
12
|
import { useAiProductEdition } from "../../../contexts/AiProductEdition";
|
|
13
13
|
import { InputContainer, BottomContainer, OptionsContainer, ButtonsContainer } from "../InputFormatter/styles";
|
|
14
|
+
import { getTextSimilarityPercentage } from "../../../ai/utils/compare-strings";
|
|
14
15
|
|
|
15
16
|
export const GeneralInput = ({
|
|
16
17
|
inputType,
|
|
@@ -43,11 +44,14 @@ export const GeneralInput = ({
|
|
|
43
44
|
isAiGenerationLoading = false,
|
|
44
45
|
isAiRegenerationLoading=false,
|
|
45
46
|
isAiActive = false,
|
|
46
|
-
|
|
47
|
+
isAiAvailable = false,
|
|
48
|
+
aiGenerated = false,
|
|
49
|
+
|
|
47
50
|
setIsAiActive = () => {},
|
|
48
51
|
handlerAiGeneration = () => {},
|
|
49
52
|
handlerRegenerateSuggestions = () => {},
|
|
50
53
|
handleChangeSuggestion = () => {}
|
|
54
|
+
|
|
51
55
|
}) => {
|
|
52
56
|
|
|
53
57
|
const {
|
|
@@ -64,40 +68,34 @@ export const GeneralInput = ({
|
|
|
64
68
|
const [aiSuggestionAccepted, setAiSuggestionAccepted] = useState(false);
|
|
65
69
|
const [valueAccepted, setValueAccepted] = useState(textValue);
|
|
66
70
|
|
|
71
|
+
const updateParentData = (generalValue, isAiAccepted) => {
|
|
72
|
+
setTextValue({ value: generalValue });
|
|
67
73
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
inputType === "textarea"
|
|
75
|
-
) {
|
|
76
|
-
let generalValue;
|
|
77
|
-
if (optionList?.length > 0) {
|
|
78
|
-
let valueSelected = evt.target.value;
|
|
79
|
-
generalValue = valueSelected;
|
|
80
|
-
setTextValue({ value: generalValue });
|
|
81
|
-
} else {
|
|
82
|
-
generalValue =
|
|
83
|
-
inputType === "checkbox" ? evt.target.checked : evt.target.value;
|
|
84
|
-
setTextValue({
|
|
85
|
-
value: generalValue,
|
|
86
|
-
});
|
|
87
|
-
}
|
|
88
|
-
let dataSave = updatedDatasheets?.slice();
|
|
74
|
+
const similarity = getTextSimilarityPercentage(valueAccepted, inputValue);
|
|
75
|
+
|
|
76
|
+
const generatedWithAi = (isAiAccepted) || aiGenerated && similarity >= 50;
|
|
77
|
+
|
|
78
|
+
if (updatedDatasheets || updatedDescriptions || inputType === "textarea") {
|
|
79
|
+
let dataSave = updatedDatasheets?.slice() || [];
|
|
89
80
|
|
|
90
81
|
if (dataSave?.length > 0) {
|
|
91
82
|
const index = dataSave.findIndex((e) => e.attributeId === inputId);
|
|
92
83
|
if (index !== -1) {
|
|
93
|
-
if (generalValue !== inputValue)
|
|
94
|
-
|
|
84
|
+
if (generalValue !== inputValue) {
|
|
85
|
+
dataSave[index].value = generalValue;
|
|
86
|
+
dataSave[index].aiSuggestionAccepted = generatedWithAi;
|
|
87
|
+
} else {
|
|
88
|
+
dataSave.splice(index, 1);
|
|
89
|
+
}
|
|
95
90
|
} else {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
91
|
+
if (generalValue !== inputValue) {
|
|
92
|
+
dataSave.push({
|
|
93
|
+
articleId: articleId,
|
|
94
|
+
attributeId: inputId,
|
|
95
|
+
value: generalValue,
|
|
96
|
+
aiSuggestionAccepted: generatedWithAi,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
101
99
|
}
|
|
102
100
|
} else {
|
|
103
101
|
if (generalValue !== inputValue) {
|
|
@@ -105,10 +103,32 @@ export const GeneralInput = ({
|
|
|
105
103
|
articleId: articleId,
|
|
106
104
|
attributeId: inputId,
|
|
107
105
|
value: generalValue,
|
|
106
|
+
aiSuggestionAccepted: generatedWithAi,
|
|
108
107
|
});
|
|
109
108
|
}
|
|
110
109
|
}
|
|
111
110
|
setUpdatedDatasheets(dataSave);
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
const onHandleChange = (evt) => {
|
|
115
|
+
if (validateInput) {
|
|
116
|
+
setTextValue({ value: validateInput(evt, position, inputsArray) });
|
|
117
|
+
} else if (
|
|
118
|
+
updatedDatasheets ||
|
|
119
|
+
updatedDescriptions ||
|
|
120
|
+
inputType === "textarea"
|
|
121
|
+
) {
|
|
122
|
+
let generalValue;
|
|
123
|
+
if (optionList?.length > 0) {
|
|
124
|
+
generalValue = evt.target.value;
|
|
125
|
+
} else {
|
|
126
|
+
generalValue =
|
|
127
|
+
inputType === "checkbox" ? evt.target.checked : evt.target.value;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
updateParentData(generalValue, aiSuggestionAccepted);
|
|
131
|
+
|
|
112
132
|
} else {
|
|
113
133
|
setTextValue({ value: evt.target.value });
|
|
114
134
|
inputOnChange && inputOnChange(evt);
|
|
@@ -136,12 +156,11 @@ export const GeneralInput = ({
|
|
|
136
156
|
|
|
137
157
|
}, [suggestions]);
|
|
138
158
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
159
|
+
useEffect(() => {
|
|
160
|
+
if(!isAiActive && !aiSuggestionAccepted) {
|
|
161
|
+
const restoredValue = typeof valueAccepted === 'object' ? valueAccepted.value : valueAccepted;
|
|
162
|
+
setTextValue({ value: restoredValue });
|
|
163
|
+
}
|
|
145
164
|
}, [suggestions, isAiActive]);
|
|
146
165
|
|
|
147
166
|
useEffect(() => {
|
|
@@ -163,13 +182,13 @@ export const GeneralInput = ({
|
|
|
163
182
|
//AI Generation
|
|
164
183
|
|
|
165
184
|
const handleAcceptSuggestion = (suggestionValue) => {
|
|
166
|
-
|
|
167
185
|
if(!suggestionValue) return;
|
|
168
186
|
|
|
169
|
-
|
|
170
|
-
setValueAccepted(suggestionValue);
|
|
187
|
+
setValueAccepted({ value: suggestionValue });
|
|
171
188
|
setAiSuggestionAccepted(true);
|
|
172
189
|
setIsAiActive(false);
|
|
190
|
+
|
|
191
|
+
updateParentData(suggestionValue, true);
|
|
173
192
|
}
|
|
174
193
|
|
|
175
194
|
return (
|
|
@@ -218,10 +237,10 @@ export const GeneralInput = ({
|
|
|
218
237
|
{
|
|
219
238
|
|
|
220
239
|
hasAiGeneration && isBenefitInput && (
|
|
221
|
-
<div className=
|
|
240
|
+
<div className={`icon_container ${isAiAvailable ? "ai-available" : ''} ${isAiActive ? 'ai-active' : ''}`} title={!isAiAvailable ? 'Debes de completar ficha técnica e imágenes para desbloquear la generación con IA' : ''} onClick={() => {
|
|
222
241
|
handlerAiGeneration({ type: "attribute" })
|
|
223
242
|
}}>
|
|
224
|
-
<img className={isAiGenerationLoading ?
|
|
243
|
+
<img className={`${isAiGenerationLoading ? 'loading' : ''}`} src={isAiGenerationLoading ? LoadingIcon : isAiActive ? CancelIcon : AiGenerationIcon} />
|
|
225
244
|
</div>
|
|
226
245
|
)
|
|
227
246
|
|
|
@@ -290,7 +309,9 @@ export const GeneralInput = ({
|
|
|
290
309
|
maxChar={maxChar}
|
|
291
310
|
isRequired={isRequired}
|
|
292
311
|
disabled={disabled}
|
|
293
|
-
hasAiGeneration={hasAiGeneration}
|
|
312
|
+
hasAiGeneration={hasAiGeneration && inputId != 'commentary-box'}
|
|
313
|
+
isAiAvailable={isAiAvailable}
|
|
314
|
+
aiGenerated={aiGenerated}
|
|
294
315
|
handlerAiGeneration={() => {
|
|
295
316
|
handlerAiGeneration({ type: "description" })
|
|
296
317
|
}}
|
|
@@ -301,7 +322,7 @@ export const GeneralInput = ({
|
|
|
301
322
|
isAiGenerationLoading={isAiGenerationLoading}
|
|
302
323
|
isAiRegenerationLoading={isAiRegenerationLoading}
|
|
303
324
|
isAiActive={isAiActive}
|
|
304
|
-
|
|
325
|
+
setIsAiActive={setIsAiActive}
|
|
305
326
|
/>
|
|
306
327
|
)}
|
|
307
328
|
{/* <p>{description}</p> */}
|
|
@@ -9,9 +9,10 @@ import LoadingIcon from "../../../assets/images/Icons/loading.svg";
|
|
|
9
9
|
import CancelIcon from "../../../assets/images/Icons/cancel.png";
|
|
10
10
|
import ReloadIcon from "../../../assets/images/Icons/reload.png";
|
|
11
11
|
|
|
12
|
-
|
|
13
12
|
import { useAiProductEdition } from "../../../contexts/AiProductEdition";
|
|
14
13
|
|
|
14
|
+
import { getTextSimilarityPercentage } from "../../../ai/utils/compare-strings";
|
|
15
|
+
|
|
15
16
|
export const InputFormatter = ({
|
|
16
17
|
mainValue = "",
|
|
17
18
|
inputId,
|
|
@@ -27,6 +28,9 @@ export const InputFormatter = ({
|
|
|
27
28
|
isAiGenerationLoading = false,
|
|
28
29
|
isAiRegenerationLoading=false,
|
|
29
30
|
isAiActive = false,
|
|
31
|
+
isAiAvailable = false,
|
|
32
|
+
aiGenerated = false,
|
|
33
|
+
|
|
30
34
|
setIsAiActive = () => {},
|
|
31
35
|
handlerAiGeneration = () => {},
|
|
32
36
|
handlerRegenerateSuggestions = () => {},
|
|
@@ -72,7 +76,6 @@ export const InputFormatter = ({
|
|
|
72
76
|
};
|
|
73
77
|
|
|
74
78
|
const onChange = (valueInput, h) => {
|
|
75
|
-
|
|
76
79
|
let value = "";
|
|
77
80
|
try {
|
|
78
81
|
if (h.getLength() - 1 <= maxLength) {
|
|
@@ -96,32 +99,49 @@ export const InputFormatter = ({
|
|
|
96
99
|
setCharsCounter(h.getLength() - 1);
|
|
97
100
|
value = valueFormater(value);
|
|
98
101
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
102
|
+
updateParentDescriptions(value, aiSuggestionAccepted);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const updateParentDescriptions = (finalValue, isAiAccepted) => {
|
|
106
|
+
if (!updatedDescriptions) return;
|
|
107
|
+
|
|
108
|
+
let idInput = inputId;
|
|
109
|
+
let dataSave = updatedDescriptions?.slice();
|
|
110
|
+
|
|
111
|
+
const similarity = getTextSimilarityPercentage(valueAccepted, inputValue);
|
|
112
|
+
|
|
113
|
+
const generatedWithAi = (isAiAccepted) || aiGenerated && similarity >= 50;
|
|
114
|
+
|
|
115
|
+
if (dataSave?.length > 0) {
|
|
116
|
+
const index = dataSave.findIndex((e) => e.attributeId === idInput);
|
|
117
|
+
if (index !== -1) {
|
|
118
|
+
if (finalValue !== mainValue) {
|
|
119
|
+
dataSave[index].value = finalValue;
|
|
120
|
+
dataSave[index].aiSuggestionAccepted = generatedWithAi;
|
|
107
121
|
} else {
|
|
108
|
-
dataSave.
|
|
109
|
-
articleId: articleId,
|
|
110
|
-
attributeId: idInput,
|
|
111
|
-
value: value,
|
|
112
|
-
});
|
|
122
|
+
dataSave.splice(index, 1);
|
|
113
123
|
}
|
|
114
124
|
} else {
|
|
115
|
-
if (
|
|
125
|
+
if (finalValue !== mainValue) {
|
|
116
126
|
dataSave.push({
|
|
117
127
|
articleId: articleId,
|
|
118
128
|
attributeId: idInput,
|
|
119
|
-
value:
|
|
129
|
+
value: finalValue,
|
|
130
|
+
aiSuggestionAccepted: generatedWithAi,
|
|
120
131
|
});
|
|
121
132
|
}
|
|
122
133
|
}
|
|
123
|
-
|
|
134
|
+
} else {
|
|
135
|
+
if (finalValue !== mainValue) {
|
|
136
|
+
dataSave.push({
|
|
137
|
+
articleId: articleId,
|
|
138
|
+
attributeId: idInput,
|
|
139
|
+
value: finalValue,
|
|
140
|
+
aiSuggestionAccepted: generatedWithAi,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
124
143
|
}
|
|
144
|
+
setUpdatedDescriptions(dataSave);
|
|
125
145
|
};
|
|
126
146
|
|
|
127
147
|
const getSelection = (range, a, b) => {
|
|
@@ -136,14 +156,19 @@ export const InputFormatter = ({
|
|
|
136
156
|
|
|
137
157
|
//AI Generation
|
|
138
158
|
const handleAcceptSuggestion = (suggestionValue) => {
|
|
139
|
-
|
|
140
|
-
if(!suggestionValue) return;
|
|
159
|
+
if (!suggestionValue) return;
|
|
141
160
|
|
|
142
161
|
setInputValue(suggestionValue);
|
|
143
162
|
setValueAccepted(suggestionValue);
|
|
144
163
|
setAiSuggestionAccepted(true);
|
|
145
164
|
setIsAiActive(false);
|
|
146
|
-
|
|
165
|
+
|
|
166
|
+
// Formateamos el valor sugerido igual que en el onChange
|
|
167
|
+
const formattedSuggestion = valueFormater(suggestionValue);
|
|
168
|
+
|
|
169
|
+
// Disparamos la actualización enviando "true" directamente
|
|
170
|
+
updateParentDescriptions(formattedSuggestion, true);
|
|
171
|
+
};
|
|
147
172
|
|
|
148
173
|
useEffect(() => {
|
|
149
174
|
|
|
@@ -161,6 +186,7 @@ export const InputFormatter = ({
|
|
|
161
186
|
setAiSuggestionAccepted(false);
|
|
162
187
|
|
|
163
188
|
}, [isAiActive]);
|
|
189
|
+
|
|
164
190
|
//End Ai Generation
|
|
165
191
|
|
|
166
192
|
return (
|
|
@@ -181,7 +207,9 @@ export const InputFormatter = ({
|
|
|
181
207
|
currentSuggestion?.[inputId]?.value
|
|
182
208
|
) : getValue(inputValue)}
|
|
183
209
|
readOnly={isAiActive || disabled}
|
|
184
|
-
modules={{
|
|
210
|
+
modules={{
|
|
211
|
+
toolbar: false,
|
|
212
|
+
}}
|
|
185
213
|
onKeyPress={(e) => {
|
|
186
214
|
if (charsCounter >= maxLength && e.key !== "Backspace") {
|
|
187
215
|
e.preventDefault();
|
|
@@ -210,7 +238,7 @@ export const InputFormatter = ({
|
|
|
210
238
|
}
|
|
211
239
|
{
|
|
212
240
|
hasAiGeneration && (
|
|
213
|
-
<div className={`icon_container ${isAiActive
|
|
241
|
+
<div className={`icon_container ${isAiActive ? "ai-active" : ''} ${isAiAvailable ? "ai-available" : ''}`} title={!isAiAvailable ? 'Debes de completar ficha técnica e imágenes para desbloquear la generación con IA' : ''} onClick={handlerAiGeneration}>
|
|
214
242
|
<img className={isAiGenerationLoading ? "loading" : ""} src={isAiGenerationLoading ? LoadingIcon : isAiActive ? CancelIcon : AiGenerationIcon} />
|
|
215
243
|
</div>
|
|
216
244
|
)
|
|
@@ -62,13 +62,11 @@ export const Container = styled.div`
|
|
|
62
62
|
margin-top: 5px;
|
|
63
63
|
}
|
|
64
64
|
`;
|
|
65
|
-
|
|
66
65
|
export const InputContainer = styled.div`
|
|
67
66
|
|
|
68
67
|
&.ai-generation {
|
|
69
|
-
position: relative;
|
|
70
68
|
|
|
71
|
-
|
|
69
|
+
position: relative;
|
|
72
70
|
|
|
73
71
|
> input[type=text] {
|
|
74
72
|
padding-right: 2.5rem;
|
|
@@ -87,6 +85,8 @@ export const InputContainer = styled.div`
|
|
|
87
85
|
height: 22.5px;
|
|
88
86
|
padding: 4px;
|
|
89
87
|
|
|
88
|
+
cursor: not-allowed;
|
|
89
|
+
|
|
90
90
|
border-radius: 50%;
|
|
91
91
|
overflow: hidden;
|
|
92
92
|
display: flex;
|
|
@@ -94,10 +94,6 @@ export const InputContainer = styled.div`
|
|
|
94
94
|
justify-content: center;
|
|
95
95
|
z-index: 1;
|
|
96
96
|
|
|
97
|
-
&.ai-active::before {
|
|
98
|
-
background: #FB4141;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
97
|
&::before {
|
|
102
98
|
content: '';
|
|
103
99
|
position: absolute;
|
|
@@ -106,6 +102,18 @@ export const InputContainer = styled.div`
|
|
|
106
102
|
width: 100%;
|
|
107
103
|
height: 100%;
|
|
108
104
|
|
|
105
|
+
background: gray;
|
|
106
|
+
background-size: 200% 200%;
|
|
107
|
+
|
|
108
|
+
animation: ai-shimmer 3s ease-in-out infinite alternate;
|
|
109
|
+
z-index: -1;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&.ai-available {
|
|
113
|
+
cursor: pointer;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
&.ai-available::before{
|
|
109
117
|
background: linear-gradient(
|
|
110
118
|
120deg,
|
|
111
119
|
#4285F4 20%,
|
|
@@ -113,9 +121,40 @@ export const InputContainer = styled.div`
|
|
|
113
121
|
#4285F4 80%
|
|
114
122
|
);
|
|
115
123
|
background-size: 200% 200%;
|
|
124
|
+
}
|
|
116
125
|
|
|
117
|
-
|
|
118
|
-
|
|
126
|
+
&.ai-available::after {
|
|
127
|
+
content: "";
|
|
128
|
+
position: absolute;
|
|
129
|
+
top: 0;
|
|
130
|
+
left: 0;
|
|
131
|
+
width: 100%;
|
|
132
|
+
height: 100%;
|
|
133
|
+
opacity: 0.75;
|
|
134
|
+
|
|
135
|
+
background: linear-gradient(
|
|
136
|
+
135deg,
|
|
137
|
+
rgba(255, 255, 255, 0) 0%,
|
|
138
|
+
rgba(255, 255, 255, 0) 40%,
|
|
139
|
+
rgba(255, 255, 255, 0.8) 50%,
|
|
140
|
+
rgba(255, 255, 255, 0) 60%,
|
|
141
|
+
rgba(255, 255, 255, 0) 100%
|
|
142
|
+
);
|
|
143
|
+
|
|
144
|
+
transform: scale(2) translate(-100%, -100%);
|
|
145
|
+
z-index: 3;
|
|
146
|
+
|
|
147
|
+
animation: ai-glint 3s infinite ease-in-out;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
&.ai-available img.loading ~ ::after {
|
|
151
|
+
animation: none;
|
|
152
|
+
display: none;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
&.ai-active::after {
|
|
156
|
+
animation: none;
|
|
157
|
+
display: none;
|
|
119
158
|
}
|
|
120
159
|
|
|
121
160
|
img {
|
|
@@ -132,6 +171,11 @@ export const InputContainer = styled.div`
|
|
|
132
171
|
height: 22.5px;
|
|
133
172
|
}
|
|
134
173
|
|
|
174
|
+
&.ai-active::before {
|
|
175
|
+
background: oklch(57.7% 0.245 27.325);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
|
|
135
179
|
}
|
|
136
180
|
}
|
|
137
181
|
|
|
@@ -144,8 +188,16 @@ export const InputContainer = styled.div`
|
|
|
144
188
|
}
|
|
145
189
|
}
|
|
146
190
|
|
|
147
|
-
|
|
191
|
+
@keyframes ai-glint {
|
|
192
|
+
0% {
|
|
193
|
+
transform: scale(2) translate(-100%, -100%);
|
|
194
|
+
}
|
|
195
|
+
70%, 100% {
|
|
196
|
+
transform: scale(2) translate(100%, 100%);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
148
199
|
|
|
200
|
+
`;
|
|
149
201
|
export const BottomContainer = styled.div`
|
|
150
202
|
|
|
151
203
|
display: flex;
|
|
@@ -13,6 +13,7 @@ import Slide2 from "../../../assets/images/sliderToolTip/slide22.svg";
|
|
|
13
13
|
import Slide3 from "../../../assets/images/sliderToolTip/slide23.svg";
|
|
14
14
|
import { FinancedCompanies } from "./FinancedCompanies";
|
|
15
15
|
import { GlobalColors } from "../../../global-files/variables";
|
|
16
|
+
import { useAiProductEdition } from "../../../contexts/AiProductEdition";
|
|
16
17
|
|
|
17
18
|
export const StatusAsignationInfo = ({
|
|
18
19
|
status = "-",
|
|
@@ -37,6 +38,10 @@ export const StatusAsignationInfo = ({
|
|
|
37
38
|
const [assignationType, setAssignationType] = useState("facilitator");
|
|
38
39
|
const isFinanced = FinancedCompanies.includes(user?.id_company);
|
|
39
40
|
|
|
41
|
+
const {
|
|
42
|
+
inputsUsingAi
|
|
43
|
+
} = useAiProductEdition();
|
|
44
|
+
|
|
40
45
|
const closeAsignations = (e) => {
|
|
41
46
|
if (!e.target.closest("#default-id") && showAsignationPanel) {
|
|
42
47
|
document.removeEventListener("click", closeAsignations, false);
|
|
@@ -93,7 +98,10 @@ export const StatusAsignationInfo = ({
|
|
|
93
98
|
{showSaveButton && !isFinanced && (
|
|
94
99
|
<Button
|
|
95
100
|
buttonType={"circular-button save-button"}
|
|
96
|
-
onClick={
|
|
101
|
+
onClick={() => {
|
|
102
|
+
if(Object.values(inputsUsingAi).some(input => !!input?.using)) return console.warn("Para guardar se debe de dejar de usar la generación con IA");
|
|
103
|
+
onClickSave();
|
|
104
|
+
}}
|
|
97
105
|
/>
|
|
98
106
|
)}
|
|
99
107
|
{imagesSection && (
|