@plusscommunities/pluss-feature-builder-web-a 1.0.2-beta.0

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 (117) hide show
  1. package/.babelrc +4 -0
  2. package/dist/index.cjs.js +7792 -0
  3. package/package.json +54 -0
  4. package/rollup.config.js +68 -0
  5. package/src/actions/featureBuilderStringsActions.js +88 -0
  6. package/src/actions/featureDefinitionsIndex.js +258 -0
  7. package/src/actions/formActions.js +311 -0
  8. package/src/actions/index.js +12 -0
  9. package/src/actions/listingActions.js +350 -0
  10. package/src/actions/wizardActions.js +240 -0
  11. package/src/components/ActivityCardExample.jsx +86 -0
  12. package/src/components/ActivityCardExample.module.css +130 -0
  13. package/src/components/BackgroundLoader.jsx +33 -0
  14. package/src/components/BackgroundLoader.module.css +46 -0
  15. package/src/components/BaseFieldConfig.jsx +305 -0
  16. package/src/components/BaseFieldConfig.module.css +42 -0
  17. package/src/components/CenteredContainer.jsx +29 -0
  18. package/src/components/CenteredContainer.module.css +171 -0
  19. package/src/components/DeleteConfirmationPopup.jsx +95 -0
  20. package/src/components/DeleteConfirmationPopup.module.css +12 -0
  21. package/src/components/ErrorBoundary.jsx +134 -0
  22. package/src/components/ErrorBoundary.module.css +77 -0
  23. package/src/components/ErrorMessage.jsx +85 -0
  24. package/src/components/ErrorMessage.module.css +116 -0
  25. package/src/components/ExampleDisplay.jsx +26 -0
  26. package/src/components/ExampleDisplay.module.css +3 -0
  27. package/src/components/FeatureBuilderSidebar.jsx +84 -0
  28. package/src/components/FeatureBuilderSuccessPopup.jsx +55 -0
  29. package/src/components/FeatureBuilderSuccessPopup.module.css +43 -0
  30. package/src/components/FeatureBuilderWelcomePopup.jsx +51 -0
  31. package/src/components/FeatureBuilderWelcomePopup.module.css +21 -0
  32. package/src/components/FeatureListingCard.jsx +104 -0
  33. package/src/components/FeatureListingCard.module.css +62 -0
  34. package/src/components/Fields.jsx +460 -0
  35. package/src/components/Fields.module.css +159 -0
  36. package/src/components/IconLoader.jsx +153 -0
  37. package/src/components/IconLoader.module.css +92 -0
  38. package/src/components/IconSelector.jsx +112 -0
  39. package/src/components/IconSelector.module.css +197 -0
  40. package/src/components/ListingEditor.jsx +406 -0
  41. package/src/components/ListingEditor.module.css +14 -0
  42. package/src/components/ListingSuccessPopup.jsx +52 -0
  43. package/src/components/LoadingScreen.jsx +54 -0
  44. package/src/components/LoadingScreen.module.css +103 -0
  45. package/src/components/LoadingState.jsx +40 -0
  46. package/src/components/LoadingState.module.css +18 -0
  47. package/src/components/PreviewFull.js +24 -0
  48. package/src/components/PreviewFull.module.css +11 -0
  49. package/src/components/PreviewGrid.js +14 -0
  50. package/src/components/PreviewWidget.js +27 -0
  51. package/src/components/PreviewWidget.module.css +15 -0
  52. package/src/components/SidebarLayout.jsx +292 -0
  53. package/src/components/SidebarLayout.module.css +145 -0
  54. package/src/components/SkeletonLoader.jsx +128 -0
  55. package/src/components/SkeletonLoader.module.css +295 -0
  56. package/src/components/SortButtonGroup.jsx +34 -0
  57. package/src/components/SortButtonGroup.module.css +51 -0
  58. package/src/components/ToastContainer.jsx +98 -0
  59. package/src/components/ToastContainer.module.css +156 -0
  60. package/src/components/ToggleSwitch.js +40 -0
  61. package/src/components/ToggleSwitch.module.css +48 -0
  62. package/src/components/TwoColumnInput.jsx +29 -0
  63. package/src/components/TwoColumnInput.module.css +32 -0
  64. package/src/components/ViewFull.js +139 -0
  65. package/src/components/ViewFull.module.css +71 -0
  66. package/src/components/ViewWidget.js +62 -0
  67. package/src/components/ViewWidget.module.css +28 -0
  68. package/src/components/iconCategories.js +135 -0
  69. package/src/components/iconImports.js +409 -0
  70. package/src/components/index.js +61 -0
  71. package/src/components/listing/FileListItem.jsx +86 -0
  72. package/src/components/listing/GalleryDisplay.jsx +331 -0
  73. package/src/components/listing/GalleryDisplay.module.css +309 -0
  74. package/src/components/listing/ListingCTAInput.jsx +82 -0
  75. package/src/components/listing/ListingDescriptionInput.jsx +73 -0
  76. package/src/components/listing/ListingField.jsx +101 -0
  77. package/src/components/listing/ListingField.module.css +106 -0
  78. package/src/components/listing/ListingFileInput.jsx +255 -0
  79. package/src/components/listing/ListingFileInput.module.css +192 -0
  80. package/src/components/listing/ListingForm.jsx +90 -0
  81. package/src/components/listing/ListingForm.module.css +38 -0
  82. package/src/components/listing/ListingGalleryInput.jsx +236 -0
  83. package/src/components/listing/ListingGalleryInput.module.css +131 -0
  84. package/src/components/listing/ListingImageInput.jsx +153 -0
  85. package/src/components/listing/ListingTextInput.jsx +72 -0
  86. package/src/feature.config.js +130 -0
  87. package/src/helper/index.js +135 -0
  88. package/src/hooks/useFeatureDefinitionLoader.js +62 -0
  89. package/src/images/full.png +0 -0
  90. package/src/images/fullNoTitle.png +0 -0
  91. package/src/images/previewWidget.png +0 -0
  92. package/src/images/widget.png +0 -0
  93. package/src/index.js +38 -0
  94. package/src/pages/CreateListingPage.jsx +49 -0
  95. package/src/pages/EditListingPage.jsx +58 -0
  96. package/src/reducers/featureBuilderReducer.js +744 -0
  97. package/src/screens/CreateListing.module.css +45 -0
  98. package/src/screens/Form.module.css +734 -0
  99. package/src/screens/FormFieldsStep.jsx +689 -0
  100. package/src/screens/FormLayoutStep.jsx +445 -0
  101. package/src/screens/FormOverviewStep.jsx +396 -0
  102. package/src/screens/ListingScreen.jsx +478 -0
  103. package/src/screens/ListingScreen.module.css +333 -0
  104. package/src/selectors/featureBuilderSelectors.js +529 -0
  105. package/src/types/index.js +91 -0
  106. package/src/utils/textUtils.js +89 -0
  107. package/src/validators/galleryValidators.js +345 -0
  108. package/src/values.config.a.js +49 -0
  109. package/src/values.config.b.js +49 -0
  110. package/src/values.config.c.js +49 -0
  111. package/src/values.config.d.js +49 -0
  112. package/src/values.config.js +49 -0
  113. package/src/webapi/featureDefinitionActions.js +0 -0
  114. package/src/webapi/featuresActions.js +90 -0
  115. package/src/webapi/helper.js +4 -0
  116. package/src/webapi/index.js +12 -0
  117. package/src/webapi/listingActions.js +176 -0
