contentoh-components-library 21.5.91 → 21.5.93

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 (66) hide show
  1. package/dist/components/atoms/GeneralButton/styles.js +1 -1
  2. package/dist/components/atoms/GeneralInput/index.js +54 -245
  3. package/dist/components/atoms/GeneralInput/styles.js +3 -7
  4. package/dist/components/atoms/InputFormatter/index.js +68 -223
  5. package/dist/components/atoms/InputFormatter/styles.js +4 -20
  6. package/dist/components/molecules/StatusAsignationInfo/index.js +1 -11
  7. package/dist/components/molecules/TabsMenu/index.js +12 -13
  8. package/dist/components/molecules/TagAndInput/index.js +24 -361
  9. package/dist/components/molecules/TagAndInput/styles.js +2 -2
  10. package/dist/components/organisms/FullProductNameHeader/index.js +22 -6
  11. package/dist/components/organisms/InputGroup/index.js +18 -22
  12. package/dist/components/pages/ProviderProductEdition/index.js +47 -34
  13. package/dist/components/pages/ProviderProductEdition/utils.js +0 -1
  14. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +196 -179
  15. package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.context.js +260 -59
  16. package/dist/components/pages/RetailerProductEdition/context/reducers/product.js +38 -50
  17. package/dist/components/pages/RetailerProductEdition/index.js +2234 -1715
  18. package/dist/components/pages/RetailerProductEdition/styles.js +2 -4
  19. package/dist/components/pages/RetailerProductEdition/utils.js +2 -251
  20. package/dist/contexts/AiProductEdition.js +157 -234
  21. package/package.json +2 -4
  22. package/src/components/atoms/GeneralButton/styles.js +0 -4
  23. package/src/components/atoms/GeneralInput/index.js +60 -237
  24. package/src/components/atoms/GeneralInput/styles.js +0 -81
  25. package/src/components/atoms/InputFormatter/index.js +51 -200
  26. package/src/components/atoms/InputFormatter/styles.js +0 -284
  27. package/src/components/molecules/StatusAsignationInfo/index.js +1 -9
  28. package/src/components/molecules/TabsMenu/index.js +11 -12
  29. package/src/components/molecules/TagAndInput/index.js +21 -286
  30. package/src/components/molecules/TagAndInput/styles.js +17 -59
  31. package/src/components/organisms/FullProductNameHeader/index.js +28 -4
  32. package/src/components/organisms/FullTabsMenu/index.js +1 -1
  33. package/src/components/organisms/InputGroup/index.js +4 -12
  34. package/src/components/pages/ProviderProductEdition/index.js +69 -51
  35. package/src/components/pages/ProviderProductEdition/utils.js +2 -2
  36. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +224 -201
  37. package/src/components/pages/RetailerProductEdition/index.js +1718 -1546
  38. package/src/components/pages/RetailerProductEdition/styles.js +2 -67
  39. package/src/components/pages/RetailerProductEdition/utils.js +0 -240
  40. package/dist/ai/utils/compare-strings.js +0 -45
  41. package/dist/components/organisms/ChangeStatusModal/index.js +0 -531
  42. package/dist/components/organisms/ChangeStatusModal/styles.js +0 -85
  43. package/dist/global-files/statusDictionary.js +0 -103
  44. package/src/ai/utils/compare-strings.js +0 -45
  45. package/src/assets/images/Icons/arrow.png +0 -0
  46. package/src/assets/images/Icons/cancel.png +0 -0
  47. package/src/assets/images/Icons/ia-icon.png +0 -0
  48. package/src/assets/images/Icons/loading.svg +0 -5
  49. package/src/assets/images/Icons/reload.png +0 -0
  50. package/src/components/atoms/RetailerSelector/RetailerSelector.stories.js +0 -10
  51. package/src/components/atoms/RetailerSelector/index.js +0 -3
  52. package/src/components/atoms/RetailerSelector/styles.js +0 -0
  53. package/src/components/organisms/ChangeStatusModal/index.jsx +0 -488
  54. package/src/components/organisms/ChangeStatusModal/styles.js +0 -333
  55. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +0 -575
  56. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +0 -62
  57. package/src/components/pages/RetailerProductEdition/context/reducers/active-state.js +0 -344
  58. package/src/components/pages/RetailerProductEdition/context/reducers/inputs.js +0 -155
  59. package/src/components/pages/RetailerProductEdition/context/reducers/product.js +0 -114
  60. package/src/components/pages/RetailerProductEdition/context/reducers/system.js +0 -60
  61. package/src/components/pages/RetailerProductEdition/index_old.js +0 -1979
  62. package/src/components/pages/RetailerProductEdition/stories/Auditor.stories.js +0 -101
  63. package/src/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +0 -115
  64. package/src/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +0 -174
  65. package/src/contexts/AiProductEdition.jsx +0 -344
  66. package/src/global-files/statusDictionary.js +0 -103
