@licklist/design 0.66.10-dev.0 → 0.66.10-dev.4

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/auth/Login/LoginComponent.js +2 -1
  2. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.js +7 -2
  3. package/dist/events/edit-event-modal/utils/getDefaultProductSet.d.ts.map +1 -1
  4. package/dist/events/edit-event-modal/utils/getDefaultProductSet.js +22 -9
  5. package/dist/layout/DropDown.d.ts +2 -1
  6. package/dist/layout/DropDown.d.ts.map +1 -1
  7. package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
  8. package/dist/product-set/control/ProductSetControl.js +3 -3
  9. package/dist/product-set/form/ProductCategoriesControl.d.ts.map +1 -1
  10. package/dist/product-set/form/ProductCategoriesControl.js +1 -3
  11. package/dist/product-set/form/ProductZonesControl.d.ts +9 -0
  12. package/dist/product-set/form/ProductZonesControl.d.ts.map +1 -0
  13. package/dist/product-set/form/ProductZonesControl.js +214 -0
  14. package/dist/product-set/form/ProductsControl.d.ts +1 -3
  15. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  16. package/dist/product-set/form/ProductsControl.js +2 -13
  17. package/dist/product-set/product/ProductControl.d.ts +5 -8
  18. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  19. package/dist/product-set/product/ProductControl.js +19 -301
  20. package/dist/product-set/product/advanced-options/AdvancedOptions.d.ts +8 -0
  21. package/dist/product-set/product/advanced-options/AdvancedOptions.d.ts.map +1 -0
  22. package/dist/product-set/product/advanced-options/AdvancedOptions.js +264 -0
  23. package/dist/product-set/product/advanced-options/index.d.ts +2 -0
  24. package/dist/product-set/product/advanced-options/index.d.ts.map +1 -0
  25. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.js +1 -0
  26. package/dist/product-set/product-category/ProductCategoryControl.d.ts +0 -2
  27. package/dist/product-set/product-category/ProductCategoryControl.d.ts.map +1 -1
  28. package/dist/product-set/product-category/ProductCategoryControl.js +2 -57
  29. package/dist/product-set/product-zone/ProductZoneControl.d.ts +15 -0
  30. package/dist/product-set/product-zone/ProductZoneControl.d.ts.map +1 -0
  31. package/dist/product-set/product-zone/ProductZoneControl.js +263 -0
  32. package/dist/product-set/product-zone/index.d.ts +2 -0
  33. package/dist/product-set/product-zone/index.d.ts.map +1 -0
  34. package/dist/product-set/utils/index.d.ts.map +1 -1
  35. package/dist/product-set/utils/index.js +3 -1
  36. package/dist/sales/booking/results/BookingResults.js +1 -1
  37. package/dist/sortable-tree/SortableTreeItem.d.ts +3 -1
  38. package/dist/sortable-tree/SortableTreeItem.d.ts.map +1 -1
  39. package/dist/sortable-tree/SortableTreeItem.js +15 -5
  40. package/dist/styles/product-set/CreateProductSetItem.scss +8 -0
  41. package/dist/styles/product-set/EditZoneSettingModal.scss +16 -0
  42. package/dist/styles/product-set/ProductSetForm.scss +14 -1
  43. package/dist/styles/product-set/_index.scss +2 -1
  44. package/package.json +1 -1
  45. package/src/auth/Login/LoginComponent.tsx +1 -1
  46. package/src/events/edit-event-modal/utils/getDefaultProductSet.ts +2 -4
  47. package/src/layout/DropDown.tsx +1 -1
  48. package/src/product-set/control/ProductSetControl.tsx +2 -1
  49. package/src/product-set/form/ProductCategoriesControl.tsx +0 -3
  50. package/src/product-set/form/ProductZonesControl.tsx +178 -0
  51. package/src/product-set/form/ProductsControl.tsx +0 -17
  52. package/src/product-set/product/ProductControl.tsx +23 -268
  53. package/src/product-set/product/advanced-options/AdvancedOptions.tsx +168 -0
  54. package/src/product-set/product/advanced-options/index.ts +1 -0
  55. package/src/product-set/product/fixed-duration-fields/FixedDurationOptions.tsx +1 -1
  56. package/src/product-set/product-category/ProductCategoryControl.tsx +1 -60
  57. package/src/product-set/product-zone/ProductZoneControl.tsx +247 -0
  58. package/src/product-set/product-zone/index.ts +1 -0
  59. package/src/product-set/utils/index.ts +5 -1
  60. package/src/sales/booking/results/BookingResults.tsx +1 -1
  61. package/src/sortable-tree/SortableTreeItem.tsx +59 -45
  62. package/src/styles/product-set/CreateProductSetItem.scss +8 -0
  63. package/src/styles/product-set/EditZoneSettingModal.scss +16 -0
  64. package/src/styles/product-set/ProductSetForm.scss +14 -1
  65. package/src/styles/product-set/_index.scss +2 -1
  66. package/yarn.lock +120 -99
