contentoh-components-library 21.5.94 → 21.5.95

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 (70) hide show
  1. package/dist/ai/utils/compare-strings.js +45 -0
  2. package/dist/components/atoms/GeneralButton/styles.js +1 -1
  3. package/dist/components/atoms/GeneralInput/index.js +245 -54
  4. package/dist/components/atoms/GeneralInput/styles.js +7 -3
  5. package/dist/components/atoms/InputFormatter/index.js +223 -68
  6. package/dist/components/atoms/InputFormatter/styles.js +20 -4
  7. package/dist/components/molecules/StatusAsignationInfo/index.js +11 -1
  8. package/dist/components/molecules/TabsMenu/index.js +13 -12
  9. package/dist/components/molecules/TagAndInput/index.js +361 -24
  10. package/dist/components/molecules/TagAndInput/styles.js +2 -2
  11. package/dist/components/organisms/ChangeStatusModal/index.js +531 -0
  12. package/dist/components/organisms/ChangeStatusModal/styles.js +85 -0
  13. package/dist/components/organisms/FullProductNameHeader/index.js +6 -22
  14. package/dist/components/organisms/InputGroup/index.js +22 -18
  15. package/dist/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +150 -337
  16. package/dist/components/pages/ProviderProductEdition/context/provider-product-edition.context.js +15 -15
  17. package/dist/components/pages/ProviderProductEdition/index.js +413 -396
  18. package/dist/components/pages/ProviderProductEdition/utils.js +1 -0
  19. package/dist/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +179 -196
  20. package/dist/components/pages/RetailerProductEdition/context/provider-product-edition.context.js +59 -260
  21. package/dist/components/pages/RetailerProductEdition/context/reducers/product.js +50 -38
  22. package/dist/components/pages/RetailerProductEdition/index.js +1719 -2237
  23. package/dist/components/pages/RetailerProductEdition/styles.js +4 -2
  24. package/dist/components/pages/RetailerProductEdition/utils.js +251 -2
  25. package/dist/contexts/AiProductEdition.js +230 -158
  26. package/dist/global-files/statusDictionary.js +103 -0
  27. package/package.json +4 -2
  28. package/src/ai/utils/compare-strings.js +45 -0
  29. package/src/assets/images/Icons/arrow.png +0 -0
  30. package/src/assets/images/Icons/cancel.png +0 -0
  31. package/src/assets/images/Icons/ia-icon.png +0 -0
  32. package/src/assets/images/Icons/loading.svg +5 -0
  33. package/src/assets/images/Icons/reload.png +0 -0
  34. package/src/components/atoms/GeneralButton/styles.js +4 -0
  35. package/src/components/atoms/GeneralInput/index.js +237 -60
  36. package/src/components/atoms/GeneralInput/styles.js +81 -0
  37. package/src/components/atoms/InputFormatter/index.js +200 -51
  38. package/src/components/atoms/InputFormatter/styles.js +284 -0
  39. package/src/components/atoms/RetailerSelector/RetailerSelector.stories.js +10 -0
  40. package/src/components/atoms/RetailerSelector/index.js +3 -0
  41. package/src/components/atoms/RetailerSelector/styles.js +0 -0
  42. package/src/components/molecules/StatusAsignationInfo/index.js +9 -1
  43. package/src/components/molecules/TabsMenu/index.js +12 -11
  44. package/src/components/molecules/TagAndInput/index.js +286 -21
  45. package/src/components/molecules/TagAndInput/styles.js +59 -17
  46. package/src/components/organisms/ChangeStatusModal/index.jsx +488 -0
  47. package/src/components/organisms/ChangeStatusModal/styles.js +333 -0
  48. package/src/components/organisms/FullProductNameHeader/index.js +4 -28
  49. package/src/components/organisms/FullTabsMenu/index.js +1 -1
  50. package/src/components/organisms/InputGroup/index.js +12 -4
  51. package/src/components/pages/ProviderProductEdition/ProviderProductEdition.stories.js +174 -202
  52. package/src/components/pages/ProviderProductEdition/context/provider-product-edition.context.jsx +14 -14
  53. package/src/components/pages/ProviderProductEdition/index.js +496 -475
  54. package/src/components/pages/ProviderProductEdition/utils.js +2 -2
  55. package/src/components/pages/RetailerProductEdition/RetailerProductEdition.stories.js +201 -224
  56. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.context.jsx +575 -0
  57. package/src/components/pages/RetailerProductEdition/context/provider-product-edition.reducer.js +62 -0
  58. package/src/components/pages/RetailerProductEdition/context/reducers/active-state.js +344 -0
  59. package/src/components/pages/RetailerProductEdition/context/reducers/inputs.js +155 -0
  60. package/src/components/pages/RetailerProductEdition/context/reducers/product.js +114 -0
  61. package/src/components/pages/RetailerProductEdition/context/reducers/system.js +60 -0
  62. package/src/components/pages/RetailerProductEdition/index.js +1545 -1718
  63. package/src/components/pages/RetailerProductEdition/index_old.js +1979 -0
  64. package/src/components/pages/RetailerProductEdition/stories/Auditor.stories.js +101 -0
  65. package/src/components/pages/RetailerProductEdition/stories/ImageEditor.stories.js +115 -0
  66. package/src/components/pages/RetailerProductEdition/stories/TextEditor.stories.js +174 -0
  67. package/src/components/pages/RetailerProductEdition/styles.js +67 -2
  68. package/src/components/pages/RetailerProductEdition/utils.js +240 -0
  69. package/src/contexts/AiProductEdition.jsx +339 -0
  70. package/src/global-files/statusDictionary.js +103 -0