@@ -7,11 +7,6 @@ import rejectIcon from "../../../assets/images/generalButton/rejectIcon.svg";
7
7
  import InfoIcon from "../../../assets/images/sliderToolTip/infoIcon.svg";
8
8
  import { SliderToolTip } from "../../atoms/SliderToolTip";
9
9
  import { Tooltip } from "../../atoms/Tooltip";
10
-
11
- import { useAiProductEdition } from "../../../contexts/AiProductEdition";
12
- import AiGenerationIcon from "../../../assets/images/Icons/ia-icon.png";
13
-
14
-
15
10
  export const TagAndInput = ({
16
11
  inputType,
17
12
  label,
@@ -31,7 +26,6 @@ export const TagAndInput = ({
31
26
  inputRows,
32
27
  maxChar,
33
28
  required,
34
- aiGenerated,
35
29
  optionList,
36
30
  description,
37
31
  inputOnChange,
@@ -49,188 +43,6 @@ export const TagAndInput = ({
49
43
  boxOnboardingData || []
50
44
  );
51
45
 
52
- const {
53
- isCreators,
54
- generateProductSuggestions,
55
- regenerateProductSuggestions,
56
- suggestions,
57
- setSuggestions,
58
- currentSuggestion,
59
- setCurrentSuggestionValue,
60
- isAiAvailable,
61
- inputsGeneratedWithAi,
62
- setInputsGeneratedWithAi,
63
- inputsUsingAi,
64
- setInputsUsingAi
65
- } = useAiProductEdition();
66
-
67
- const isBenefitInput = label?.toLowerCase().includes("beneficios");
68
-
69
- const [isAiGenerationLoading, setIsAiGenerationLoading] = useState(false);
70
- const [isAiActive, setIsAiActive] = useState(false);
71
- const [isAiRegenerationLoading, setIsAiRegenerationLoading] = useState(false);
72
- const [isAiGenerated, setIsAiGenerated] = useState(false);
73
-
74
- const [errorMessage, setErrorMessage] = useState("");
75
-
76
- async function handlerAiGeneration({
77
- type
78
- }) {
79
-
80
- if(isAiGenerationLoading || !isAiAvailable) return;
81
-
82
- if(isAiActive) {
83
- setIsAiActive(false);
84
- return;
85
- }
86
-
87
- //Si ya tiene sugerencias generadas, se las mostramos
88
- const currentSuggestions = suggestions?.[inputId];
89
-
90
- if(Array.isArray(currentSuggestions) && currentSuggestions.length > 0)
91
- return setIsAiActive(true);
92
-
93
- setErrorMessage("");
94
- setIsAiGenerationLoading(true);
95
-
96
- const aiSuggestions = await generateProductSuggestions({
97
- inputName: label,
98
- currentValue: value,
99
- description: description,
100
- maxChar: maxChar ?? 99,
101
- type: type,
102
- // Informacion del producto
103
- articleId: articleId,
104
- versionId: version,
105
- descriptionId: !isBenefitInput ? inputId : null,
106
- attributeId: isBenefitInput ? inputId : null
107
- });
108
-
109
- if(!aiSuggestions && aiSuggestions.length === 0) {
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);
119
- setIsAiGenerationLoading(false);
120
- return;
121
- }
122
-
123
- setSuggestions(prev => ({
124
- ...prev,
125
- [inputId]: aiSuggestions
126
- }));
127
-
128
-
129
- setIsAiActive(true);
130
- setIsAiGenerationLoading(false);
131
-
132
- }
133
-
134
- async function handlerRegenerateSuggestions({
135
- type = "description"
136
- }) {
137
-
138
- if(isAiRegenerationLoading) return;
139
-
140
- setErrorMessage("");
141
- setIsAiRegenerationLoading(true);
142
-
143
- const currentSuggestions = suggestions?.[inputId];
144
-
145
- const aiSuggestions = await regenerateProductSuggestions({
146
- inputName: label,
147
- currentValue: value,
148
- description: description,
149
- maxChar: maxChar ?? 99,
150
- type: type,
151
- //Información del producto
152
- articleId,
153
- versionId: version,
154
- descriptionId: !isBenefitInput ? inputId : null,
155
- attributeId: isBenefitInput ? inputId : null
156
- });
157
-
158
- if(!aiSuggestions && aiSuggestions.length === 0) {
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);
171
- setIsAiRegenerationLoading(false);
172
- return;
173
- }
174
-
175
- setSuggestions(prev => ({
176
- ...prev,
177
- [inputId]: [
178
- ...currentSuggestions,
179
- ...aiSuggestions
180
- ]
181
- }))
182
-
183
- setIsAiRegenerationLoading(false);
184
-
185
- }
186
-
187
- const handleChangeSuggestion = ({
188
- action = "next" // "prev" o "next"
189
- }) => {
190
-
191
- const inputSuggestions = suggestions?.[inputId];
192
-
193
- if(!inputSuggestions || !Array.isArray(inputSuggestions)) return console.log("Error: No existe la sugerencia");
194
-
195
- const currentIndex = currentSuggestion?.[inputId]?.index;
196
-
197
- if(!currentIndex && currentIndex != 0) return console.log("Error: No existe un indice en la sugerencia actual");
198
-
199
- switch(action) {
200
- case "prev":
201
-
202
- if(currentIndex === 0) return;
203
-
204
- const prevIndex = currentIndex - 1;
205
-
206
- setCurrentSuggestionValue({
207
- inputId,
208
- index: prevIndex,
209
- value: inputSuggestions[prevIndex]?.value
210
- })
211
-
212
- break;
213
-
214
- case "next":
215
-
216
- if(currentIndex === inputSuggestions.length - 1) return;
217
-
218
- const nextIndex = currentIndex + 1;
219
-
220
- setCurrentSuggestionValue({
221
- inputId,
222
- index: nextIndex,
223
- value: inputSuggestions[nextIndex]?.value
224
- })
225
-
226
- break;
227
-
228
- default:
229
- break;
230
- }
231
-
232
- }
233
-
234
46
  useEffect(() => {
235
47
  const temp = {};
236
48
  let maxBoxId = 0;
@@ -251,56 +63,10 @@ export const TagAndInput = ({
251
63
  );
252
64
  }
253
65
  }, []);
254
-
255
66
  useEffect(() => {
256
67
  onChange && onChange(boxOnboardingList);
257
68
  }, [boxOnboardingList]);
258
69
 
259
- useEffect(() => {
260
- const currentDescriptionUpdate = Array.isArray(updatedDescriptions)
261
- ? updatedDescriptions.find(desc => desc?.attributeId === inputId)
262
- : null;
263
-
264
- const currentDatasheetUpdate = Array.isArray(updatedDatasheets)
265
- ? updatedDatasheets.find(data => data?.attributeId === inputId)
266
- : null;
267
-
268
- let calculatedIsAiGenerated = aiGenerated;
269
-
270
- if (currentDescriptionUpdate) {
271
- calculatedIsAiGenerated = currentDescriptionUpdate.aiSuggestionAccepted;
272
- } else if (currentDatasheetUpdate) {
273
- calculatedIsAiGenerated = currentDatasheetUpdate.aiSuggestionAccepted;
274
- }
275
-
276
- setInputsGeneratedWithAi(prev => ({
277
- ...prev,
278
- [`${inputId}-${inputType}-${version}`]: {
279
- inputType,
280
- inputId,
281
- version,
282
- isAiGenerated: !!calculatedIsAiGenerated,
283
- label
284
- }
285
- }));
286
-
287
- }, [updatedDescriptions, updatedDatasheets, aiGenerated, inputId]);
288
-
289
- useEffect(() => {
290
- setIsAiGenerated(!!inputsGeneratedWithAi[`${inputId}-${inputType}-${version}`]?.isAiGenerated);
291
- }, [inputsGeneratedWithAi]);
292
-
293
- useEffect(() => {
294
-
295
- setInputsUsingAi(prev => ({
296
- ...prev,
297
- [`${inputId}-${inputType}-${version}`]: {
298
- using: isAiActive
299
- }
300
- }))
301
-
302
- }, [isAiActive])
303
-
304
70
  return (
305
71
  <Container
306
72
  inputType={inputType}
@@ -309,45 +75,28 @@ export const TagAndInput = ({
309
75
  >
310
76
  {label?.length && (
311
77
  <div className="title-container">
312
- <div className="titles">
313
- <ScreenHeader
314
- text={label}
315
- headerType={"input-name-header"}
316
- color={color}
78
+ <ScreenHeader
79
+ text={label}
80
+ headerType={"input-name-header"}
81
+ color={color}
82
+ />
83
+ {description && (
84
+ <Tooltip
85
+ componentTooltip={
86
+ <>
87
+ <p>{description}</p>
88
+ </>
89
+ }
90
+ children={
91
+ <img
92
+ src={InfoIcon}
93
+ alt="info icon"
94
+ className={'icon_information'}
95
+ />
96
+ }
97
+ classNameTooltip={"container-tooltip"}
317
98
  />
318
- {description && (
319
- <Tooltip
320
- componentTooltip={
321
- <>
322
- <p>{description}</p>
323
- </>
324
- }
325
- children={
326
- <img
327
- src={InfoIcon}
328
- alt="info icon"
329
- className={'icon_information'}
330
- />
331
- }
332
- classNameTooltip={"container-tooltip"}
333
- />
334
- )}
335
- </div>
336
- {
337
- isCreators && isAiGenerated ? (
338
- <div className="ai-generated">
339
- <img src={AiGenerationIcon} />
340
- <p>Atributo generado con IA</p>
341
- </div>
342
- ) : null
343
- }
344
- </div>
345
- )}
346
- {errorMessage && (
347
- <div
348
- className="error-message-container"
349
- >
350
- <p>{errorMessage}</p>
99
+ )}
351
100
  </div>
352
101
  )}
353
102
  <GeneralInput
@@ -374,19 +123,6 @@ export const TagAndInput = ({
374
123
  inputOnChange={inputOnChange}
375
124
  onKeyDown={onKeyDown}
376
125
  auditClass={auditClass}
377
- // AI Generation
378
- hasAiGeneration={isCreators}
379
- isBenefitInput={isBenefitInput}
380
- isAiGenerationLoading={isAiGenerationLoading}
381
- isAiRegenerationLoading={isAiRegenerationLoading}
382
- isAiActive={isAiActive}
383
- setIsAiActive={setIsAiActive}
384
- isAiAvailable={isAiAvailable}
385
- aiGenerated={aiGenerated}
386
- // aiSuggestions={aiSuggestions}
387
- handlerAiGeneration={handlerAiGeneration}
388
- handlerRegenerateSuggestions={handlerRegenerateSuggestions}
389
- handleChangeSuggestion={handleChangeSuggestion}
390
126
  onChange={(e) => {
391
127
  setBoxOnboardingList((prev) => {
392
128
  return prev.map((box, i) => {
@@ -397,7 +133,6 @@ export const TagAndInput = ({
397
133
  });
398
134
  });
399
135
  }}
400
-
401
136
  />
402
137
  </Container>
403
138
  );
@@ -7,55 +7,26 @@ export const Container = styled.div`
7
7
 
8
8
  display: flex;
9
9
  align-items: center;
10
- justify-content: space-between;
10
+ gap: .5rem;
11
11
 
12
- font-family: ${FontFamily.Raleway};
13
-
14
- .titles{
15
- display: flex;
16
- gap: .5rem;
17
- align-items: center;
12
+ .icon_information{
13
+ width: 1.35rem;
14
+ height: 1.35rem;
15
+ filter: brightness(.35);
18
16
  }
19
17
 
20
- .icon_information{
21
- width: 1.35rem;
22
- height: 1.35rem;
23
- filter: brightness(.35);
24
- margin-top: 10px;
25
- }
26
-
27
- .tooltip {
28
- display: none;
29
- position: absolute;
30
- background-color: ${GlobalColors.white};
31
- color: ${({ color }) => (color ? color : GlobalColors.s5)};
32
- font-size: 14px;
33
- line-height: 19px;
34
- left: 0;
35
- top: 0;
36
- height: fit-content;
37
- transition: display 2s;
38
- }
39
-
40
- .ai-generated{
41
-
42
- display: flex;
43
- align-items: items-center;
44
- gap: .5rem;
45
- font-size: 11px;
46
- background-color: rgba(224, 57, 167, 0.025);
47
- border: 1px solid rgba(224, 57, 167, 0.1);
48
- padding: .25rem .5rem;
49
- border-radius: 5px;
50
- margin-left: 0.5rem;
51
- margin-top: 7px;
52
- cursor: default;
53
-
54
- > img {
55
- width: 0.75rem;
56
- height: 0.75rem;
57
- }
58
-
18
+ .tooltip {
19
+ display: none;
20
+ position: absolute;
21
+ background-color: ${GlobalColors.white};
22
+ color: ${({ color }) => (color ? color : GlobalColors.s5)};
23
+ font-family: ${FontFamily.Raleway};
24
+ font-size: 14px;
25
+ line-height: 19px;
26
+ left: 0;
27
+ top: 0;
28
+ height: fit-content;
29
+ transition: display 2s;
59
30
  }
60
31
 
61
32
  &:hover {
@@ -63,8 +34,6 @@ export const Container = styled.div`
63
34
  display: block;
64
35
  }
65
36
  }
66
-
67
-
68
37
  }
69
38
 
70
39
  & > :first-child {
@@ -75,15 +44,4 @@ export const Container = styled.div`
75
44
  & + * {
76
45
  margin-top: ${({ inputType }) => (inputType !== "textarea" ? 0 : 10)}px;
77
46
  }
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
- }
89
47
  `;
@@ -27,15 +27,39 @@ export const FullProductNameHeader = ({
27
27
  const [retailerIndex, setRetailerIndex] = useState(null);
28
28
 
29
29
  useEffect(() => {
30
- const ifFromTasks = headerData.statusByRetailer ? true : false;
30
+ // necesitamos definir los retailers que se deberan de mostrar en el selecto de retailers
31
+ // Si se viene desde la vista de productos se deben usar los de categoryRetailer
32
+ // Si se vene desde la vista de tareas entonces se debe trabajar con los retailers que esten en statusByRetailer
33
+
34
+ const ifFromTasks = headerData.statusByRetailer;
31
35
  const categoryRetailer =
32
36
  headerData.categoryRetailer || headerData.article.categoryRetailer;
33
37
 
38
+ const categoryRetailerNormalized = categoryRetailer
39
+ ? categoryRetailer.map((rel) => ({
40
+ id_retailer: rel.id_retailer || rel.retailer_id,
41
+ retailer: rel.retailer_name || rel.retailerName || rel.retailer,
42
+ name: rel.retailer_name || rel.retailerName || rel.retailer,
43
+ id_category: rel.id_category,
44
+ category: rel.category_name || rel.categoryName || rel.category,
45
+ image: `https://content-management-images.s3.amazonaws.com/retailers/${
46
+ rel.id_retailer || rel.retailer_id
47
+ }.png`,
48
+ }))
49
+ : null;
50
+
51
+ const retailersIdsFromStatusByRetailer = Object.keys(
52
+ headerData.statusByRetailer || {}
53
+ ).map((id) => parseInt(id, 10));
54
+
34
55
  if (ifFromTasks) {
35
- setRetailers(headerData.categoryRetailerInOrder);
56
+ const categoryRetailerInOrder = categoryRetailerNormalized.filter((rel) =>
57
+ retailersIdsFromStatusByRetailer.includes(rel.id_retailer)
58
+ );
59
+
60
+ setRetailers(categoryRetailerInOrder);
36
61
  } else {
37
- console.log({ categoryRetailer });
38
- setRetailers(categoryRetailer);
62
+ setRetailers(categoryRetailerNormalized);
39
63
  }
40
64
  }, [servicesData]);
41
65
 
@@ -1,7 +1,7 @@
1
1
  import { Container } from "./styles";
2
2
  import { TabsMenu } from "../../molecules/TabsMenu/index";
3
3
  import { StatusAsignationInfo } from "../../molecules/StatusAsignationInfo/index";
4
- import { useEffect, useState } from "react";
4
+ import { useState } from "react";
5
5
 
6
6
  export const FullTabsMenu = ({
7
7
  tabsSections,
@@ -179,7 +179,7 @@ export const InputGroup = ({
179
179
  ? "inputs-validation-onboarding"
180
180
  : "inputs-validation"
181
181
  }>
182
- {dataInputs[input]?.isApproved === false && (
182
+ {dataInputs[input]?.isApproved === false && (
183
183
  <InputReviewSection
184
184
  inputId={dataInputs[input]?.id}
185
185
  isApproved={dataInputs[input]?.isApproved}
@@ -219,7 +219,6 @@ export const InputGroup = ({
219
219
  inputPlaceHolder={input?.placeholder}
220
220
  articleId={articleId}
221
221
  isRequired={dataInputs[input]?.required}
222
- aiGenerated={dataInputs[input]?.ai_generated}
223
222
  updatedDatasheets={updatedDatasheets}
224
223
  setUpdatedDatasheets={setUpdatedDatasheets}
225
224
  maxChar={
@@ -278,7 +277,6 @@ export const InputGroup = ({
278
277
  : input?.value
279
278
  }
280
279
  isRequired={input.required}
281
- aiGenerated={input?.ai_generated}
282
280
  disabled={input.id===44186||input.id===44187?false:input?.isApproved}
283
281
  maxChar={input.max_chars}
284
282
  inputPlaceHolder={input?.placeholder}
@@ -343,18 +341,13 @@ export const InputGroup = ({
343
341
  (dataInputs[input]?.required ? "*" : "")
344
342
  }
345
343
  value={
346
- dataInputs[input]?.box ? (
347
- Object.values(dataInputs[input]?.box)[0]
348
- ) : (
349
- compare
350
- ? auditInputs[input]?.value
351
- : dataInputs[input]?.value
352
- )
344
+ compare
345
+ ? auditInputs[input]?.value
346
+ : dataInputs[input]?.value
353
347
  }
354
348
  inputPlaceHolder={input?.placeholder}
355
349
  articleId={articleId}
356
350
  isRequired={dataInputs[input]?.required}
357
- aiGenerated={dataInputs[input]?.ai_generated}
358
351
  updatedDatasheets={updatedDatasheets}
359
352
  setUpdatedDatasheets={setUpdatedDatasheets}
360
353
  maxChar={
@@ -416,7 +409,6 @@ export const InputGroup = ({
416
409
  : input?.value
417
410
  }
418
411
  isRequired={input.required}
419
- aiGenerated={input?.ai_generated}
420
412
  maxChar={input.max_chars}
421
413
  inputPlaceHolder={input?.placeholder}
422
414
  updatedDescriptions={updatedDescriptions}