@@ -0,0 +1,178 @@
1
+ import { useContext, useState } from "react";
2
+ import {
3
+ ArrayPath,
4
+ Controller,
5
+ Path,
6
+ useFieldArray,
7
+ useFormContext,
8
+ useWatch,
9
+ } from "react-hook-form";
10
+ import { Badge } from "react-bootstrap";
11
+ import { CategoryType } from "@licklist/core/dist/DataMapper/Product/ProductCategoryDataMapper";
12
+ import { HookFormService } from "@licklist/plugins";
13
+ import { useTranslation } from "react-i18next";
14
+ import {
15
+ FieldNamePrefixPath,
16
+ FormValues,
17
+ } from "@licklist/plugins/dist/types/services/Form/hook-form-service";
18
+ import { ProductSetLoadingContext } from "./context";
19
+ import { useSortableTreeFunctions } from "../hooks/useSortableTreeFunctions";
20
+ import { ProductZoneControl, ProductZoneControlValues } from "../product-zone";
21
+ import { CreateProductSetItem } from "../item/CreateProductSetItem";
22
+ import { SortableTree } from "../../sortable-tree";
23
+ import { ProductSetModalClasses } from "../../sortable-tree/SortableTreeItem";
24
+
25
+ interface ProductZonesControlProps<T> extends FieldNamePrefixPath<T> {
26
+ isOverrides: boolean;
27
+ categoryType?: CategoryType;
28
+ }
29
+
30
+ const getDefaultProductZone = (): ProductZoneControlValues => ({
31
+ id: null,
32
+ zoneId: null,
33
+ capacity: null,
34
+ duration: null,
35
+ subSlots: null,
36
+ offset: null,
37
+ pause: null,
38
+ serviceTime: null,
39
+ });
40
+
41
+ export const ProductZonesControl = <T extends FormValues>({
42
+ isOverrides,
43
+ fieldNamePrefix,
44
+ categoryType,
45
+ }: ProductZonesControlProps<T>) => {
46
+ const [showProductZoneModal, setShowProductZoneModal] = useState(false);
47
+ const { t } = useTranslation(["Design", "Validation", "ProductSet"]);
48
+
49
+ const {
50
+ control,
51
+ formState: { errors },
52
+ trigger,
53
+ clearErrors,
54
+ } = useFormContext<T>();
55
+
56
+ const productZonesFieldName =
57
+ `${fieldNamePrefix}.productZones` as ArrayPath<T>;
58
+
59
+ const { fields, append, remove } = useFieldArray({
60
+ name: productZonesFieldName,
61
+ control,
62
+ keyName: "_id",
63
+ rules: {
64
+ required: t("Validation:fieldMinNumber", {
65
+ attribute: t("zones"),
66
+ min: 1,
67
+ }) as string,
68
+ minLength: 1,
69
+ },
70
+ });
71
+
72
+ const { zones = [] } = useContext(ProductSetLoadingContext);
73
+
74
+ const { edit, saveValidField, cancelChanges } = useSortableTreeFunctions({
75
+ fieldName: productZonesFieldName,
76
+ remove,
77
+ isOverrides,
78
+ });
79
+
80
+ const productZonesError = HookFormService.getErrors<T>(
81
+ `${productZonesFieldName}.root` as Path<T>,
82
+ errors,
83
+ );
84
+
85
+ const zoneCapacity = useWatch({
86
+ control,
87
+ name: [
88
+ ...fields.map(
89
+ (_, index) => `${productZonesFieldName}.${index}.capacity` as const,
90
+ ),
91
+ ],
92
+ });
93
+
94
+ const zoneDuration = useWatch({
95
+ control,
96
+ name: [
97
+ ...fields.map(
98
+ (_, index) => `${productZonesFieldName}.${index}.duration` as const,
99
+ ),
100
+ ],
101
+ });
102
+
103
+ const onZoneSettingRemove = (index: number) => {
104
+ remove(index);
105
+ };
106
+
107
+ return (
108
+ <>
109
+ {fields.map((productZones, index) => (
110
+ <Controller
111
+ key={productZones._id}
112
+ control={control}
113
+ name={`${productZonesFieldName}.${index}.zoneId` as const}
114
+ rules={{
115
+ required: t("Validation:fieldRequired", {
116
+ attribute: t("zone"),
117
+ }) as string,
118
+ }}
119
+ render={({ field: { value } }) => (
120
+ <SortableTree.Item
121
+ key={`productZones-${productZones._id}`}
122
+ id={String(productZones._id)}
123
+ title={zones.find((zone) => zone.id === Number(value))?.name}
124
+ badge={
125
+ <Badge className="product-zone-badge">{t("productZone")}</Badge>
126
+ }
127
+ isIconInHeader={false}
128
+ cancelChanges={() => cancelChanges(index)}
129
+ edit={() => edit(index)}
130
+ subTitle={
131
+ <div className="product-set-badges-container">
132
+ <div className="product-set-subtitle-dot product-set-subtitle-product-dot" />
133
+ <span>
134
+ {zoneCapacity[index] &&
135
+ `${t("Cap")}: ${zoneCapacity[index]}; `}
136
+ {`${t("Dur")}: ${zoneDuration[index]}`}
137
+ </span>
138
+ </div>
139
+ }
140
+ modalLabel={t("addAZone")}
141
+ modalClass={ProductSetModalClasses.productZones}
142
+ isNewAdded={showProductZoneModal}
143
+ shouldExpand={false}
144
+ body={
145
+ <ProductZoneControl
146
+ isOverrides={isOverrides}
147
+ categoryType={categoryType}
148
+ productZonesFieldName={productZonesFieldName}
149
+ fieldNamePrefix={
150
+ `${productZonesFieldName}.${index}` as Path<T>
151
+ }
152
+ />
153
+ }
154
+ onDelete={() => onZoneSettingRemove(index)}
155
+ validate={() => trigger(`${productZonesFieldName}.${index}`)}
156
+ saveValidField={saveValidField}
157
+ />
158
+ )}
159
+ />
160
+ ))}
161
+ <CreateProductSetItem
162
+ title={t("addZone")}
163
+ onClick={() => {
164
+ // @TODO after updating react hook form fix issue with this type
165
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
166
+ // @ts-expect-error
167
+ append(getDefaultProductZone());
168
+ setShowProductZoneModal(true);
169
+
170
+ if (productZonesError) {
171
+ clearErrors(productZonesFieldName);
172
+ }
173
+ }}
174
+ />
175
+ <div className="manual-form-error">{productZonesError}</div>
176
+ </>
177
+ );
178
+ };
@@ -14,7 +14,6 @@ import { generateUuid } from "@licklist/core/dist/Services";
14
14
  import HookFormService from "@licklist/plugins/dist/services/Form/HookFormService";