@@ -0,0 +1,104 @@
1
+ import React from "react";
2
+ import { ToggleSwitch } from "./ToggleSwitch";
3
+ import { PlussCore } from "../feature.config";
4
+ import styles from "./FeatureListingCard.module.css";
5
+
6
+ const { Text, SVGIcon, Button, MoreMenu } = PlussCore.Components;
7
+
8
+ const FeatureListingCard = ({
9
+ id,
10
+ className,
11
+ style,
12
+ isDeleted,
13
+ icon,
14
+ title,
15
+ description,
16
+ isActive,
17
+ onEdit,
18
+ onDelete,
19
+ onToggle,
20
+ onRestore,
21
+ }) => {
22
+ const getMenuOptions = () => {
23
+ return [
24
+ {
25
+ key: "edit",
26
+ text: "Edit",
27
+ onPress: () => onEdit && onEdit(id),
28
+ },
29
+ {
30
+ key: "delete",
31
+ text: "Delete",
32
+ onPress: () => onDelete && onDelete(id),
33
+ },
34
+ ];
35
+ };
36
+
37
+ const handleToggle = (isActive) => {
38
+ if (onToggle) {
39
+ onToggle(id, isActive);
40
+ }
41
+ };
42
+
43
+ const renderLeftSection = () => {
44
+ return (
45
+ <div className={styles.featureListingCard__leftSection}>
46
+ {icon && (
47
+ <SVGIcon
48
+ icon={icon}
49
+ className={styles.featureListingCard__icon}
50
+ colour="#6c757d"
51
+ />
52
+ )}
53
+ <div className={styles.featureListingCard__content}>
54
+ <Text type="name" className={styles.featureListingCard__title}>
55
+ {title || "Untitled"}
56
+ </Text>
57
+ <Text type="body" className={styles.featureListingCard__description}>
58
+ {description}
59
+ </Text>
60
+ </div>
61
+ </div>
62
+ );
63
+ };
64
+
65
+ const renderRightSection = () => {
66
+ if (isDeleted) {
67
+ return (
68
+ <div className={styles.featureListingCard__rightSection}>
69
+ <Button
70
+ buttonType="success"
71
+ onClick={() => onRestore && onRestore(id)}
72
+ narrow
73
+ >
74
+ Restore
75
+ </Button>
76
+ </div>
77
+ );
78
+ }
79
+
80
+ return (
81
+ <div className={styles.featureListingCard__rightSection}>
82
+ <ToggleSwitch isActive={isActive} onChange={handleToggle} />
83
+ <MoreMenu options={getMenuOptions()} />
84
+ </div>
85
+ );
86
+ };
87
+
88
+ const cardClasses = [
89
+ styles.featureListingCard,
90
+ isDeleted ? styles["featureListingCard--deleted"] : "",
91
+ className,
92
+ ]
93
+ .filter(Boolean)
94
+ .join(" ");
95
+
96
+ return (
97
+ <div key={id} className={cardClasses} style={{ ...style }}>
98
+ {renderLeftSection()}
99
+ {renderRightSection()}
100
+ </div>
101
+ );
102
+ };
103
+
104
+ export { FeatureListingCard };
@@ -0,0 +1,62 @@
1
+ /* FeatureListingCard BEM CSS Module */
2
+
3
+ /* Block */
4
+ .featureListingCard {
5
+ border: 1px solid var(--linegrey);
6
+ background-color: var(--bg-white);
7
+ padding: 16px;
8
+ border-radius: 4px;
9
+ display: flex;
10
+ justify-content: space-between;
11
+ align-items: center;
12
+ margin-bottom: 8px;
13
+ opacity: 1;
14
+ transition: all 0.2s ease;
15
+ }
16
+
17
+ /* Modifiers */
18
+ .featureListingCard--deleted {
19
+ border-color: var(--linegrey);
20
+ background-color: var(--bg-bluegrey);
21
+ opacity: 0.7;
22
+ }
23
+
24
+ .featureListingCard:hover {
25
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
26
+ }
27
+
28
+ /* Elements */
29
+ .featureListingCard__leftSection {
30
+ display: flex;
31
+ align-items: center;
32
+ flex: 1;
33
+ min-width: 0;
34
+ }
35
+
36
+ .featureListingCard__icon {
37
+ width: 40px;
38
+ height: 40px;
39
+ margin-right: 12px;
40
+ flex-shrink: 0;
41
+ color: var(--text-light);
42
+ }
43
+
44
+ .featureListingCard__content {
45
+ flex: 1;
46
+ min-width: 0;
47
+ }
48
+
49
+ .featureListingCard__title {
50
+ margin-bottom: 4px;
51
+ }
52
+
53
+ .featureListingCard__description {
54
+ color: var(--text-light);
55
+ }
56
+
57
+ .featureListingCard__rightSection {
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 12px;
61
+ flex-shrink: 0;
62
+ }
@@ -0,0 +1,460 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
3
+ import { CheckBox, Text, Button } from "./index.js";
4
+ import { BaseFieldConfig } from "./BaseFieldConfig.jsx";
5
+ import { iconImports } from "./iconImports.js";
6
+ import styles from "./Fields.module.css";
7
+
8
+ /**
9
+ * Field component for rendering different field types in feature builder
10
+ * Acts as a factory component that renders the appropriate field component based on type
11
+ * Handles all supported field types with proper props forwarding
12
+ *
13
+ * @typedef {Object} FieldProps
14
+ * @property {string} type - Field type ("title", "text", "description", "image", "gallery", "feature-image", "cta", "file")
15
+ * @property {boolean} isMandatory - Whether field is mandatory/required
16
+ * @property {number} fieldIndex - Index of field in the form
17
+ * @property {string} id - Unique identifier of the field
18
+ * @property {Function} [handleDelete] - Callback function for field deletion
19
+ * @property {Function} [onReplaceField] - Callback function for field replacement
20
+ * @property {Object} [stepErrors] - Validation errors by field ID
21
+ * @property {boolean} [showWarnings] - Whether to show validation warnings
22
+ * @property {Object} values - Field configuration values
23
+ *
24
+ * @param {FieldProps} props - Field component props
25
+ * @returns {React.ReactElement} Rendered field component
26
+ *
27
+ * @example
28
+ * <Field
29
+ * type="text"
30
+ * isMandatory={true}
31
+ * fieldIndex={0}
32
+ * id="field-123"
33
+ * values={{label: "Name", isRequired: true}}
34
+ * />
35
+ */
36
+ export const Field = (props) => {
37
+ const { type, isMandatory } = props;
38
+ let Component;
39
+
40
+ switch (type) {
41
+ case "title":
42
+ Component = TitleField;
43
+ break;
44
+ case "text":
45
+ Component = TextField;
46
+ break;
47
+ case "description":
48
+ Component = DescriptionField;
49
+ break;
50
+ case "image":
51
+ Component = ImageField;
52
+ break;
53
+ case "gallery":
54
+ Component = GalleryField;
55
+ break;
56
+ case "feature-image":
57
+ Component = FeatureImageField;
58
+ break;
59
+
60
+ case "cta":
61
+ Component = CTAField;
62
+ break;
63
+ case "file":
64
+ Component = FileField;
65
+ break;
66
+ default:
67
+ return <Text type="h1">Field {type} not implemented yet</Text>;
68
+ }
69
+
70
+ // Create field content with field header and content
71
+ const fieldContent = (
72
+ <>
73
+ <div className={styles.fieldHeader}>
74
+ <div className={styles.group}>
75
+ <div className={styles.line} />
76
+ <div className={styles.fieldType}>{getFieldTypeDisplay(type)}</div>
77
+ {!isMandatory && (
78
+ <Button
79
+ buttonType="secondary"
80
+ className={styles.changeTypeButton}
81
+ onClick={() => props.onReplaceField && props.onReplaceField()}
82
+ label="Change Type"
83
+ >
84
+ <FontAwesomeIcon icon={iconImports.repeat} />
85
+ <span className={styles.buttonLabel}>Change</span>
86
+ </Button>
87
+ )}
88
+ </div>
89
+ <div className={styles.group}>
90
+ {!isMandatory && (
91
+ <Button
92
+ buttonType="secondary"
93
+ className={styles.deleteButton}
94
+ onClick={props.handleDelete}
95
+ label="Remove Field"
96
+ >
97
+ <FontAwesomeIcon icon={iconImports.trash} />
98
+ <span className={styles.buttonLabel}>Remove</span>
99
+ </Button>
100
+ )}
101
+ {isMandatory && (
102
+ <span className={styles.padlockIcon}>
103
+ <PadlockIcon />
104
+ <p>This field cannot be removed</p>
105
+ </span>
106
+ )}
107
+ </div>
108
+ </div>
109
+ <div className={styles.fieldInner}>
110
+ <Component {...props} />
111
+ </div>
112
+ </>
113
+ );
114
+
115
+ // Both base and custom fields use the same wrapper now with the maintenance styling
116
+ const hasError =
117
+ props.showWarnings && props.stepErrors && props.stepErrors[props.id];
118
+
119
+ return (
120
+ <div className={styles.fieldContainer}>
121
+ <div className={styles.fieldNumberContainer}>
122
+ <p className={styles.fieldNumber}>{props.fieldIndex + 1}</p>
123
+ </div>
124
+ <div
125
+ className={`${styles.field} ${hasError ? styles["field--invalid"] : ""}`}
126
+ >
127
+ {fieldContent}
128
+ </div>
129
+ </div>
130
+ );
131
+ };
132
+
133
+ // Padlock icon component for base fields
134
+ const PadlockIcon = () => {
135
+ const icon = iconImports.lock;
136
+ return (
137
+ <span className={styles.padlockIcon}>
138
+ <FontAwesomeIcon icon={icon} />
139
+ </span>
140
+ );
141
+ };
142
+
143
+ // Field type icon component
144
+ const FieldTypeIcon = ({ type }) => {
145
+ const getIconForType = (type) => {
146
+ switch (type) {
147
+ case "title":
148
+ return iconImports.heading;
149
+ case "text":
150
+ return iconImports.pen;
151
+ case "description":
152
+ return iconImports.alignLeft;
153
+ case "image":
154
+ return iconImports.image;
155
+ case "feature-image":
156
+ return iconImports.camera;
157
+
158
+ case "cta":
159
+ return iconImports.link;
160
+ case "file":
161
+ return iconImports.file;
162
+ default:
163
+ return iconImports.cog;
164
+ }
165
+ };
166
+
167
+ const icon = getIconForType(type);
168
+
169
+ return (
170
+ <span className={styles.fieldTypeIcon}>
171
+ <FontAwesomeIcon icon={icon} />
172
+ </span>
173
+ );
174
+ };
175
+
176
+ // Helper function to get display text for field types
177
+ const getFieldTypeDisplay = (type) => {
178
+ switch (type) {
179
+ case "title":
180
+ return "Title";
181
+ case "text":
182
+ return "Text";
183
+ case "description":
184
+ return "Description";
185
+ case "image":
186
+ return "Image";
187
+ case "gallery":
188
+ return "Gallery";
189
+ case "feature-image":
190
+ return "Feature Image";
191
+
192
+ case "cta":
193
+ return "Action Button";
194
+ case "file":
195
+ return "File";
196
+ default:
197
+ return type;
198
+ }
199
+ };
200
+
201
+ const TitleField = (props) => {
202
+ const {
203
+ setPlaceholder,
204
+ setLabel,
205
+ setHelpText,
206
+ stepErrors,
207
+ showWarnings,
208
+ id,
209
+ } = props;
210
+ const { placeholder, label, isRequired, helpText } = props.values;
211
+
212
+ return (
213
+ <BaseFieldConfig
214
+ label={label}
215
+ placeholder={placeholder}
216
+ helpText={helpText}
217
+ isRequired={true} // Title fields are always required
218
+ setLabel={setLabel}
219
+ setPlaceholder={() => {}}
220
+ setHelpText={setHelpText}
221
+ toggleIsRequired={() => {}} // Disable toggling - title fields are always required
222
+ stepErrors={stepErrors}
223
+ showWarnings={showWarnings}
224
+ id={id}
225
+ fieldType="title"
226
+ id={id} // Fix: pass the field ID
227
+ />
228
+ );
229
+ };
230
+
231
+ const TextField = (props) => {
232
+ const {
233
+ setPlaceholder,
234
+ setLabel,
235
+ setHelpText,
236
+ stepErrors,
237
+ showWarnings,
238
+ id,
239
+ } = props;
240
+ const { placeholder, label, isRequired, helpText } = props.values;
241
+
242
+ return (
243
+ <BaseFieldConfig
244
+ label={label}
245
+ placeholder={placeholder}
246
+ helpText={helpText}
247
+ isRequired={true} // Text fields are always required
248
+ setLabel={setLabel}
249
+ setPlaceholder={() => {}}
250
+ setHelpText={setHelpText}
251
+ toggleIsRequired={() => {}} // Disable toggling - text fields are always required
252
+ stepErrors={stepErrors}
253
+ showWarnings={showWarnings}
254
+ id={id}
255
+ fieldType="text"
256
+ id={id} // Fix: pass the field ID
257
+ />
258
+ );
259
+ };
260
+
261
+ const DescriptionField = (props) => {
262
+ const {
263
+ setPlaceholder,
264
+ toggleIsRequired,
265
+ setLabel,
266
+ setHelpText,
267
+ stepErrors,
268
+ showWarnings,
269
+ setUseAsSummary,
270
+ id, // Get ID from root props
271
+ } = props;
272
+ const { placeholder, label, isRequired, helpText, useAsSummary } =
273
+ props.values;
274
+
275
+ return (
276
+ <BaseFieldConfig
277
+ label={label}
278
+ placeholder={placeholder}
279
+ helpText={helpText}
280
+ isRequired={isRequired}
281
+ setLabel={setLabel}
282
+ setPlaceholder={() => {}}
283
+ setHelpText={setHelpText}
284
+ toggleIsRequired={toggleIsRequired}
285
+ stepErrors={stepErrors}
286
+ showWarnings={showWarnings}
287
+ id={id}
288
+ fieldType="description"
289
+ useAsSummary={useAsSummary}
290
+ setUseAsSummary={setUseAsSummary}
291
+ />
292
+ );
293
+ };
294
+
295
+ const ImageField = (props) => {
296
+ const {
297
+ setLabel,
298
+ setHelpText,
299
+ toggleIsRequired,
300
+ setAllowCaption,
301
+ toggleAllowCaption,
302
+ stepErrors,
303
+ showWarnings,
304
+ id, // Get ID from root props
305
+ } = props;
306
+ const { label, isRequired, placeholder, allowCaption, helpText } =
307
+ props.values;
308
+
309
+ return (
310
+ <BaseFieldConfig
311
+ label={label}
312
+ placeholder={placeholder}
313
+ allowCaption={allowCaption}
314
+ helpText={helpText}
315
+ isRequired={isRequired}
316
+ setLabel={setLabel}
317
+ setPlaceholder={() => {}}
318
+ setAllowCaption={setAllowCaption}
319
+ setHelpText={setHelpText}
320
+ toggleIsRequired={toggleIsRequired}
321
+ toggleAllowCaption={toggleAllowCaption}
322
+ stepErrors={stepErrors}
323
+ showWarnings={showWarnings}
324
+ id={id} // Fix: pass the field ID
325
+ fieldType="image"
326
+ />
327
+ );
328
+ };
329
+
330
+ const FeatureImageField = (props) => {
331
+ const {
332
+ setLabel,
333
+ setHelpText,
334
+ stepErrors,
335
+ showWarnings,
336
+ id, // Get ID from root props
337
+ } = props;
338
+ const { label, placeholder, helpText } = props.values;
339
+
340
+ return (
341
+ <BaseFieldConfig
342
+ label={label}
343
+ placeholder={placeholder}
344
+ helpText={helpText}
345
+ isRequired={true} // Feature image fields are always required
346
+ setLabel={setLabel}
347
+ setPlaceholder={() => {}}
348
+ setHelpText={setHelpText}
349
+ toggleIsRequired={() => {}} // Disable toggling - feature image fields are always required
350
+ stepErrors={stepErrors}
351
+ showWarnings={showWarnings}
352
+ id={id} // Fix: pass the field ID
353
+ fieldType="feature-image"
354
+ customLabel="Label"
355
+ />
356
+ );
357
+ };
358
+
359
+ const GalleryField = (props) => {
360
+ const {
361
+ setLabel,
362
+ setHelpText,
363
+ toggleIsRequired,
364
+ setMinImages,
365
+ setMaxImages,
366
+ setMaxFileSize,
367
+ setAllowedTypes,
368
+ stepErrors,
369
+ showWarnings,
370
+ id, // Get ID from root props
371
+ } = props;
372
+ const {
373
+ label,
374
+ isRequired,
375
+ helpText,
376
+ placeholder,
377
+ minImages,
378
+ maxImages,
379
+ maxFileSize,
380
+ allowedTypes,
381
+ } = props.values;
382
+
383
+ return (
384
+ <BaseFieldConfig
385
+ label={label}
386
+ placeholder={placeholder}
387
+ helpText={helpText}
388
+ isRequired={isRequired}
389
+ minImages={minImages}
390
+ maxImages={maxImages}
391
+ maxFileSize={maxFileSize}
392
+ allowedTypes={allowedTypes}
393
+ setLabel={setLabel}
394
+ showPlaceholder={false}
395
+ setPlaceholder={() => {}}
396
+ setHelpText={setHelpText}
397
+ toggleIsRequired={toggleIsRequired}
398
+ setMinImages={setMinImages}
399
+ setMaxImages={setMaxImages}
400
+ setMaxFileSize={setMaxFileSize}
401
+ setAllowedTypes={setAllowedTypes}
402
+ stepErrors={stepErrors}
403
+ showWarnings={showWarnings}
404
+ id={id}
405
+ fieldType="gallery"
406
+ />
407
+ );
408
+ };
409
+
410
+ const CTAField = (props) => {
411
+ const {
412
+ setLabel,
413
+ toggleIsRequired,
414
+ setHelpText,
415
+ setPlaceholder,
416
+ stepErrors,
417
+ showWarnings,
418
+ } = props;
419
+ const { label, isRequired, helpText, placeholder } = props.values;
420
+ const { id } = props; // Get ID from root props
421
+
422
+ return (
423
+ <BaseFieldConfig
424
+ label={label}
425
+ placeholder={placeholder}
426
+ helpText={helpText}
427
+ isRequired={isRequired}
428
+ setLabel={setLabel}
429
+ setPlaceholder={() => {}}
430
+ setHelpText={setHelpText}
431
+ toggleIsRequired={toggleIsRequired}
432
+ stepErrors={stepErrors}
433
+ showWarnings={showWarnings}
434
+ id={id} // Fix: pass the field ID
435
+ fieldType="cta"
436
+ />
437
+ );
438
+ };
439
+
440
+ const FileField = (props) => {
441
+ const { toggleIsRequired, setLabel, setHelpText, stepErrors, showWarnings } =
442
+ props;
443
+ const { id } = props; // Get ID from root props
444
+ const { label, isRequired, helpText } = props.values;
445
+
446
+ return (
447
+ <BaseFieldConfig
448
+ label={label}
449
+ helpText={helpText}
450
+ isRequired={isRequired}
451
+ setLabel={setLabel}
452
+ setHelpText={setHelpText}
453
+ toggleIsRequired={toggleIsRequired}
454
+ stepErrors={stepErrors}
455
+ showWarnings={showWarnings}
456
+ id={id}
457
+ fieldType="file"
458
+ />
459
+ );
460
+ };