@@ -0,0 +1,344 @@
1
+ export const activeStateInitialState = {
2
+ active_retailer: null,
3
+ active_percentage: null,
4
+ active_tab: "Descripción",
5
+ comments: {},
6
+ comment: null,
7
+ collaborator_assignations: {},
8
+ selected_images: [],
9
+ all_image_checked: false,
10
+ images_values: null,
11
+ datasheets_inputs: null,
12
+ descriptions_inputs: null,
13
+ current_image: 0,
14
+ current_percentage: 0,
15
+ missing_required_fields: {
16
+ "Ficha técnica": 0,
17
+ Descripción: 0,
18
+ Imágenes: 0,
19
+ },
20
+ };
21
+
22
+ export const ACTIVE_STATE_ACTIONS = {
23
+ SET_ACTIVE_RETAILER: "SET_ACTIVE_RETAILER",
24
+ SET_ACTIVE_PERCENTAGES: "SET_ACTIVE_PERCENTAGES",
25
+ SET_ACTIVE_TAB: "SET_ACTIVE_TAB",
26
+ SET_COMMENTS: "SET_COMMENTS",
27
+ SET_COMMENT: "SET_COMMENT",
28
+ SET_COLLABORATOR_ASSIGNATIONS: "SET_COLLABORATOR_ASSIGNATIONS",
29
+ SET_CURRENT_IMAGE: "SET_CURRENT_IMAGE",
30
+ SET_SELECTED_IMAGE: "SET_SELECTED_IMAGE",
31
+ SET_DATASHEETS_INPUTS: "SET_DATASHEETS_INPUTS",
32
+ SET_DESCRIPTIONS_INPUTS: "SET_DESCRIPTIONS_INPUTS",
33
+ SET_IMAGES_VALUES: "SET_IMAGES_VALUES",
34
+ ADD_IMAGE_VALUE: "ADD_IMAGE_VALUE",
35
+ UPDATE_IMAGE_VALUE: "UPDATE_IMAGE_VALUE",
36
+ DELETE_IMAGES: "DELETE_IMAGES",
37
+ TOGGLE_CHECK_ALL_IMAGES: "TOGGLE_CHECK_ALL_IMAGES",
38
+ TOGGLE_CHECKBOX_IMAGE: "TOGGLE_CHECKBOX_IMAGE",
39
+ SET_MISSING_REQUIRED_FIELDS: "SET_MISSING_REQUIRED_FIELDS",
40
+ CHANGE_ATTR_VALUE: "CHANGE_ATTR_VALUE",
41
+ };
42
+
43
+ export const activeStateReducer = (state, action) => {
44
+ switch (action.type) {
45
+ case ACTIVE_STATE_ACTIONS.SET_ACTIVE_RETAILER: {
46
+ return {
47
+ ...state,
48
+ active_retailer: action.payload,
49
+ };
50
+ }
51
+
52
+ case ACTIVE_STATE_ACTIONS.SET_ACTIVE_PERCENTAGES: {
53
+ return {
54
+ ...state,
55
+ active_percentage: action.payload,
56
+ };
57
+ }
58
+
59
+ case ACTIVE_STATE_ACTIONS.SET_ACTIVE_TAB: {
60
+ return {
61
+ ...state,
62
+ active_tab: action.payload,
63
+ comment: state.comments[action.payload] || null,
64
+ };
65
+ }
66
+
67
+ case ACTIVE_STATE_ACTIONS.SET_COMMENTS: {
68
+ return {
69
+ ...state,
70
+ comments: action.payload,
71
+ comment: action.payload[state.active_tab] || null,
72
+ };
73
+ }
74
+
75
+ case ACTIVE_STATE_ACTIONS.SET_COMMENT: {
76
+ return {
77
+ ...state,
78
+ comment: action.payload,
79
+ };
80
+ }
81
+
82
+ case ACTIVE_STATE_ACTIONS.SET_COLLABORATOR_ASSIGNATIONS: {
83
+ return {
84
+ ...state,
85
+ collaborator_assignations: action.payload,
86
+ };
87
+ }
88
+
89
+ case ACTIVE_STATE_ACTIONS.SET_CURRENT_IMAGE: {
90
+ return {
91
+ ...state,
92
+ current_image: action.payload,
93
+ };
94
+ }
95
+
96
+ case ACTIVE_STATE_ACTIONS.SET_SELECTED_IMAGE: {
97
+ return {
98
+ ...state,
99
+ selected_images: action.payload,
100
+ };
101
+ }
102
+
103
+ case ACTIVE_STATE_ACTIONS.SET_DATASHEETS_INPUTS: {
104
+ return {
105
+ ...state,
106
+ datasheets_inputs: action.payload,
107
+ };
108
+ }
109
+
110
+ case ACTIVE_STATE_ACTIONS.SET_DESCRIPTIONS_INPUTS: {
111
+ return {
112
+ ...state,
113
+ descriptions_inputs: action.payload,
114
+ };
115
+ }
116
+
117
+ case ACTIVE_STATE_ACTIONS.SET_IMAGES_VALUES: {
118
+ return {
119
+ ...state,
120
+ images_values: action.payload,
121
+ };
122
+ }
123
+
124
+ case ACTIVE_STATE_ACTIONS.ADD_IMAGE_VALUE: {
125
+ return {
126
+ ...state,
127
+ images_values: {
128
+ ...state.images_values,
129
+ values: [...state.images_values.values, action.payload],
130
+ },
131
+ };
132
+ }
133
+
134
+ case ACTIVE_STATE_ACTIONS.UPDATE_IMAGE_VALUE: {
135
+ const { index, attribute, value } = action.payload;
136
+
137
+ // Paso 1. Crear una copia del array de valores de imágenes
138
+ const updatedValues = [...state.images_values.values];
139
+
140
+ // Paso 2. Buscar la imagen por su index
141
+ const imageToUpdate = updatedValues[index];
142
+
143
+ // Paso 3. Buscar si ya existe dentro de updated_images_values
144
+ const existingUpdatedIndex = state.updated_images_values.findIndex(
145
+ (img) => img.id === imageToUpdate.id,
146
+ );
147
+
148
+ // Paso 4. Actualizar el valor en images_values
149
+ const newImageValues = updatedValues.map((img, i) =>
150
+ i === index
151
+ ? {
152
+ ...img,
153
+ [attribute]: value,
154
+ ...(attribute === "image_id" && { imageID: value }),
155
+ }
156
+ : img,
157
+ );
158
+
159
+ // Paso 5. Actualizar updated_images_values
160
+ let newUpdatedImagesValues;
161
+ if (existingUpdatedIndex === -1) {
162
+ const {
163
+ status,
164
+ image_shot_type,
165
+ onb_comentarios,
166
+ onb_estatus,
167
+ scene_type,
168
+ ...rest
169
+ } = imageToUpdate;
170
+
171
+ // Si no existe, agregarlo a updated_images_values con el valor original
172
+ newUpdatedImagesValues = [
173
+ ...state.updated_images_values,
174
+ {
175
+ ...rest,
176
+ originalValue: imageToUpdate[attribute],
177
+ newValue: value,
178
+ [attribute]: value,
179
+ },
180
+ ];
181
+ } else {
182
+ // Si existe, actualizar su newValue
183
+ newUpdatedImagesValues = state.updated_images_values.map((img, i) =>
184
+ i === existingUpdatedIndex ? { ...img, newValue: value } : img,
185
+ );
186
+
187
+ // Verificar si el nuevo valor es igual al valor original
188
+ // Normalizar valores booleanos (0/1 a true/false) para comparación correcta
189
+ const originalValue =
190
+ newUpdatedImagesValues[existingUpdatedIndex].originalValue;
191
+ const normalizedOriginal =
192
+ typeof originalValue === "number" &&
193
+ (originalValue === 0 || originalValue === 1)
194
+ ? Boolean(originalValue)
195
+ : originalValue;
196
+ const normalizedNew =
197
+ typeof value === "number" && (value === 0 || value === 1)
198
+ ? Boolean(value)
199
+ : value;
200
+
201
+ const isOriginalValue = normalizedOriginal === normalizedNew;
202
+
203
+ // Si el nuevo valor es igual al original, eliminar la imagen de updated_images_values
204
+ if (isOriginalValue) {
205
+ newUpdatedImagesValues = state.updated_images_values.filter(
206
+ (_, i) => i !== existingUpdatedIndex,
207
+ );
208
+ }
209
+ }
210
+
211
+ return {
212
+ ...state,
213
+ images_values: {
214
+ ...state.images_values,
215
+ values: newImageValues,
216
+ },
217
+ updated_images_values: newUpdatedImagesValues,
218
+ };
219
+ }
220
+
221
+ case ACTIVE_STATE_ACTIONS.DELETE_IMAGES: {
222
+ const { selectedImages } = action.payload;
223
+
224
+ // Filtrar las imágenes que no están seleccionadas
225
+ const remainingImages = state.images_values.values.filter((image) => {
226
+ // Comparar por image_id o id dependiendo de cuál exista
227
+ const imageIdentifier = image.image_id || image.id;
228
+ return !selectedImages.some((selected) => {
229
+ const selectedIdentifier = selected.image_id || selected.id;
230
+ return imageIdentifier === selectedIdentifier;
231
+ });
232
+ });
233
+
234
+ // También actualizar services.images.values
235
+ const remainingServicesImages = state.services.images.values.filter(
236
+ (image) => {
237
+ const imageIdentifier = image.image_id || image.id;
238
+ return !selectedImages.some((selected) => {
239
+ const selectedIdentifier = selected.image_id || selected.id;
240
+ return imageIdentifier === selectedIdentifier;
241
+ });
242
+ },
243
+ );
244
+
245
+ return {
246
+ ...state,
247
+ images_values: {
248
+ ...state.images_values,
249
+ values: remainingImages,
250
+ },
251
+ services: {
252
+ ...state.services,
253
+ images: {
254
+ ...state.services.images,
255
+ values: remainingServicesImages,
256
+ },
257
+ },
258
+ selected_images: [],
259
+ all_image_checked: false,
260
+ };
261
+ }
262
+
263
+ case ACTIVE_STATE_ACTIONS.TOGGLE_CHECK_ALL_IMAGES: {
264
+ const isChecked = action.payload;
265
+
266
+ return {
267
+ ...state,
268
+ selected_images: isChecked ? [...state.images_values.values] : [],
269
+ };
270
+ }
271
+
272
+ case ACTIVE_STATE_ACTIONS.TOGGLE_CHECKBOX_IMAGE: {
273
+ return {
274
+ ...state,
275
+ all_image_checked: action.payload,
276
+ };
277
+ }
278
+
279
+ case ACTIVE_STATE_ACTIONS.SET_MISSING_REQUIRED_FIELDS: {
280
+ return {
281
+ ...state,
282
+ missing_required_fields: action.payload,
283
+ };
284
+ }
285
+
286
+ case ACTIVE_STATE_ACTIONS.CHANGE_ATTR_VALUE: {
287
+ const { id, value } = action.payload;
288
+ const attrForImgs = state.images_values?.attrForImgs;
289
+
290
+ if (!attrForImgs?.general) return state;
291
+
292
+ const attrIndex = attrForImgs.general.findIndex((f) => f.id === id);
293
+ if (attrIndex === -1) return state;
294
+
295
+ const originalAttr = attrForImgs.general[attrIndex];
296
+
297
+ const updatedGeneral = attrForImgs.general.map((attr, i) =>
298
+ i === attrIndex ? { ...attr, value } : attr,
299
+ );
300
+
301
+ // Tracking de cambios en updated_attr_for_imgs
302
+ const existingIndex = state.updated_attr_for_imgs.findIndex(
303
+ (attr) => attr.attrId === id,
304
+ );
305
+
306
+ let newUpdatedAttrForImgs;
307
+ if (existingIndex === -1) {
308
+ // Agregar nuevo cambio con valor original
309
+ newUpdatedAttrForImgs = [
310
+ ...state.updated_attr_for_imgs,
311
+ { attrId: id, value, originalValue: originalAttr.value },
312
+ ];
313
+ } else {
314
+ // Actualizar valor existente
315
+ const updated = state.updated_attr_for_imgs.map((attr, i) =>
316
+ i === existingIndex ? { ...attr, value } : attr,
317
+ );
318
+ // Si el valor vuelve al original, eliminarlo del tracking
319
+ const originalValue = updated[existingIndex].originalValue;
320
+ if (String(value) === String(originalValue)) {
321
+ newUpdatedAttrForImgs = updated.filter((_, i) => i !== existingIndex);
322
+ } else {
323
+ newUpdatedAttrForImgs = updated;
324
+ }
325
+ }
326
+
327
+ return {
328
+ ...state,
329
+ images_values: {
330
+ ...state.images_values,
331
+ attrForImgs: {
332
+ ...attrForImgs,
333
+ general: updatedGeneral,
334
+ },
335
+ },
336
+ updated_attr_for_imgs: newUpdatedAttrForImgs,
337
+ };
338
+ }
339
+
340
+ default: {
341
+ return null;
342
+ }
343
+ }
344
+ };
@@ -0,0 +1,155 @@
1
+ export const inputsInitialState = {
2
+ updated_datasheets_inputs: [],
3
+ updated_descriptions_inputs: [],
4
+ updated_images_values: [],
5
+ updated_attr_for_imgs: [],
6
+ };
7
+
8
+ export const INPUTS_ACTIONS = {
9
+ SET_UPDATED_DATASHEETS_INPUTS: "SET_UPDATED_DATASHEETS_INPUTS",
10
+ SET_UPDATED_DESCRIPTIONS_INPUTS: "SET_UPDATED_DESCRIPTIONS_INPUTS",
11
+ SET_UPDATED_IMAGES_VALUES: "SET_UPDATED_IMAGES_VALUES",
12
+ SET_UPDATED_ATTR_FOR_IMGS: "SET_UPDATED_ATTR_FOR_IMGS",
13
+ UPDATE_DESCRIPTIONS_INPUTS: "UPDATE_DESCRIPTIONS_INPUTS",
14
+ UPDATE_DATASHEETS_INPUTS: "UPDATE_DATASHEETS_INPUTS",
15
+ };
16
+
17
+ export const inputsReducer = (state, action) => {
18
+ switch (action.type) {
19
+ case INPUTS_ACTIONS.SET_UPDATED_DESCRIPTIONS_INPUTS: {
20
+ return {
21
+ ...state,
22
+ updated_descriptions_inputs: action.payload,
23
+ };
24
+ }
25
+
26
+ case INPUTS_ACTIONS.SET_UPDATED_DATASHEETS_INPUTS: {
27
+ return {
28
+ ...state,
29
+ updated_datasheets_inputs: action.payload,
30
+ };
31
+ }
32
+
33
+ case INPUTS_ACTIONS.SET_UPDATED_IMAGES_VALUES: {
34
+ return {
35
+ ...state,
36
+ updated_images_values: action.payload,
37
+ };
38
+ }
39
+
40
+ case INPUTS_ACTIONS.SET_UPDATED_ATTR_FOR_IMGS: {
41
+ return {
42
+ ...state,
43
+ updated_attr_for_imgs: action.payload,
44
+ };
45
+ }
46
+
47
+ case INPUTS_ACTIONS.UPDATE_DESCRIPTIONS_INPUTS: {
48
+ // Validar que la posicion [0] de descriptions_inputs corresponda al retailer actual
49
+ const retailerId = state.active_retailer.id_retailer;
50
+ if (state.descriptions_inputs[0]?.id !== retailerId) {
51
+ console.warn(
52
+ `Warning: The first element's retailer ID (${state.descriptions_inputs[0]?.id_retailer}) does not match the active retailer ID (${retailerId}). Update aborted.`
53
+ );
54
+ return state;
55
+ }
56
+
57
+ // action.payload es un array de los inputs que se van a actualizar
58
+ // debemos de recorrer descriptions_inputs y actualizar solo el value de los que vienen en el payload
59
+ const updatedDescriptionsInputs = state.descriptions_inputs[0].inputs.map(
60
+ (input) => {
61
+ const updatedInput = action.payload.find(
62
+ (updated) => updated.attributeId === input.id
63
+ );
64
+ return updatedInput ? { ...input, value: updatedInput.value } : input;
65
+ }
66
+ );
67
+
68
+ // Tambien actualizarlo dentro de services.descriptions
69
+ // buscar el index del retailer activo en services
70
+ const retailerIndex = state.services.descriptions.findIndex(
71
+ (retailer) => retailer.id === retailerId
72
+ );
73
+
74
+ return {
75
+ ...state,
76
+ descriptions_inputs: [
77
+ {
78
+ ...state.descriptions_inputs[0],
79
+ inputs: updatedDescriptionsInputs,
80
+ },
81
+ ],
82
+ services: {
83
+ ...state.services,
84
+ descriptions: state.services.descriptions.map((retailer, index) =>
85
+ index === retailerIndex
86
+ ? {
87
+ ...retailer,
88
+ inputs: updatedDescriptionsInputs,
89
+ }
90
+ : retailer
91
+ ),
92
+ },
93
+ };
94
+ }
95
+
96
+ case INPUTS_ACTIONS.UPDATE_DATASHEETS_INPUTS: {
97
+ const retailerId = state.active_retailer.id_retailer;
98
+
99
+ /* ---------- 1. Actualizar services.datasheets.inputs ---------- */
100
+ const updatedServiceInputs = {
101
+ ...state.services.datasheets.inputs,
102
+ };
103
+
104
+ action.payload.forEach(({ attributeId, value }) => {
105
+ const key = `${attributeId}_${retailerId}`;
106
+
107
+ if (!updatedServiceInputs[key]) return;
108
+
109
+ updatedServiceInputs[key] = {
110
+ ...updatedServiceInputs[key],
111
+ value,
112
+ };
113
+ });
114
+
115
+ /* ---------- 2. Actualizar datasheets_inputs ---------- */
116
+ const updatedDatasheetsInputs = state.datasheets_inputs.map(
117
+ (group, index) => {
118
+ if (index !== 1) return group;
119
+
120
+ return {
121
+ ...group,
122
+ ...action.payload.reduce((acc, { attributeId, value }) => {
123
+ const key = `${attributeId}_${retailerId}`;
124
+
125
+ if (!group[key]) return acc;
126
+
127
+ acc[key] = {
128
+ ...group[key],
129
+ value,
130
+ };
131
+
132
+ return acc;
133
+ }, {}),
134
+ };
135
+ }
136
+ );
137
+
138
+ return {
139
+ ...state,
140
+ datasheets_inputs: updatedDatasheetsInputs,
141
+ services: {
142
+ ...state.services,
143
+ datasheets: {
144
+ ...state.services.datasheets,
145
+ inputs: updatedServiceInputs,
146
+ },
147
+ },
148
+ };
149
+ }
150
+
151
+ default: {
152
+ return null;
153
+ }
154
+ }
155
+ };
@@ -0,0 +1,114 @@
1
+ import { STATUS_DICTIONARY } from "../../../../../global-files/statusDictionary";
2
+
3
+ export const productInitialState = {
4
+ product: null,
5
+ services: null,
6
+ services_data: null,
7
+ };
8
+
9
+ export const PRODUCT_ACTIONS = {
10
+ SET_PRODUCT: "SET_PRODUCT",
11
+ SET_SERVICES: "SET_SERVICES",
12
+ SET_SERVICES_DATA: "SET_SERVICES_DATA",
13
+ SET_PRODUCT_VERSION: "SET_PRODUCT_VERSION",
14
+ SET_PERCENTAGES: "SET_PERCENTAGES",
15
+ SET_RETAILER_STATUS: "SET_RETAILER_STATUS",
16
+ };
17
+
18
+ export const productReducer = (state, action) => {
19
+ switch (action.type) {
20
+ case PRODUCT_ACTIONS.SET_PRODUCT: {
21
+ return {
22
+ ...state,
23
+ product: action.payload,
24
+ };
25
+ }
26
+
27
+ case PRODUCT_ACTIONS.SET_SERVICES: {
28
+ return {
29
+ ...state,
30
+ services: action.payload,
31
+ };
32
+ }
33
+
34
+ case PRODUCT_ACTIONS.SET_RETAILER_STATUS: {
35
+ return {
36
+ ...state,
37
+ product: {
38
+ ...state.product,
39
+ status: getMinorStatus(
40
+ action.payload.map((status) => status?.status),
41
+ ),
42
+ description_status:
43
+ action.payload.find(
44
+ (status) =>
45
+ status?.service === "description" &&
46
+ status?.retailer_id === state?.active_retailer?.id_retailer,
47
+ )?.status || "NS",
48
+ datasheet_status:
49
+ action.payload.find(
50
+ (status) =>
51
+ status?.service === "datasheet" &&
52
+ status?.retailer_id === state?.active_retailer?.id_retailer,
53
+ )?.status || "NS",
54
+ images_status:
55
+ action.payload.find(
56
+ (status) =>
57
+ status?.service === "images" &&
58
+ status?.retailer_id === state?.active_retailer?.id_retailer,
59
+ )?.status || "NS",
60
+ statusByRetailer: action.payload,
61
+ },
62
+ };
63
+ }
64
+
65
+ case PRODUCT_ACTIONS.SET_SERVICES_DATA: {
66
+ return {
67
+ ...state,
68
+ services_data: action.payload,
69
+ };
70
+ }
71
+
72
+ case PRODUCT_ACTIONS.SET_PRODUCT_VERSION: {
73
+ return {
74
+ ...state,
75
+ product: {
76
+ ...state.product,
77
+ version: action.payload,
78
+ },
79
+ };
80
+ }
81
+
82
+ case PRODUCT_ACTIONS.SET_PERCENTAGES: {
83
+ return {
84
+ ...state,
85
+ product: { ...state.product, percentages: action.payload },
86
+ };
87
+ }
88
+
89
+ default: {
90
+ return null;
91
+ }
92
+ }
93
+ };
94
+
95
+ function getMinorStatus(servicesStatus = []) {
96
+ if (!servicesStatus || servicesStatus.length === 0)
97
+ return STATUS_DICTIONARY.NS.name;
98
+
99
+ console.log({ servicesStatus });
100
+
101
+ const winner = servicesStatus.reduce((minor, current) => {
102
+ const currentObj =
103
+ typeof current === "string" ? STATUS_DICTIONARY[current] : current;
104
+ const minorObj =
105
+ typeof minor === "string" ? STATUS_DICTIONARY[minor] : minor;
106
+
107
+ if (!currentObj || typeof currentObj.weight === "undefined") return minor;
108
+ if (!minorObj || typeof minorObj.weight === "undefined") return current;
109
+
110
+ return currentObj.weight < minorObj.weight ? currentObj : minorObj;
111
+ }, servicesStatus[0] || STATUS_DICTIONARY.NS);
112
+
113
+ return winner?.status || STATUS_DICTIONARY.NS?.status;
114
+ }
@@ -0,0 +1,60 @@
1
+ export const systemInitialState = {
2
+ loading: false,
3
+ saving: false,
4
+ errors: [],
5
+ modal: {
6
+ show: false,
7
+ title: "",
8
+ message: "",
9
+ image: null,
10
+ buttons: [],
11
+ },
12
+ };
13
+
14
+ export const SYSTEM_ACTIONS = {
15
+ SET_ERRORS: "SET_ERRORS",
16
+ SET_LOADING: "SET_LOADING",
17
+ SET_SAVING: "SET_SAVING",
18
+ SET_MODAL: "SET_MODAL",
19
+ RESET: "RESET",
20
+ };
21
+
22
+ export const systemReducer = (state, action, initialState) => {
23
+ switch (action.type) {
24
+ case SYSTEM_ACTIONS.SET_ERRORS: {
25
+ return {
26
+ ...state,
27
+ errors: action.payload,
28
+ };
29
+ }
30
+
31
+ case SYSTEM_ACTIONS.SET_LOADING: {
32
+ return {
33
+ ...state,
34
+ loading: action.payload,
35
+ };
36
+ }
37
+
38
+ case SYSTEM_ACTIONS.SET_SAVING: {
39
+ return {
40
+ ...state,
41
+ saving: action.payload,
42
+ };
43
+ }
44
+
45
+ case SYSTEM_ACTIONS.SET_MODAL: {
46
+ return {
47
+ ...state,
48
+ modal: action.payload,
49
+ };
50
+ }
51
+
52
+ case SYSTEM_ACTIONS.RESET: {
53
+ return initialState;
54
+ }
55
+
56
+ default: {
57
+ return null;
58
+ }
59
+ }
60
+ };