15
15
 
16
16
  import { CategoryType } from "@licklist/core/dist/DataMapper/Product/ProductCategoryDataMapper";
17
- import { Zone } from "@licklist/core/dist/DataMapper/Provider/ZoneDataMapper";
18
17
  import { ProductControl, ProductControlProps, ProductSetFormValues } from "..";
19
18
  import { SortableTree } from "../../sortable-tree";
20
19
  import { CreateProductSetItem } from "../item/CreateProductSetItem";
@@ -33,7 +32,6 @@ interface ProductsControlProps extends WithIsLoading {
33
32
  productCategoryIndex: number;
34
33
  hasTicket?: boolean;
35
34
  categoryType: CategoryType;
36
- zones?: Zone[];
37
35
  isOverrides?: boolean;
38
36
  isEventEditProductSet?: boolean;
39
37
  isCreateNewOverrides?: boolean;
@@ -50,8 +48,6 @@ const getDefaultProductValue = (sort: number): Product => ({
50
48
  minQuantity: null,
51
49
  maxQuantity: null,
52
50
  totalQuantity: 0,
53
- capacity: 0,
54
- duration: 0,
55
51
  isAvailable: true,
56
52
  isSoldOut: false,
57
53
  isRequired: false,
@@ -62,14 +58,9 @@ const getDefaultProductValue = (sort: number): Product => ({
62
58
  originalProductId: null,
63
59
  type: DEFAULT_PRODUCT_TYPE,
64
60
  tierId: Number(uniqueId()),
65
- zoneId: null,
66
61
  subProducts: [],
67
62
  images: [],
68
63
  uuid: generateUuid(),
69
- subSlots: null,
70
- offset: null,
71
- pause: null,
72
- serviceTime: null,
73
64
  sort,
74
65
  });
75
66
 
@@ -80,7 +71,6 @@ export function ProductsControl({
80
71
  productCategoryIndex,
81
72
  hasTicket,
82
73
  categoryType,
83
- zones,
84
74
  isOverrides,
85
75
  isEventEditProductSet,
86
76
  isCreateNewOverrides,
@@ -99,12 +89,6 @@ export function ProductsControl({
99
89
  getValues,
100
90
  } = form;
101
91
 
102
- const zoneId = watch(
103
- `steps.${stepIndex}.productCategories.${productCategoryIndex}.zoneId`,
104
- );
105
-
106
- const catergoryZone = zones?.find((zone) => zone.id === Number(zoneId));
107
-
108
92
  const productControlFieldName =
109
93
  `steps.${stepIndex}.productCategories.${productCategoryIndex}.products` as const;
110
94
 
@@ -275,7 +259,6 @@ export function ProductsControl({
275
259
  onProductNameChange={onChange}
276
260
  hasTicket={hasTicket}
277
261
  categoryType={categoryType}
278
- zoneDuration={catergoryZone?.defaultDuration}
279
262
  isOverrides={
280
263
  isNewProductOverrides || isOverridesProductSet
281
264
  }
@@ -1,16 +1,11 @@
1
1
  import {
2
2
  CategoryType,
3
3
  QuantityType,
4
- CATEGORY_TYPE_FIXED_DURATION,
5
- CATEGORY_TYPE_GAME,
6
4
  QUANTITY_TYPE_CONSTANT,
7
5
  QUANTITY_TYPE_LIST_DTO,
8
6
  QUANTITY_TYPE_RECHARGING,
9
7
  } from "@licklist/core/dist/DataMapper/Product/ProductCategoryDataMapper";
10
- import {
11
- ProductType,
12
- PRODUCT_DEfAULT_COLORS,
13
- } from "@licklist/core/dist/DataMapper/Product/ProductDataMapper";
8
+ import { ProductType } from "@licklist/core/dist/DataMapper/Product/ProductDataMapper";
14
9
  import HookFormService from "@licklist/plugins/dist/services/Form/HookFormService";
15
10
  import clsx from "clsx";
16
11
  import {
@@ -44,14 +39,14 @@ import {
44
39
  IMAGE_TYPE_IMAGE,
45
40
  } from "@licklist/core/dist/DataMapper/Media/ImageDataMapper";
46
41
  import { FaClipboard } from "react-icons/fa";
42
+ import { checkIfZoneCategory } from "@licklist/plugins";
47
43
  import { FileUpload } from "../../file-upload";
48
- import { BooleanSwitch, FormNumberInput } from "../../static";
44
+ import { BooleanSwitch } from "../../static";
49
45
  import { SelectItem } from "../../types/generic/SelectItem";
50
46
  import { ProductSetLoadingContext } from "../form/context";
51
47
  import {
52
48
  ProductBookingManagementControl,
53
49
  ProductBookingManagementControlProps,
54
- ProductBookingManagementControlValues,
55
50
  } from "./booking-management/ProductBookingManagementControl";
56
51
  import {
57
52
  ProductDepositControl,
@@ -62,20 +57,19 @@ import {
62
57
  ProductQuantityControl,
63
58
  ProductQuantityRechargingControl,
64
59
  } from "./quantity";
65
- import { PropertyControl } from "../../snippet";
66
60
  import { TipTapEditor } from "../../tiptap-editor";
67
61
  import { IsDeletableEvent } from "../types";
68
- import { FixedDurationOptions } from "./fixed-duration-fields";
69
- import { ProductDurationControl } from "./duration";
70
62
  import { ProductPriceControl } from "./price";
71
63
  import { MAX_PRODUCT_DESCRIPTION_CHARACTERS_LENGTH } from "./constants";
64
+ import { ProductZoneControlValues } from "../product-zone";
65
+ import { AdvancedOptions } from "./advanced-options";
66
+ import { ProductZonesControl } from "../form/ProductZonesControl";
72
67
 
73
68
  // TO DO refactor this file
74
69
  // and add correct types
75
70
  export interface ProductControlValues
76
71
  extends FormValues,
77
- ProductDepositControlValues,
78
- ProductBookingManagementControlValues {
72
+ ProductDepositControlValues {
79
73
  name: string;
80
74
  productGroupId: number;
81
75
  description: string;
@@ -98,12 +92,9 @@ export interface ProductControlValues
98
92
  tierId?: number;
99
93
  images: Image[] | null;
100
94
  uuid: string;
101
- subSlots: number;
102
- pause: number;
103
- offset: number;
104
- serviceTime: number;
105
95
  sort: number | null;
106
96
  color?: string;
97
+ productZones?: ProductZoneControlValues[];
107
98
  }
108
99
 
109
100
  export interface ProductControlProps<T>
@@ -120,7 +111,6 @@ export interface ProductControlProps<T>
120
111
  hasTicket?: boolean;
121
112
  categoryType?: CategoryType;
122
113
  isOverrides?: boolean;
123
- zoneDuration?: number;
124
114
  }
125
115
 
126
116
  export function ProductControl<T extends FormValues>({
@@ -134,7 +124,6 @@ export function ProductControl<T extends FormValues>({
134
124
  productName,
135
125
  hasTicket,
136
126
  categoryType,
137
- zoneDuration,
138
127
  isOverrides = false,
139
128
  }: ProductControlProps<T>) {
140
129
  const {
@@ -144,11 +133,9 @@ export function ProductControl<T extends FormValues>({
144
133
  setValue,
145
134
  getValues,
146
135
  watch,
147
- trigger,
148
- clearErrors,
149
136
  } = useFormContext<T>();
150
137
 
151
- const { setLoading, productGroupList } = useContext(ProductSetLoadingContext);
138
+ const { setLoading } = useContext(ProductSetLoadingContext);
152
139
  const { t } = useTranslation(["Design", "Validation", "ProductSet"]);
153
140
  const [expanded, setExpanded] = useState(false);
154
141
  const [initialImages, setInitialImages] = useState<Image[] | null>(null);
@@ -156,21 +143,16 @@ export function ProductControl<T extends FormValues>({
156
143
  const isUnlimited = Boolean(
157
144
  watch(`${fieldNamePrefix}.isUnlimited` as Path<T>),
158
145
  );
159
- const capacity = watch(`${fieldNamePrefix}.capacity` as Path<T>);
160
- const disabledDuration = capacity === "0" || !capacity;
161
146
  const advancedId = useId();
162
147
  const nameId = useId();
163
148
 
164
- const productGroupId = useId();
165
149
  const descriptionId = useId();
166
- const termsAndConditionsId = useId();
167
150
  const isAvailableId = useId();
168
151
  const isSoldOutId = useId();
169
- const isRequiredId = useId();
170
152
  const quantitySelectorId = useId();
171
- const hasSpecialNotesId = useId();
172
153
  const unlimitedQuantityId = useId();
173
- const minSpendId = useId();
154
+
155
+ const isZoneCategory = checkIfZoneCategory(categoryType);
174
156
 
175
157
  const quantitySelectorList: SelectItem[] = [
176
158
  { id: 1, value: t("quantitySelector") },
@@ -200,18 +182,6 @@ export function ProductControl<T extends FormValues>({
200
182
  },
201
183
  [handleImageUploading],
202
184
  );
203
-
204
- const onChangeGameCapacity = (value: number) => {
205
- if (!zoneDuration) {
206
- return;
207
- }
208
- setValue(
209
- `${fieldNamePrefix}.duration` as Path<T>,
210
- /* @ts-expect-error 6385 */
211
- (value * zoneDuration) as UnpackNestedValue<PathValue<T, Path<T>>>,
212
- );
213
- };
214
-
215
185
  const onImageRemove = useCallback(
216
186
  (id, path) => {
217
187
  handleImageRemove(String(id), path);
@@ -240,20 +210,6 @@ export function ProductControl<T extends FormValues>({
240
210
  }
241
211
  }, [images, fieldNamePrefix, setValue]);
242
212
 
243
- useEffect(() => {
244
- if (!disabledDuration) {
245
- trigger(`${fieldNamePrefix}.duration` as Path<T>);
246
- return;
247
- }
248
- setValue(
249
- `${fieldNamePrefix}.duration` as Path<T>,
250
- /* @ts-expect-error 6385 */
251
- 0 as UnpackNestedValue<PathValue<T, Path<T>>>,
252
- );
253
- clearErrors(`${fieldNamePrefix}.duration` as Path<T>);
254
- // eslint-disable-next-line react-hooks/exhaustive-deps
255
- }, [disabledDuration]);
256
-
257
213
  const quantitySelector = quantityValue ?? "1";
258
214
  const quantity = QUANTITY_TYPE_LIST_DTO[quantitySelector as string];
259
215
  return (
@@ -396,164 +352,17 @@ export function ProductControl<T extends FormValues>({
396
352
  )}
397
353
  </Form.Control.Feedback>
398
354
  </Form.Group>
399
-
400
- <PropertyControl<T>
401
- item={`${fieldNamePrefix}.color` as Path<T>}
402
- label={t("ProductSet:selectColor")}
403
- isDisabled={isOverrides}
404
- isRequired={false}
405
- defaultColors={PRODUCT_DEfAULT_COLORS}
406
- />
407
-
408
- <Form.Group controlId={productGroupId}>
409
- <Form.Label>{t("productGroup")}</Form.Label>
410
- <Form.Control
411
- as="select"
412
- {...register(`${fieldNamePrefix}.productGroupId` as Path<T>)}
413
- isInvalid={HookFormService.isInvalid<T>(
414
- `${fieldNamePrefix}.productGroupId` as Path<T>,
415
- errors,
416
- )}
417
- disabled={isLoading || isOverrides}
418
- defaultValue=""
419
- >
420
- <option value="">{t("Design:selectProductGroup")}</option>
421
- {productGroupList.map((productGroup) => {
422
- return (
423
- <option value={productGroup.id} key={productGroup.id}>
424
- {productGroup.value}
425
- </option>
426
- );
427
- })}
428
- </Form.Control>
429
- <Form.Control.Feedback type="invalid">
430
- {HookFormService.getErrors<T>(
431
- `${fieldNamePrefix}.productGroupId` as Path<T>,
432
- errors,
433
- )}
434
- </Form.Control.Feedback>
435
- </Form.Group>
436
355
  </Col>
437
356
  </Row>
438
357
 
439
- {categoryType === CATEGORY_TYPE_FIXED_DURATION && (
440
- <Row className="align-items-start duration-capacity-container">
441
- <ProductDurationControl
358
+ <Row className="my-4 mx-0 d-flex flex-column">
359
+ {isZoneCategory && (
360
+ <ProductZonesControl
361
+ isOverrides={isOverrides}
442
362
  fieldNamePrefix={fieldNamePrefix}
443
- disabled={disabledDuration || isOverrides}
363
+ categoryType={categoryType}
444
364
  />
445
-
446
- <Col lg={4} md={4}>
447
- <FormNumberInput
448
- fieldName={`${fieldNamePrefix}.capacity`}
449
- label={t("capacity")}
450
- disabled={isOverrides}
451
- rules={{
452
- min: {
453
- value: 0,
454
- message: t("Validation:fieldMinNumber", {
455
- attribute: t("capacity"),
456
- min: 0,
457
- }) as string,
458
- },
459
- }}
460
- />
461
- </Col>
462
- {disabledDuration && (
463
- <div className="duration-hint duration-capacity-container">
464
- {t("Design:forDurationEditing")}
465
- </div>
466
- )}
467
- </Row>
468
- )}
469
-
470
- {categoryType === CATEGORY_TYPE_GAME && (
471
- <>
472
- <Row className="align-items-start duration-capacity-container">
473
- <Col lg={4} md={4}>
474
- <FormNumberInput
475
- fieldName={`${fieldNamePrefix}.capacity`}
476
- label={t("capacity")}
477
- onChange={onChangeGameCapacity}
478
- disabled={isOverrides}
479
- rules={{
480
- min: {
481
- value: 0,
482
- message: t("Validation:fieldMinNumber", {
483
- attribute: t("capacity"),
484
- min: 1,
485
- }) as string,
486
- },
487
- }}
488
- />
489
- </Col>
490
- <Col lg={4} md={4}>
491
- <FormNumberInput
492
- fieldName={`${fieldNamePrefix}.duration`}
493
- label={t("durationMinutes")}
494
- disabled={disabledDuration || isOverrides}
495
- rules={{
496
- min: {
497
- value: 0,
498
- message: t("Validation:fieldMinNumber", {
499
- attribute: t("duration"),
500
- min: 0,
501
- }) as string,
502
- },
503
- validate: (val) => {
504
- if (!disabledDuration && (!val || val < 1)) {
505
- return t("Validation:fieldRequired", {
506
- attribute: t("duration"),
507
- }) as string;
508
- }
509
- return true;
510
- },
511
- }}
512
- />
513
- </Col>
514
- </Row>
515
- {disabledDuration && (
516
- <div className="duration-hint pl-0">
517
- {t("Design:forDurationEditing")}
518
- </div>
519
- )}
520
- </>
521
- )}
522
-
523
- <Row className="mt-4">
524
- <Col lg={8} md={8}>
525
- <Form.Group controlId={termsAndConditionsId}>
526
- <Form.Label>{t("productTermsConditions")}</Form.Label>
527
-
528
- <Controller
529
- render={({ field: { value, onChange, name, ref } }) => (
530
- <Form.Control
531
- ref={ref}
532
- as="textarea"
533
- rows={3}
534
- value={value as string}
535
- onChange={onChange}
536
- isInvalid={HookFormService.isInvalid<T>(
537
- `${fieldNamePrefix}.termsAndConditions` as Path<T>,
538
- errors,
539
- )}
540
- disabled={isLoading || isOverrides}
541
- name={name}
542
- />
543
- )}
544
- control={control}
545
- name={`${fieldNamePrefix}.termsAndConditions` as Path<T>}
546
- />
547
-
548
- <Form.Control.Feedback type="invalid">
549
- {HookFormService.getErrors<T>(
550
- `${fieldNamePrefix}.termsAndConditions` as Path<T>,
551
- errors,
552
- )}
553
- </Form.Control.Feedback>
554
- </Form.Group>
555
- </Col>
556
-
365
+ )}
557
366
  <Col
558
367
  lg={4}
559
368
  md={4}
@@ -640,67 +449,13 @@ export function ProductControl<T extends FormValues>({
640
449
 
641
450
  <Col lg={12} md={12} xl className="p-0">
642
451
  <Collapse in={expanded}>
452
+ {/* Div should be here not in component, otherwise component will be always collapsed */}
643
453
  <div>
644
- <Form.Group
645
- controlId={isRequiredId}
646
- className="advanced-switch-container"
647
- >
648
- <Form.Label>{t("isRequired")}</Form.Label>
649
-
650
- <Controller
651
- render={({ field: { value, onChange, name } }) => (
652
- <BooleanSwitch
653
- name={name}
654
- value={Boolean(value)}
655
- onChange={onChange}
656
- disabled={isLoading || isOverrides}
657
- />
658
- )}
659
- control={control}
660
- name={`${fieldNamePrefix}.isRequired` as Path<T>}
661
- />
662
- </Form.Group>
663
-
664
- <Form.Group
665
- controlId={hasSpecialNotesId}
666
- className="advanced-switch-container"
667
- >
668
- <Form.Label>{t("hasSpecialNotes")}</Form.Label>
669
-
670
- <Controller
671
- render={({ field: { value, onChange, name } }) => (
672
- <BooleanSwitch
673
- name={name}
674
- value={Boolean(value)}
675
- onChange={onChange}
676
- disabled={isLoading || isOverrides}
677
- />
678
- )}
679
- control={control}
680
- name={`${fieldNamePrefix}.hasSpecialNotes` as Path<T>}
681
- />
682
- </Form.Group>
683
- {[CATEGORY_TYPE_GAME, CATEGORY_TYPE_FIXED_DURATION].includes(
684
- categoryType,
685
- ) && (
686
- <FixedDurationOptions
687
- fieldNamePrefix={fieldNamePrefix}
688
- isOverrides={isOverrides}
689
- />
690
- )}
691
- <Form.Group
692
- controlId={minSpendId}
693
- className="advanced-switch-container"
694
- >
695
- <ProductPriceControl
696
- title={t("minSpend")}
697
- isRequired={false}
698
- isMoreThanZero
699
- allowDeposits={false}
700
- isLoading={isLoading || isOverrides}
701
- fieldNamePrefix={`${fieldNamePrefix}.minSpend` as Path<T>}
702
- />
703
- </Form.Group>
454
+ <AdvancedOptions
455
+ isOverrides={isOverrides}
456
+ fieldNamePrefix={fieldNamePrefix}
457
+ isLoading={isLoading}
458
+ />
704
459
  </div>
705
460
  </Collapse>
706
461