@licklist/design 0.58.9 → 0.58.10

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 (92) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/product-set/card/ProductSetCard.d.ts +2 -1
  3. package/dist/product-set/card/ProductSetCard.d.ts.map +1 -1
  4. package/dist/product-set/card/ProductSetCard.js +1 -1
  5. package/dist/product-set/control/DateInput.d.ts +17 -0
  6. package/dist/product-set/control/DateInput.d.ts.map +1 -0
  7. package/dist/product-set/control/DateInput.js +1 -0
  8. package/dist/product-set/control/ProductSetControl.d.ts +2 -1
  9. package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
  10. package/dist/product-set/control/ProductSetControl.js +1 -1
  11. package/dist/product-set/control/ProductSetRecurrenceOverridesControl.d.ts +11 -0
  12. package/dist/product-set/control/ProductSetRecurrenceOverridesControl.d.ts.map +1 -0
  13. package/dist/product-set/control/ProductSetRecurrenceOverridesControl.js +1 -0
  14. package/dist/product-set/control/TutorialGifCard.d.ts +2 -1
  15. package/dist/product-set/control/TutorialGifCard.d.ts.map +1 -1
  16. package/dist/product-set/control/TutorialGifCard.js +1 -1
  17. package/dist/product-set/form/ProductCategoriesControl.d.ts +2 -1
  18. package/dist/product-set/form/ProductCategoriesControl.d.ts.map +1 -1
  19. package/dist/product-set/form/ProductCategoriesControl.js +1 -1
  20. package/dist/product-set/form/ProductSetForm.d.ts +3 -1
  21. package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
  22. package/dist/product-set/form/ProductSetForm.js +1 -1
  23. package/dist/product-set/form/ProductsControl.d.ts +2 -1
  24. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  25. package/dist/product-set/form/ProductsControl.js +1 -1
  26. package/dist/product-set/form/StepsControl.d.ts +2 -1
  27. package/dist/product-set/form/StepsControl.d.ts.map +1 -1
  28. package/dist/product-set/form/StepsControl.js +1 -1
  29. package/dist/product-set/form/SubProductsControl.d.ts +2 -1
  30. package/dist/product-set/form/SubProductsControl.d.ts.map +1 -1
  31. package/dist/product-set/form/SubProductsControl.js +1 -1
  32. package/dist/product-set/hooks/useSortableTreeFunctions.d.ts +2 -1
  33. package/dist/product-set/hooks/useSortableTreeFunctions.d.ts.map +1 -1
  34. package/dist/product-set/hooks/useSortableTreeFunctions.js +1 -1
  35. package/dist/product-set/item/CreateProductSetItem.d.ts +2 -1
  36. package/dist/product-set/item/CreateProductSetItem.d.ts.map +1 -1
  37. package/dist/product-set/item/CreateProductSetItem.js +1 -1
  38. package/dist/product-set/product/ProductControl.d.ts +2 -1
  39. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  40. package/dist/product-set/product/ProductControl.js +1 -1
  41. package/dist/product-set/product/constants.d.ts +1 -0
  42. package/dist/product-set/product/constants.d.ts.map +1 -1
  43. package/dist/product-set/product/constants.js +1 -1
  44. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.d.ts +4 -2
  45. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.d.ts.map +1 -1
  46. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.js +1 -1
  47. package/dist/product-set/product/quantity/ProductQuantityControl.d.ts +1 -0
  48. package/dist/product-set/product/quantity/ProductQuantityControl.d.ts.map +1 -1
  49. package/dist/product-set/product/quantity/ProductQuantityControl.js +1 -1
  50. package/dist/product-set/product-category/ProductCategoryControl.d.ts +2 -1
  51. package/dist/product-set/product-category/ProductCategoryControl.d.ts.map +1 -1
  52. package/dist/product-set/product-category/ProductCategoryControl.js +1 -1
  53. package/dist/recurring-date-picker-input/DatePickerInput.d.ts +19 -0
  54. package/dist/recurring-date-picker-input/DatePickerInput.d.ts.map +1 -0
  55. package/dist/recurring-date-picker-input/DatePickerInput.js +1 -0
  56. package/dist/recurring-date-picker-input/RecurrenceAndFrequencyInput.d.ts +15 -0
  57. package/dist/recurring-date-picker-input/RecurrenceAndFrequencyInput.d.ts.map +1 -0
  58. package/dist/recurring-date-picker-input/RecurrenceAndFrequencyInput.js +1 -0
  59. package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts +2 -0
  60. package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts.map +1 -1
  61. package/dist/recurring-date-picker-input/RecurringDatePickerInput.js +1 -1
  62. package/dist/sortable-list/SortableList.d.ts +2 -1
  63. package/dist/sortable-list/SortableList.d.ts.map +1 -1
  64. package/dist/sortable-list/SortableList.js +1 -1
  65. package/dist/sortable-tree/SortableTreeItem.d.ts +3 -1
  66. package/dist/sortable-tree/SortableTreeItem.d.ts.map +1 -1
  67. package/dist/sortable-tree/SortableTreeItem.js +1 -1
  68. package/dist/styles/product-set/EditVenueMapSetModal.scss +1 -1
  69. package/package.json +1 -1
  70. package/src/product-set/card/ProductSetCard.tsx +12 -1
  71. package/src/product-set/control/DateInput.tsx +318 -0
  72. package/src/product-set/control/ProductSetControl.tsx +46 -24
  73. package/src/product-set/control/ProductSetRecurrenceOverridesControl.tsx +63 -0
  74. package/src/product-set/control/TutorialGifCard.tsx +11 -3
  75. package/src/product-set/form/ProductCategoriesControl.tsx +12 -1
  76. package/src/product-set/form/ProductSetForm.tsx +5 -0
  77. package/src/product-set/form/ProductsControl.tsx +10 -0
  78. package/src/product-set/form/StepsControl.tsx +8 -2
  79. package/src/product-set/form/SubProductsControl.tsx +3 -0
  80. package/src/product-set/hooks/useSortableTreeFunctions.ts +4 -0
  81. package/src/product-set/item/CreateProductSetItem.tsx +3 -0
  82. package/src/product-set/product/ProductControl.tsx +32 -13
  83. package/src/product-set/product/constants.ts +1 -0
  84. package/src/product-set/product/fixed-duration-fields/FixedDurationOptions.tsx +10 -2
  85. package/src/product-set/product/quantity/ProductQuantityControl.tsx +4 -3
  86. package/src/product-set/product-category/ProductCategoryControl.tsx +12 -8
  87. package/src/recurring-date-picker-input/DatePickerInput.tsx +93 -0
  88. package/src/recurring-date-picker-input/RecurrenceAndFrequencyInput.tsx +137 -0
  89. package/src/recurring-date-picker-input/RecurringDatePickerInput.tsx +4 -1
  90. package/src/sortable-list/SortableList.tsx +3 -0
  91. package/src/sortable-tree/SortableTreeItem.tsx +13 -5
  92. package/src/styles/product-set/EditVenueMapSetModal.scss +1 -1
@@ -34,6 +34,7 @@ interface ProductsControlProps extends WithIsLoading {
34
34
  hasTicket?: boolean;
35
35
  categoryType: CategoryType;
36
36
  zones?: Zone[];
37
+ isOverrides?: boolean;
37
38
  }
38
39
 
39
40
  const getDefaultProductValue = (sort: number): Product => ({
@@ -77,6 +78,7 @@ export function ProductsControl({
77
78
  hasTicket,
78
79
  categoryType,
79
80
  zones,
81
+ isOverrides,
80
82
  }: ProductsControlProps) {
81
83
  const { t } = useTranslation("Design");
82
84
  const form = useFormContext<ProductSetFormValues>();
@@ -112,6 +114,7 @@ export function ProductsControl({
112
114
  const { edit, saveValidField, cancelChanges } = useSortableTreeFunctions({
113
115
  fieldName: productControlFieldName,
114
116
  remove,
117
+ isOverrides,
115
118
  });
116
119
 
117
120
  const allowDeposits = watch(
@@ -159,6 +162,7 @@ export function ProductsControl({
159
162
  });
160
163
 
161
164
  const handleDragEnd = (_event) => {
165
+ if (isOverrides) return;
162
166
  const { active, over } = _event;
163
167
 
164
168
  if (!active || !over || !active?.id || !over?.id) return;
@@ -176,6 +180,7 @@ export function ProductsControl({
176
180
  };
177
181
 
178
182
  const onProductRemove = (index: number) => {
183
+ if (isOverrides) return;
179
184
  const currentProduct = getValues(
180
185
  `${productControlFieldName}.${index}` as const
181
186
  );
@@ -215,10 +220,12 @@ export function ProductsControl({
215
220
  isExpanded={isFirstProductAdded}
216
221
  isInvalid={!!categoryProductErrors}
217
222
  title={value}
223
+ isOverride={isOverrides}
218
224
  badge={<Badge className="product-badge">{t("product")}</Badge>}
219
225
  isIconInHeader={false}
220
226
  cancelChanges={() => cancelChanges(index)}
221
227
  edit={() => edit(index)}
228
+ isProduct
222
229
  secondaryBadge={getBadgeConfig(categoryType, t(categoryType))}
223
230
  subTitle={
224
231
  <div className="product-set-badges-container">
@@ -255,6 +262,7 @@ export function ProductsControl({
255
262
  hasTicket={hasTicket}
256
263
  categoryType={categoryType}
257
264
  zoneDuration={catergoryZone?.defaultDuration}
265
+ isOverrides={isOverrides}
258
266
  />
259
267
  }
260
268
  onDelete={() => onProductRemove(index)}
@@ -276,7 +284,9 @@ export function ProductsControl({
276
284
  </SortableTree>
277
285
  <CreateProductSetItem
278
286
  title={t("addProduct")}
287
+ isOverride={isOverrides}
279
288
  onClick={() => {
289
+ if (isOverrides) return;
280
290
  append(getDefaultProductValue(fields.length));
281
291
  setShowProductModal(true);
282
292
 
@@ -18,9 +18,10 @@ import { ProductSetFormValues } from "./ProductSetForm";
18
18
 
19
19
  interface StepsControlProps {
20
20
  isLoading: boolean;
21
+ isOverrides?: boolean;
21
22
  }
22
23
 
23
- export function StepsControl({ isLoading }: StepsControlProps) {
24
+ export function StepsControl({ isLoading, isOverrides }: StepsControlProps) {
24
25
  const form = useFormContext<ProductSetFormValues>();
25
26
  const { t } = useTranslation("Design");
26
27
  const [showStepModal, setShowStepModal] = useState(false);
@@ -42,6 +43,7 @@ export function StepsControl({ isLoading }: StepsControlProps) {
42
43
  const { edit, saveValidField, cancelChanges } = useSortableTreeFunctions({
43
44
  fieldName: "steps",
44
45
  remove,
46
+ isOverrides,
45
47
  });
46
48
 
47
49
  useEffect(() => {
@@ -90,8 +92,9 @@ export function StepsControl({ isLoading }: StepsControlProps) {
90
92
  modalLabel={t("addNewStep")}
91
93
  modalClass={ProductSetModalClasses.step}
92
94
  isNewAdded={showStepModal}
93
- edit={() => edit(index)}
95
+ edit={() => !isOverrides && edit(index)}
94
96
  cancelChanges={() => cancelChanges(index)}
97
+ isOverride={isOverrides}
95
98
  subTitle={
96
99
  <div className="product-set-badges-container">
97
100
  <div className="product-set-subtitle-dot product-set-subtitle-step-dot" />
@@ -136,6 +139,7 @@ export function StepsControl({ isLoading }: StepsControlProps) {
136
139
  <ProductCategoriesControl
137
140
  isLoading={isLoading}
138
141
  stepIndex={index}
142
+ isOverrides={isOverrides}
139
143
  />
140
144
  </SortableTree.Item>
141
145
  )}
@@ -145,7 +149,9 @@ export function StepsControl({ isLoading }: StepsControlProps) {
145
149
 
146
150
  <CreateProductSetItem
147
151
  title={t("addStep")}
152
+ isOverride={isOverrides}
148
153
  onClick={() => {
154
+ if (isOverrides) return;
149
155
  append(getDefaultStepsValues());
150
156
  setShowStepModal(true);
151
157
  if (errors.steps?.type === HookFormService.manualErrorType) {
@@ -15,6 +15,7 @@ interface SubProductsControlProps {
15
15
  productCategoryIndex: number;
16
16
  productIndex: number;
17
17
  isLoading: boolean;
18
+ isOverrides?: boolean;
18
19
  }
19
20
 
20
21
  export function SubProductsControl({
@@ -23,6 +24,7 @@ export function SubProductsControl({
23
24
  stepIndex,
24
25
  productCategoryIndex,
25
26
  productIndex,
27
+ isOverrides,
26
28
  }: SubProductsControlProps) {
27
29
  const form = useFormContext<ProductSetFormValues>();
28
30
  const { fields, append } = useFieldArray({
@@ -49,6 +51,7 @@ export function SubProductsControl({
49
51
  key={`sub-product-${subProduct.id}-${index}`}
50
52
  id={subProduct.id}
51
53
  title={subProduct.name}
54
+ isOverride={isOverrides}
52
55
  body={
53
56
  <ProductControl<ProductSetFormValues>
54
57
  isLoading={isLoading}
@@ -4,21 +4,25 @@ import { useFormContext } from "react-hook-form";
4
4
  interface useSortableTreeFunctionsProps {
5
5
  fieldName: string;
6
6
  remove: (index?: number | number[]) => void;
7
+ isOverrides?: boolean;
7
8
  }
8
9
  export const useSortableTreeFunctions = ({
9
10
  fieldName,
10
11
  remove,
12
+ isOverrides,
11
13
  }: useSortableTreeFunctionsProps) => {
12
14
  const { getValues, setValue } = useFormContext();
13
15
  const [previousValue, setEditValue] = useState(null);
14
16
 
15
17
  const edit = (index: number) => {
18
+ if (isOverrides) return;
16
19
  const currentCategoryProduct = getValues(`${fieldName}.${index}` as const);
17
20
  const cloneCategoryProduct = structuredClone(currentCategoryProduct);
18
21
  setEditValue(cloneCategoryProduct);
19
22
  };
20
23
 
21
24
  const cancelChanges = (index: number) => {
25
+ if (isOverrides) return;
22
26
  if (!previousValue) {
23
27
  return remove(index);
24
28
  }
@@ -6,18 +6,21 @@ interface CreateProductSetItemProps {
6
6
  onClick: () => void;
7
7
  title: string;
8
8
  className?: string;
9
+ isOverride?: boolean;
9
10
  }
10
11
 
11
12
  export function CreateProductSetItem({
12
13
  onClick,
13
14
  title,
14
15
  className,
16
+ isOverride,
15
17
  }: CreateProductSetItemProps) {
16
18
  return (
17
19
  <button
18
20
  className={clsx(
19
21
  "product-set-item-wrapper w-100",
20
22
  `product-set-item-wrapper-${title.toLowerCase().split(" ")[1]}`,
23
+ isOverride && "bg-light",
21
24
  className
22
25
  )}
23
26
  onClick={onClick}
@@ -14,6 +14,7 @@ import {
14
14
  FormValues,
15
15
  } from "@licklist/plugins/dist/types/services/Form/hook-form-service";
16
16
  import { useId } from "@react-aria/utils";
17
+ import clsx from "clsx";
17
18
  import React, {
18
19
  ChangeEvent,
19
20
  useCallback,
@@ -113,6 +114,7 @@ export interface ProductControlProps<T>
113
114
  productName: string;
114
115
  hasTicket?: boolean;
115
116
  categoryType?: CategoryType;
117
+ isOverrides?: boolean;
116
118
  zoneDuration?: number;
117
119
  }
118
120
 
@@ -128,6 +130,7 @@ export function ProductControl<T extends FormValues>({
128
130
  hasTicket,
129
131
  categoryType,
130
132
  zoneDuration,
133
+ isOverrides = false,
131
134
  }: ProductControlProps<T>) {
132
135
  const {
133
136
  register,
@@ -260,7 +263,7 @@ export function ProductControl<T extends FormValues>({
260
263
  `${fieldNamePrefix}.name` as Path<T>,
261
264
  errors
262
265
  )}
263
- disabled={isLoading}
266
+ disabled={isLoading || isOverrides}
264
267
  placeholder={t("name")}
265
268
  />
266
269
  <Form.Control.Feedback type="invalid">
@@ -280,7 +283,7 @@ export function ProductControl<T extends FormValues>({
280
283
  viewMode={false}
281
284
  onUpdate={onChange}
282
285
  content={value as string}
283
- disabled={isLoading}
286
+ disabled={isLoading || isOverrides}
284
287
  />
285
288
  )}
286
289
  rules={{
@@ -326,6 +329,7 @@ export function ProductControl<T extends FormValues>({
326
329
  <ProductQuantityControl<T>
327
330
  isLoading={isLoading}
328
331
  fieldNamePrefix={fieldNamePrefix}
332
+ isOverrides={isOverrides}
329
333
  onFocus={onFocus}
330
334
  />
331
335
 
@@ -370,7 +374,7 @@ export function ProductControl<T extends FormValues>({
370
374
  `${fieldNamePrefix}.quantitySelector` as Path<T>,
371
375
  errors
372
376
  )}
373
- disabled={isLoading || hasTicket}
377
+ disabled={isLoading || hasTicket || isOverrides}
374
378
  >
375
379
  {quantitySelectorList.map((selector) => (
376
380
  <option value={selector.id} key={selector.id}>
@@ -392,13 +396,14 @@ export function ProductControl<T extends FormValues>({
392
396
  <Row className="align-items-start duration-capacity-container">
393
397
  <ProductDurationControl
394
398
  fieldNamePrefix={fieldNamePrefix}
395
- disabled={disabledDuration}
399
+ disabled={disabledDuration || isOverrides}
396
400
  />
397
401
 
398
402
  <Col lg={4} md={4}>
399
403
  <FormNumberInput
400
404
  fieldName={`${fieldNamePrefix}.capacity`}
401
405
  label={t("capacity")}
406
+ disabled={isOverrides}
402
407
  rules={{
403
408
  min: {
404
409
  value: 0,
@@ -426,6 +431,7 @@ export function ProductControl<T extends FormValues>({
426
431
  fieldName={`${fieldNamePrefix}.capacity`}
427
432
  label={t("capacity")}
428
433
  onChange={onChangeGameCapacity}
434
+ disabled={isOverrides}
429
435
  rules={{
430
436
  min: {
431
437
  value: 0,
@@ -441,7 +447,7 @@ export function ProductControl<T extends FormValues>({
441
447
  <FormNumberInput
442
448
  fieldName={`${fieldNamePrefix}.duration`}
443
449
  label={t("durationMinutes")}
444
- disabled={disabledDuration}
450
+ disabled={disabledDuration || isOverrides}
445
451
  rules={{
446
452
  min: {
447
453
  value: 0,
@@ -487,7 +493,7 @@ export function ProductControl<T extends FormValues>({
487
493
  `${fieldNamePrefix}.termsAndConditions` as Path<T>,
488
494
  errors
489
495
  )}
490
- disabled={isLoading}
496
+ disabled={isLoading || isOverrides}
491
497
  name={name}
492
498
  />
493
499
  )}
@@ -504,7 +510,14 @@ export function ProductControl<T extends FormValues>({
504
510
  </Form.Group>
505
511
  </Col>
506
512
 
507
- <Col lg={4} md={4} className="licklist-file-upload-wrapper">
513
+ <Col
514
+ lg={4}
515
+ md={4}
516
+ className={clsx(
517
+ "licklist-file-upload-wrapper",
518
+ isOverrides && "opacity-50"
519
+ )}
520
+ >
508
521
  <FileUpload
509
522
  onFilesChange={onFilesChange}
510
523
  allowedExtensions={["jpeg", "jpg", "png"]}
@@ -513,6 +526,7 @@ export function ProductControl<T extends FormValues>({
513
526
  onFileRemove={onImageRemove}
514
527
  defaultFiles={images}
515
528
  isLoading={isImageUploading}
529
+ disabled={isOverrides}
516
530
  withIcon
517
531
  title={t("addImage")}
518
532
  />
@@ -533,7 +547,7 @@ export function ProductControl<T extends FormValues>({
533
547
  name={name}
534
548
  value={Boolean(value)}
535
549
  onChange={onChange}
536
- disabled={isLoading}
550
+ disabled={isLoading || isOverrides}
537
551
  />
538
552
  );
539
553
  }}
@@ -568,7 +582,7 @@ export function ProductControl<T extends FormValues>({
568
582
  custom
569
583
  type="checkbox"
570
584
  name={advancedId}
571
- disabled={isLoading}
585
+ disabled={isLoading || isOverrides}
572
586
  >
573
587
  <Form.Check.Input
574
588
  checked={expanded}
@@ -595,7 +609,7 @@ export function ProductControl<T extends FormValues>({
595
609
  name={name}
596
610
  value={Boolean(value)}
597
611
  onChange={onChange}
598
- disabled={isLoading}
612
+ disabled={isLoading || isOverrides}
599
613
  />
600
614
  )}
601
615
  control={control}
@@ -615,7 +629,7 @@ export function ProductControl<T extends FormValues>({
615
629
  name={name}
616
630
  value={Boolean(value)}
617
631
  onChange={onChange}
618
- disabled={isLoading}
632
+ disabled={isLoading || isOverrides}
619
633
  />
620
634
  )}
621
635
  control={control}
@@ -624,7 +638,12 @@ export function ProductControl<T extends FormValues>({
624
638
  </Form.Group>
625
639
  {[CATEGORY_TYPE_GAME, CATEGORY_TYPE_FIXED_DURATION].includes(
626
640
  categoryType
627
- ) && <FixedDurationOptions fieldNamePrefix={fieldNamePrefix} />}
641
+ ) && (
642
+ <FixedDurationOptions
643
+ fieldNamePrefix={fieldNamePrefix}
644
+ isOverrides={isOverrides}
645
+ />
646
+ )}
628
647
  <Form.Group
629
648
  controlId={minSpendId}
630
649
  className="advanced-switch-container"
@@ -634,7 +653,7 @@ export function ProductControl<T extends FormValues>({
634
653
  isRequired={false}
635
654
  isMoreThanZero
636
655
  allowDeposits={false}
637
- isLoading={isLoading}
656
+ isLoading={isLoading || isOverrides}
638
657
  fieldNamePrefix={`${fieldNamePrefix}.minSpend` as Path<T>}
639
658
  />
640
659
  </Form.Group>
@@ -1 +1,2 @@
1
1
  export const MAX_PRODUCT_DESCRIPTION_CHARACTERS_LENGTH = 1000;
2
+ export const MAX_QUANTITY_RECURRENCE_DATE_IN_OVERRIDE = 1;
@@ -5,10 +5,15 @@ import { FieldNamePrefixPath } from "@licklist/plugins/dist/types/services/Form/
5
5
  import { useWatch } from "react-hook-form";
6
6
  import { FormNumberInput } from "../../../static";
7
7
 
8
- type FixedDurationOptionsProps<T> = FieldNamePrefixPath<T>;
8
+
9
+
10
+ interface FixedDurationOptionsProps<T> extends FieldNamePrefixPath<T> {
11
+ isOverrides?: boolean;
12
+ }
9
13
 
10
14
  export const FixedDurationOptions = <T,>({
11
15
  fieldNamePrefix,
16
+ isOverrides,
12
17
  }: FixedDurationOptionsProps<T>) => {
13
18
  const { t } = useTranslation("Design");
14
19
 
@@ -21,6 +26,7 @@ export const FixedDurationOptions = <T,>({
21
26
  <FormNumberInput
22
27
  fieldName={`${fieldNamePrefix}.subSlots`}
23
28
  label={t("subSlotsInMin")}
29
+ disabled={isOverrides}
24
30
  />
25
31
  </Col>
26
32
 
@@ -28,7 +34,7 @@ export const FixedDurationOptions = <T,>({
28
34
  <FormNumberInput
29
35
  fieldName={`${fieldNamePrefix}.pause`}
30
36
  label={t("pauseInMin")}
31
- disabled={!subSlotsFieldValue}
37
+ disabled={!subSlotsFieldValue || isOverrides}
32
38
  />
33
39
  </Col>
34
40
  </Row>
@@ -38,6 +44,7 @@ export const FixedDurationOptions = <T,>({
38
44
  <FormNumberInput
39
45
  fieldName={`${fieldNamePrefix}.offset`}
40
46
  label={t("offsetInMin")}
47
+ disabled={isOverrides}
41
48
  />
42
49
  </Col>
43
50
 
@@ -45,6 +52,7 @@ export const FixedDurationOptions = <T,>({
45
52
  <FormNumberInput
46
53
  fieldName={`${fieldNamePrefix}.serviceTime`}
47
54
  label={t("serviceTimeInMin")}
55
+ disabled={isOverrides}
48
56
  />
49
57
  </Col>
50
58
  </Row>
@@ -22,12 +22,13 @@ export interface ProductQuantityControlValues extends FormValues {
22
22
  export interface ProductQuantityControlProps<T> extends FieldNamePrefixPath<T> {
23
23
  isLoading: boolean;
24
24
  onFocus?: (e: React.SyntheticEvent) => void;
25
+ isOverrides?: boolean;
25
26
  }
26
27
 
27
28
  export function ProductQuantityControl<T extends FormValues>(
28
29
  props: ProductQuantityControlProps<T>
29
30
  ) {
30
- const { isLoading = false, fieldNamePrefix, onFocus } = props;
31
+ const { isLoading = false, fieldNamePrefix, onFocus, isOverrides } = props;
31
32
  const {
32
33
  control,
33
34
  formState: { errors },
@@ -90,7 +91,7 @@ export function ProductQuantityControl<T extends FormValues>(
90
91
  isInvalid={
91
92
  Number(minQuantityValue) > Number(maxQuantityValue)
92
93
  }
93
- disabled={isLoading}
94
+ disabled={isLoading || isOverrides}
94
95
  />
95
96
  )}
96
97
  control={control}
@@ -148,7 +149,7 @@ export function ProductQuantityControl<T extends FormValues>(
148
149
  isInvalid={
149
150
  Number(minQuantityValue) > Number(maxQuantityValue)
150
151
  }
151
- disabled={isLoading}
152
+ disabled={isLoading || isOverrides}
152
153
  />
153
154
  )}
154
155
  control={control}
@@ -49,6 +49,7 @@ export interface ProductCategoryControlProps extends IsDeletableEvent {
49
49
  onCategoryNameChange: (args: any) => void;
50
50
  stepIndex: number;
51
51
  productCategoryIndex: number;
52
+ isOverride?: boolean;
52
53
  }
53
54
 
54
55
  const categoriesWithTickets = [
@@ -63,6 +64,7 @@ export function ProductCategoryControl({
63
64
  onCategoryNameChange,
64
65
  productCategoryIndex,
65
66
  stepIndex,
67
+ isOverride = false,
66
68
  }: ProductCategoryControlProps) {
67
69
  const {
68
70
  control,
@@ -157,7 +159,7 @@ export function ProductCategoryControl({
157
159
  errors
158
160
  )}
159
161
  placeholder={t("name")}
160
- disabled={isLoading}
162
+ disabled={isLoading || isOverride}
161
163
  />
162
164
  <Form.Control.Feedback type="invalid">
163
165
  {HookFormService.getErrors<ProductSetFormValues>(
@@ -183,7 +185,7 @@ export function ProductCategoryControl({
183
185
  }))}
184
186
  value={field.value}
185
187
  onChange={field.onChange}
186
- disabled={isLoading}
188
+ disabled={isLoading || isOverride}
187
189
  />
188
190
  </Form.Group>
189
191
  )}
@@ -227,7 +229,7 @@ export function ProductCategoryControl({
227
229
  `${fieldNamePrefix}.minSubItems` as const,
228
230
  errors
229
231
  )}
230
- disabled={isLoading}
232
+ disabled={isLoading || isOverride}
231
233
  name={name}
232
234
  />
233
235
  )}
@@ -299,7 +301,7 @@ export function ProductCategoryControl({
299
301
  `${fieldNamePrefix}.maxSubItems` as const,
300
302
  errors
301
303
  )}
302
- disabled={isLoading}
304
+ disabled={isLoading || isOverride}
303
305
  />
304
306
  )}
305
307
  control={control}
@@ -337,6 +339,7 @@ export function ProductCategoryControl({
337
339
  render={({ field }) => (
338
340
  <Form.Control
339
341
  as="select"
342
+ disabled={isOverride}
340
343
  isInvalid={HookFormService.isInvalid<ProductSetFormValues>(
341
344
  `${fieldNamePrefix}.zoneId`,
342
345
  errors
@@ -384,6 +387,7 @@ export function ProductCategoryControl({
384
387
  <Form.Check.Input
385
388
  checked={expanded}
386
389
  onChange={handleExpand}
390
+ disabled={isOverride}
387
391
  type="checkbox"
388
392
  />
389
393
  <Form.Check.Label>{t("showAdvancedOptions")}</Form.Check.Label>
@@ -452,7 +456,7 @@ export function ProductCategoryControl({
452
456
  name={name}
453
457
  value={Boolean(value)}
454
458
  onChange={onChange}
455
- disabled={isLoading}
459
+ disabled={isLoading || isOverride}
456
460
  />
457
461
  )}
458
462
  control={control}
@@ -476,7 +480,7 @@ export function ProductCategoryControl({
476
480
  name={name}
477
481
  value={Boolean(value)}
478
482
  onChange={onChange}
479
- disabled={isLoading}
483
+ disabled={isLoading || isOverride}
480
484
  />
481
485
  )}
482
486
  control={control}
@@ -499,7 +503,7 @@ export function ProductCategoryControl({
499
503
  name={name}
500
504
  value={Boolean(value)}
501
505
  onChange={onChange}
502
- disabled={isLoading}
506
+ disabled={isLoading || isOverride}
503
507
  />
504
508
  )}
505
509
  control={control}
@@ -527,7 +531,7 @@ export function ProductCategoryControl({
527
531
  `${fieldNamePrefix}.remainderExpireAfter` as const,
528
532
  errors
529
533
  )}
530
- disabled={isLoading}
534
+ disabled={isLoading || isOverride}
531
535
  name={name}
532
536
  />
533
537
  )}
@@ -0,0 +1,93 @@
1
+ import React, { PropsWithChildren } from "react";
2
+ import { Frequency } from "rrule";
3
+ import { useTranslation } from "react-i18next";
4
+ import Button from "react-bootstrap/Button";
5
+ import { DateTime } from "luxon";
6
+ import { TIME_FULL_FORMAT } from "@licklist/core/dist/Config/Date";
7
+ import { FormProvider, useForm } from "react-hook-form";
8
+ import { Form } from "react-bootstrap";
9
+ import { ConfirmModal } from "../modals";
10
+ import { DeleteFieldButton } from "../product-set/elements";
11
+ import { RecurringDatePickerInputValues } from "./RecurringDatePickerInput";
12
+ import RecurrenceAndFrequencyInput from "./RecurrenceAndFrequencyInput";
13
+
14
+ export interface RecurringDatePickerInputProps {
15
+ disabled?: boolean;
16
+ defaultValues?: Partial<RecurringDatePickerInputValues>;
17
+ onChange: (state: RecurringDatePickerInputValues) => void;
18
+ onDelete: () => void;
19
+ initialFrequency?: Frequency;
20
+ setInitialStartDateAfterSelect?: boolean;
21
+ minDate?: string;
22
+ }
23
+
24
+ export interface DatePickerInputValues {
25
+ startDate: string;
26
+ startTime: string;
27
+ endTime: string;
28
+ }
29
+
30
+ export function DatePickerInput({
31
+ disabled = false,
32
+ onChange,
33
+ onDelete,
34
+ defaultValues,
35
+ children,
36
+ minDate,
37
+ }: PropsWithChildren<RecurringDatePickerInputProps>) {
38
+ const { t } = useTranslation(["Design"]);
39
+
40
+ const form = useForm<DatePickerInputValues>({
41
+ defaultValues: {
42
+ startDate: defaultValues?.startDate ?? "",
43
+ startTime: defaultValues?.startTime ?? "",
44
+ endTime: defaultValues?.endTime ?? "",
45
+ },
46
+ mode: "onChange",
47
+ });
48
+
49
+ const { handleSubmit } = form;
50
+
51
+ const onSubmit = (nextState: RecurringDatePickerInputValues) => {
52
+ const endTimeNextState = nextState?.endTime
53
+ ? DateTime.fromISO(nextState?.endTime).toFormat(TIME_FULL_FORMAT)
54
+ : "";
55
+
56
+ onChange({
57
+ ...nextState,
58
+ endTime: endTimeNextState,
59
+ });
60
+ };
61
+
62
+ return (
63
+ <FormProvider {...form}>
64
+ <Form
65
+ noValidate
66
+ onSubmit={(event) => {
67
+ // prevents parent form submitting
68
+ event.preventDefault();
69
+ event.stopPropagation();
70
+ return handleSubmit(onSubmit)(event);
71
+ }}
72
+ >
73
+ <RecurrenceAndFrequencyInput disabled={disabled} minDate={minDate} />
74
+
75
+ {children}
76
+
77
+ <div className="d-inline-flex align-items-center w-100">
78
+ <Button type="submit">{t("Design:apply")}</Button>
79
+
80
+ {defaultValues && (
81
+ <div className="d-flex justify-content-end delete-btn">
82
+ <ConfirmModal>
83
+ {(confirm) => (
84
+ <DeleteFieldButton onDelete={() => confirm(onDelete)} />
85
+ )}
86
+ </ConfirmModal>
87
+ </div>
88
+ )}
89
+ </div>
90
+ </Form>
91
+ </FormProvider>
92
+ );
93
+ }