@licklist/design 0.58.9 → 0.58.11-dev.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 (259) hide show
  1. package/bitbucket-pipelines.yml +0 -8
  2. package/dist/assets/iframe/calendar.svg +2 -2
  3. package/dist/assets/iframe/calendar.svg.js +1 -1
  4. package/dist/assets/iframe/ticket.svg +2 -2
  5. package/dist/assets/iframe/ticket.svg.js +1 -1
  6. package/dist/calendar/Calendar.d.ts +1 -1
  7. package/dist/calendar/Calendar.d.ts.map +1 -1
  8. package/dist/calendar/Calendar.js +1 -1
  9. package/dist/calendar/components/CalendarButtons/CalendarButtons.js +1 -1
  10. package/dist/calendar/components/CalendarDates/CalendarDates.d.ts +2 -2
  11. package/dist/calendar/components/CalendarDates/CalendarDates.d.ts.map +1 -1
  12. package/dist/calendar/components/CalendarDates/CalendarDates.js +1 -1
  13. package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.js +1 -1
  14. package/dist/events/event-statistic-modal/EventStatisticModal.js +1 -1
  15. package/dist/iframe/event/event-card/IframeEventCard.d.ts +2 -1
  16. package/dist/iframe/event/event-card/IframeEventCard.d.ts.map +1 -1
  17. package/dist/iframe/event/event-card/IframeEventCard.js +1 -1
  18. package/dist/iframe/event/event-venue-map/IframeEventVenueMap.js +1 -1
  19. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts +2 -2
  20. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts.map +1 -1
  21. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.js +1 -1
  22. package/dist/iframe/order-process/components/BookingSummary/components/BookingSummaryAccordion/BookingSummaryAccordion.d.ts +4 -2
  23. package/dist/iframe/order-process/components/BookingSummary/components/BookingSummaryAccordion/BookingSummaryAccordion.d.ts.map +1 -1
  24. package/dist/iframe/order-process/components/BookingSummary/components/BookingSummaryAccordion/BookingSummaryAccordion.js +1 -1
  25. package/dist/iframe/order-process/components/BookingSummary/components/SummaryTotal/components/SummaryTotalBlock.d.ts +1 -1
  26. package/dist/iframe/order-process/components/BookingSummary/components/SummaryTotal/components/SummaryTotalBlock.d.ts.map +1 -1
  27. package/dist/iframe/order-process/components/BookingSummary/components/SummaryTotal/components/SummaryTotalBlock.js +1 -1
  28. package/dist/iframe/order-process/components/BookingSummary/components/ToggleHeader/ToggleHeader.d.ts +4 -2
  29. package/dist/iframe/order-process/components/BookingSummary/components/ToggleHeader/ToggleHeader.d.ts.map +1 -1
  30. package/dist/iframe/order-process/components/BookingSummary/components/ToggleHeader/ToggleHeader.js +1 -1
  31. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts +4 -0
  32. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts.map +1 -1
  33. package/dist/iframe/order-process/components/CalendarStepsForm/CalendarStepsForm.js +1 -1
  34. package/dist/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.js +1 -1
  35. package/dist/iframe/page/components/PageBody/components/LeftBlock/LeftBlock.d.ts.map +1 -1
  36. package/dist/iframe/page/components/PageBody/components/LeftBlock/LeftBlock.js +1 -1
  37. package/dist/iframe/page/components/PageBody/constants.d.ts +1 -0
  38. package/dist/iframe/page/components/PageBody/constants.d.ts.map +1 -1
  39. package/dist/iframe/page/components/PageBody/constants.js +1 -1
  40. package/dist/iframe/page/components/PageBody/hooks/useResizePageBody.d.ts.map +1 -1
  41. package/dist/iframe/page/components/PageBody/hooks/useResizePageBody.js +1 -1
  42. package/dist/iframe/payment/order-items-table/OrderItemsTable.js +1 -1
  43. package/dist/iframe/payment/order-items-table/utils/paymentSummary.js +1 -1
  44. package/dist/iframe/payment/payment-form/PaymentForm.js +1 -1
  45. package/dist/iframe/payment/payment-page/PaymentPage.d.ts.map +1 -1
  46. package/dist/iframe/payment/payment-page/PaymentPage.js +1 -1
  47. package/dist/iframe/payment/payment-page/PaymentTimer.js +1 -1
  48. package/dist/iframe/payment/payment-status-page/PaymentStatusPage.js +1 -1
  49. package/dist/iframe/ryft/RyftPaymentForm.d.ts.map +1 -1
  50. package/dist/iframe/ryft/RyftPaymentForm.js +1 -1
  51. package/dist/iframe/ryft/utils/ryft-form.d.ts +5 -0
  52. package/dist/iframe/ryft/utils/ryft-form.d.ts.map +1 -0
  53. package/dist/iframe/ryft/utils/ryft-form.js +1 -0
  54. package/dist/index.js +1 -1
  55. package/dist/product-set/card/ProductSetCard.d.ts +2 -1
  56. package/dist/product-set/card/ProductSetCard.d.ts.map +1 -1
  57. package/dist/product-set/card/ProductSetCard.js +1 -1
  58. package/dist/product-set/control/DateAndRecurrenceInput.d.ts.map +1 -1
  59. package/dist/product-set/control/DateAndRecurrenceInput.js +1 -1
  60. package/dist/product-set/control/DateInput.d.ts +17 -0
  61. package/dist/product-set/control/DateInput.d.ts.map +1 -0
  62. package/dist/product-set/control/DateInput.js +1 -0
  63. package/dist/product-set/control/ProductSetControl.d.ts +2 -1
  64. package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
  65. package/dist/product-set/control/ProductSetControl.js +1 -1
  66. package/dist/product-set/control/ProductSetRecurrenceOverridesControl.d.ts +11 -0
  67. package/dist/product-set/control/ProductSetRecurrenceOverridesControl.d.ts.map +1 -0
  68. package/dist/product-set/control/ProductSetRecurrenceOverridesControl.js +1 -0
  69. package/dist/product-set/control/TutorialGifCard.d.ts +2 -1
  70. package/dist/product-set/control/TutorialGifCard.d.ts.map +1 -1
  71. package/dist/product-set/control/TutorialGifCard.js +1 -1
  72. package/dist/product-set/form/ProductCategoriesControl.d.ts +2 -1
  73. package/dist/product-set/form/ProductCategoriesControl.d.ts.map +1 -1
  74. package/dist/product-set/form/ProductCategoriesControl.js +1 -1
  75. package/dist/product-set/form/ProductSetForm.d.ts +7 -2
  76. package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
  77. package/dist/product-set/form/ProductSetForm.js +1 -1
  78. package/dist/product-set/form/ProductsControl.d.ts +2 -1
  79. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  80. package/dist/product-set/form/ProductsControl.js +1 -1
  81. package/dist/product-set/form/StepsControl.d.ts +2 -1
  82. package/dist/product-set/form/StepsControl.d.ts.map +1 -1
  83. package/dist/product-set/form/StepsControl.js +1 -1
  84. package/dist/product-set/form/SubProductsControl.d.ts +2 -1
  85. package/dist/product-set/form/SubProductsControl.d.ts.map +1 -1
  86. package/dist/product-set/form/SubProductsControl.js +1 -1
  87. package/dist/product-set/form/VenueMapsControl.js +1 -1
  88. package/dist/product-set/hooks/useSortableTreeFunctions.d.ts +2 -1
  89. package/dist/product-set/hooks/useSortableTreeFunctions.d.ts.map +1 -1
  90. package/dist/product-set/hooks/useSortableTreeFunctions.js +1 -1
  91. package/dist/product-set/item/CreateProductSetItem.d.ts +2 -1
  92. package/dist/product-set/item/CreateProductSetItem.d.ts.map +1 -1
  93. package/dist/product-set/item/CreateProductSetItem.js +1 -1
  94. package/dist/product-set/product/ProductControl.d.ts +3 -1
  95. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  96. package/dist/product-set/product/ProductControl.js +1 -1
  97. package/dist/product-set/product/constants.d.ts +1 -0
  98. package/dist/product-set/product/constants.d.ts.map +1 -1
  99. package/dist/product-set/product/constants.js +1 -1
  100. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.d.ts +4 -2
  101. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.d.ts.map +1 -1
  102. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.js +1 -1
  103. package/dist/product-set/product/quantity/ProductQuantityControl.d.ts +1 -0
  104. package/dist/product-set/product/quantity/ProductQuantityControl.d.ts.map +1 -1
  105. package/dist/product-set/product/quantity/ProductQuantityControl.js +1 -1
  106. package/dist/product-set/product-category/ProductCategoryControl.d.ts +3 -1
  107. package/dist/product-set/product-category/ProductCategoryControl.d.ts.map +1 -1
  108. package/dist/product-set/product-category/ProductCategoryControl.js +1 -1
  109. package/dist/provider/working-hours-input/WorkingHoursInputDescription.d.ts.map +1 -1
  110. package/dist/provider/working-hours-input/WorkingHoursInputDescription.js +1 -1
  111. package/dist/recurring-date-picker-input/DatePickerInput.d.ts +19 -0
  112. package/dist/recurring-date-picker-input/DatePickerInput.d.ts.map +1 -0
  113. package/dist/recurring-date-picker-input/DatePickerInput.js +1 -0
  114. package/dist/recurring-date-picker-input/RecurrenceAndFrequencyInput.d.ts +15 -0
  115. package/dist/recurring-date-picker-input/RecurrenceAndFrequencyInput.d.ts.map +1 -0
  116. package/dist/recurring-date-picker-input/RecurrenceAndFrequencyInput.js +1 -0
  117. package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts +5 -1
  118. package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts.map +1 -1
  119. package/dist/recurring-date-picker-input/RecurringDatePickerInput.js +1 -1
  120. package/dist/recurring-date-picker-input/utils.d.ts +9 -0
  121. package/dist/recurring-date-picker-input/utils.d.ts.map +1 -1
  122. package/dist/recurring-date-picker-input/utils.js +1 -1
  123. package/dist/sales/booking/results/components/ResultCard.d.ts.map +1 -1
  124. package/dist/sales/booking/results/components/ResultCard.js +1 -1
  125. package/dist/sales/notes/NotesTableRow.js +1 -1
  126. package/dist/setting/admin/AdminSettingForm.d.ts +2 -2
  127. package/dist/setting/admin/AdminSettingForm.d.ts.map +1 -1
  128. package/dist/setting/dashboard/snippets/card/SnippetCard.js +1 -1
  129. package/dist/snippet/snippet-template/control/PropertyControl.d.ts +3 -1
  130. package/dist/snippet/snippet-template/control/PropertyControl.d.ts.map +1 -1
  131. package/dist/snippet/snippet-template/control/PropertyControl.js +1 -1
  132. package/dist/snippet/snippet-template/preview/Preview.js +1 -1
  133. package/dist/sortable-list/SortableList.d.ts +2 -1
  134. package/dist/sortable-list/SortableList.d.ts.map +1 -1
  135. package/dist/sortable-list/SortableList.js +1 -1
  136. package/dist/sortable-tree/SortableTreeItem.d.ts +3 -1
  137. package/dist/sortable-tree/SortableTreeItem.d.ts.map +1 -1
  138. package/dist/sortable-tree/SortableTreeItem.js +1 -1
  139. package/dist/static/manual-date-picker/ManualDatePicker.js +1 -1
  140. package/dist/static/manual-date-picker/constants/index.d.ts +4 -1
  141. package/dist/static/manual-date-picker/constants/index.d.ts.map +1 -1
  142. package/dist/static/manual-date-picker/constants/index.js +1 -1
  143. package/dist/static/manual-date-picker/utils/index.d.ts +4 -0
  144. package/dist/static/manual-date-picker/utils/index.d.ts.map +1 -1
  145. package/dist/static/manual-date-picker/utils/index.js +1 -1
  146. package/dist/striped-static-table/StripedStaticTable.js +1 -1
  147. package/dist/styles/iframe-events/Card.scss +24 -8
  148. package/dist/styles/iframe-events/PoweredBy.scss +2 -2
  149. package/dist/styles/iframe-order-process/IframeOrderProcess.scss +57 -20
  150. package/dist/styles/iframe-page/Page.scss +1 -0
  151. package/dist/styles/iframe-page/PageBody.scss +34 -12
  152. package/dist/styles/iframe-page/PageHeader.scss +41 -39
  153. package/dist/styles/product-set/EditVenueMapSetModal.scss +1 -1
  154. package/dist/styles/ryft-payment-form/RyftPaymentForm.scss +125 -2
  155. package/dist/styles/sales/BookingResults.scss +1 -1
  156. package/dist/venue-map-sets/form/components/VenueMapImageControl.js +1 -1
  157. package/dist/zone/form/utils/dates.d.ts.map +1 -1
  158. package/package.json +10 -35
  159. package/src/assets/iframe/calendar.svg +2 -2
  160. package/src/assets/iframe/ticket.svg +2 -2
  161. package/src/calendar/Calendar.stories.tsx +23 -0
  162. package/src/calendar/Calendar.tsx +5 -5
  163. package/src/calendar/components/CalendarDates/CalendarDates.tsx +0 -5
  164. package/src/iframe/event/event-card/IframeEventCard.stories.tsx +1 -0
  165. package/src/iframe/event/event-card/IframeEventCard.tsx +7 -8
  166. package/src/iframe/order-process/components/BookingSummary/BookingSummary.stories.tsx +9 -0
  167. package/src/iframe/order-process/components/BookingSummary/BookingSummary.tsx +58 -7
  168. package/src/iframe/order-process/components/BookingSummary/components/BookingSummaryAccordion/BookingSummaryAccordion.tsx +8 -0
  169. package/src/iframe/order-process/components/BookingSummary/components/SummaryTotal/components/SummaryTotalBlock.tsx +4 -4
  170. package/src/iframe/order-process/components/BookingSummary/components/ToggleHeader/ToggleHeader.tsx +63 -10
  171. package/src/iframe/order-process/components/BookingSummary/types/index.ts +4 -0
  172. package/src/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.tsx +1 -1
  173. package/src/iframe/page/components/PageBody/components/LeftBlock/LeftBlock.tsx +3 -1
  174. package/src/iframe/page/components/PageBody/constants.ts +2 -0
  175. package/src/iframe/page/components/PageBody/hooks/useResizePageBody.ts +10 -0
  176. package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +6 -6
  177. package/src/iframe/payment/payment-page/PaymentPage.stories.tsx +546 -6
  178. package/src/iframe/payment/payment-page/PaymentPage.tsx +38 -29
  179. package/src/iframe/ryft/RyftPaymentForm.tsx +11 -5
  180. package/src/iframe/ryft/utils/ryft-form.ts +47 -0
  181. package/src/product-set/card/ProductSetCard.tsx +12 -1
  182. package/src/product-set/control/DateAndRecurrenceInput.tsx +2 -1
  183. package/src/product-set/control/DateInput.tsx +316 -0
  184. package/src/product-set/control/ProductSetControl.tsx +46 -24
  185. package/src/product-set/control/ProductSetRecurrenceOverridesControl.tsx +63 -0
  186. package/src/product-set/control/TutorialGifCard.tsx +11 -3
  187. package/src/product-set/form/ProductCategoriesControl.tsx +12 -1
  188. package/src/product-set/form/ProductSetForm.tsx +10 -1
  189. package/src/product-set/form/ProductsControl.tsx +10 -0
  190. package/src/product-set/form/StepsControl.tsx +8 -2
  191. package/src/product-set/form/SubProductsControl.tsx +3 -0
  192. package/src/product-set/hooks/useSortableTreeFunctions.ts +6 -0
  193. package/src/product-set/item/CreateProductSetItem.tsx +3 -0
  194. package/src/product-set/product/ProductControl.tsx +48 -15
  195. package/src/product-set/product/constants.ts +1 -0
  196. package/src/product-set/product/fixed-duration-fields/FixedDurationOptions.tsx +8 -2
  197. package/src/product-set/product/quantity/ProductQuantityControl.tsx +4 -3
  198. package/src/product-set/product-category/ProductCategoryControl.tsx +116 -50
  199. package/src/provider/working-hours-input/WorkingHoursInputDescription.tsx +4 -18
  200. package/src/recurring-date-picker-input/DatePickerInput.tsx +93 -0
  201. package/src/recurring-date-picker-input/RecurrenceAndFrequencyInput.tsx +136 -0
  202. package/src/recurring-date-picker-input/RecurringDatePickerInput.tsx +15 -2
  203. package/src/recurring-date-picker-input/utils.ts +75 -0
  204. package/src/sales/booking/results/BookingResults.stories.tsx +3 -2
  205. package/src/sales/booking/results/components/ResultCard.tsx +2 -5
  206. package/src/setting/admin/AdminSettingForm.tsx +2 -2
  207. package/src/snippet/snippet-template/control/PropertyControl.tsx +6 -2
  208. package/src/sortable-list/SortableList.tsx +3 -0
  209. package/src/sortable-tree/SortableTreeItem.tsx +12 -4
  210. package/src/static/manual-date-picker/ManualDatePicker.tsx +3 -3
  211. package/src/static/manual-date-picker/constants/index.ts +6 -2
  212. package/src/static/manual-date-picker/utils/index.ts +11 -0
  213. package/src/static/switch/BooleanSwitch.tsx +1 -1
  214. package/src/styles/iframe-events/Card.scss +24 -8
  215. package/src/styles/iframe-events/PoweredBy.scss +2 -2
  216. package/src/styles/iframe-order-process/IframeOrderProcess.scss +57 -20
  217. package/src/styles/iframe-page/Page.scss +1 -0
  218. package/src/styles/iframe-page/PageBody.scss +34 -12
  219. package/src/styles/iframe-page/PageHeader.scss +41 -39
  220. package/src/styles/product-set/EditVenueMapSetModal.scss +1 -1
  221. package/src/styles/ryft-payment-form/RyftPaymentForm.scss +125 -2
  222. package/src/styles/sales/BookingResults.scss +1 -1
  223. package/src/zone/form/utils/dates.ts +9 -10
  224. package/jest.config.js +0 -29
  225. package/tests/Auth/Authorizer.test.tsx +0 -194
  226. package/tests/Auth/Layout/UserNavDropDown.test.tsx +0 -43
  227. package/tests/Auth/Layout/UserNavDropDownToggle.test.tsx +0 -33
  228. package/tests/Auth/Login/LoginComponent.test.tsx +0 -246
  229. package/tests/Auth/Login/LoginFormComponent.test.tsx +0 -182
  230. package/tests/Auth/Register/RegisterComponent.test.tsx +0 -285
  231. package/tests/Auth/Register/RegisterFormComponent.test.tsx +0 -170
  232. package/tests/Auth/Settings/Dashboard/IpInput.test.tsx +0 -130
  233. package/tests/Auth/Social/SocialCallbackComponent.test.tsx +0 -133
  234. package/tests/Auth/Social/SocialFormComponent.test.tsx +0 -118
  235. package/tests/FileUpload/FileUpload.test.tsx +0 -42
  236. package/tests/Notification/EmailTemplate.test.tsx +0 -82
  237. package/tests/ProductSet/ProductSetPopover.test.tsx +0 -40
  238. package/tests/Report/Report.test.tsx +0 -48
  239. package/tests/Sales/Coupon.test.tsx +0 -51
  240. package/tests/Sales/SalesAndVIews.test.tsx +0 -63
  241. package/tests/SnippetTemplates/SnippetTemplates.test.tsx +0 -56
  242. package/tests/Table/FilterHelperComponent.test.tsx +0 -88
  243. package/tests/Table/PaginationHelperComponent.test.tsx +0 -109
  244. package/tests/Table/PerPageHelperComponent.test.tsx +0 -34
  245. package/tests/Table/TableHelperComponent.test.tsx +0 -295
  246. package/tests/TipTapEditor/TipTapEditor.test.tsx +0 -28
  247. package/tests/__mock__/hooks/useAuthApi.ts +0 -13
  248. package/tests/__mock__/hooks/useAuthMock.ts +0 -13
  249. package/tests/__mock__/hooks/useFormMock.ts +0 -27
  250. package/tests/__mock__/hooks/useNotificationMock.ts +0 -13
  251. package/tests/__mock__/hooks/useQueryMock.ts +0 -16
  252. package/tests/__mock__/hooks/useSocialApiMock.ts +0 -20
  253. package/tests/__mock__/hooks/useTranslationMock.ts +0 -17
  254. package/tests/__mock__/hooks/useUserApiMock.ts +0 -18
  255. package/tests/__mock__/hooks/useUserMock.ts +0 -13
  256. package/tests/__mock__/styleMock.js +0 -1
  257. package/tests/__mock__/windowMock.ts +0 -5
  258. package/tests/packages/react-query.tsx +0 -28
  259. package/tests/setupTests.ts +0 -10
@@ -26,6 +26,7 @@ export interface ProductCategoryControlValues extends FormValues {
26
26
  name: string;
27
27
  minSubItems: number | null;
28
28
  maxSubItems: number | null;
29
+ overallQuantity?: number | null;
29
30
  quantityType: QuantityType;
30
31
  type: CategoryType;
31
32
  isTimeRelated: boolean;
@@ -49,6 +50,7 @@ export interface ProductCategoryControlProps extends IsDeletableEvent {
49
50
  onCategoryNameChange: (args: any) => void;
50
51
  stepIndex: number;
51
52
  productCategoryIndex: number;
53
+ isOverride?: boolean;
52
54
  }
53
55
 
54
56
  const categoriesWithTickets = [
@@ -63,6 +65,7 @@ export function ProductCategoryControl({
63
65
  onCategoryNameChange,
64
66
  productCategoryIndex,
65
67
  stepIndex,
68
+ isOverride = false,
66
69
  }: ProductCategoryControlProps) {
67
70
  const {
68
71
  control,
@@ -100,6 +103,7 @@ export function ProductCategoryControl({
100
103
  const collectUserInfoId = useId();
101
104
  const hasTicketId = useId();
102
105
  const zoneId = useId();
106
+ const overallCapacityId = useId();
103
107
 
104
108
  const allowDepositsId = useId();
105
109
  const remainderExpireAfterId = useId();
@@ -125,7 +129,7 @@ export function ProductCategoryControl({
125
129
  // eslint-disable-next-line react-hooks/exhaustive-deps
126
130
  }, [maxSubItems, fieldNamePrefix]);
127
131
 
128
- const shouldShowZoneSelect =
132
+ const isZoneCategory =
129
133
  category.type === CATEGORY_TYPE_FIXED_DURATION ||
130
134
  category.type === CATEGORY_TYPE_GAME;
131
135
 
@@ -157,7 +161,7 @@ export function ProductCategoryControl({
157
161
  errors
158
162
  )}
159
163
  placeholder={t("name")}
160
- disabled={isLoading}
164
+ disabled={isLoading || isOverride}
161
165
  />
162
166
  <Form.Control.Feedback type="invalid">
163
167
  {HookFormService.getErrors<ProductSetFormValues>(
@@ -183,7 +187,7 @@ export function ProductCategoryControl({
183
187
  }))}
184
188
  value={field.value}
185
189
  onChange={field.onChange}
186
- disabled={isLoading}
190
+ disabled={isLoading || isOverride}
187
191
  />
188
192
  </Form.Group>
189
193
  )}
@@ -227,7 +231,7 @@ export function ProductCategoryControl({
227
231
  `${fieldNamePrefix}.minSubItems` as const,
228
232
  errors
229
233
  )}
230
- disabled={isLoading}
234
+ disabled={isLoading || isOverride}
231
235
  name={name}
232
236
  />
233
237
  )}
@@ -299,7 +303,7 @@ export function ProductCategoryControl({
299
303
  `${fieldNamePrefix}.maxSubItems` as const,
300
304
  errors
301
305
  )}
302
- disabled={isLoading}
306
+ disabled={isLoading || isOverride}
303
307
  />
304
308
  )}
305
309
  control={control}
@@ -326,49 +330,110 @@ export function ProductCategoryControl({
326
330
  </Col>
327
331
  </Row>
328
332
 
329
- {shouldShowZoneSelect && (
330
- <Row>
331
- <Col>
332
- <Form.Group controlId={zoneId}>
333
- <Form.Label>{t("Design:zone")}</Form.Label>
334
- <Controller
335
- control={control}
336
- name={`${fieldNamePrefix}.zoneId`}
337
- render={({ field }) => (
338
- <Form.Control
339
- as="select"
340
- isInvalid={HookFormService.isInvalid<ProductSetFormValues>(
341
- `${fieldNamePrefix}.zoneId`,
333
+ {isZoneCategory && (
334
+ <>
335
+ <Row>
336
+ <Col md={6} sm={6} xs={6}>
337
+ <Form.Group controlId={overallCapacityId}>
338
+ <Form.Label>{t("Design:overallQuantity")}</Form.Label>
339
+ <InputGroup hasValidation>
340
+ <InputGroup.Prepend
341
+ className="arrow-up-btn"
342
+ onClick={() => {
343
+ const currentOverallCapacity = Number(
344
+ getValues(`${fieldNamePrefix}.overallQuantity`) || 0
345
+ );
346
+ setValue(
347
+ `${fieldNamePrefix}.overallQuantity`,
348
+ currentOverallCapacity + 1,
349
+ { shouldValidate: true }
350
+ );
351
+ }}
352
+ >
353
+ <InputGroup.Text className="py-0 px-3">
354
+ <IncrementIcon />
355
+ </InputGroup.Text>
356
+ </InputGroup.Prepend>
357
+ <Controller
358
+ control={control}
359
+ name={`${fieldNamePrefix}.overallQuantity`}
360
+ render={({ field }) => (
361
+ <Form.Control
362
+ min={0}
363
+ step={1}
364
+ type="number"
365
+ disabled={isOverride}
366
+ isInvalid={HookFormService.isInvalid<ProductSetFormValues>(
367
+ `${fieldNamePrefix}.overallQuantity`,
368
+ errors
369
+ )}
370
+ {...field}
371
+ />
372
+ )}
373
+ rules={{
374
+ min: {
375
+ value: 0,
376
+ message: t("Validation:fieldMinNumber", {
377
+ attribute: t("overallQuantity"),
378
+ min: 0,
379
+ }) as string,
380
+ },
381
+ }}
382
+ />
383
+ <Form.Control.Feedback type="invalid">
384
+ {HookFormService.getErrors<ProductSetFormValues>(
385
+ `${fieldNamePrefix}.overallQuantity`,
342
386
  errors
343
387
  )}
344
- {...field}
345
- >
346
- <option value={null}>{t("Design:choose")}</option>
347
- {zones.map((zone) => (
348
- <option key={zone.id} value={zone.id}>
349
- {zone.name}
350
- </option>
351
- ))}
352
- </Form.Control>
353
- )}
354
- rules={{
355
- required: {
356
- value: providerHasBookingManagement,
357
- message: t("Validation:fieldRequired", {
358
- attribute: t("zone"),
359
- }),
360
- },
361
- }}
362
- />
363
- <Form.Control.Feedback type="invalid">
364
- {HookFormService.getErrors<ProductSetFormValues>(
365
- `${fieldNamePrefix}.zoneId`,
366
- errors
367
- )}
368
- </Form.Control.Feedback>
369
- </Form.Group>
370
- </Col>
371
- </Row>
388
+ </Form.Control.Feedback>
389
+ </InputGroup>
390
+ </Form.Group>
391
+ </Col>
392
+ </Row>
393
+ <Row>
394
+ <Col>
395
+ <Form.Group controlId={zoneId}>
396
+ <Form.Label>{t("Design:zone")}</Form.Label>
397
+ <Controller
398
+ control={control}
399
+ name={`${fieldNamePrefix}.zoneId`}
400
+ render={({ field }) => (
401
+ <Form.Control
402
+ as="select"
403
+ disabled={isOverride}
404
+ isInvalid={HookFormService.isInvalid<ProductSetFormValues>(
405
+ `${fieldNamePrefix}.zoneId`,
406
+ errors
407
+ )}
408
+ {...field}
409
+ >
410
+ <option value={null}>{t("Design:choose")}</option>
411
+ {zones.map((zone) => (
412
+ <option key={zone.id} value={zone.id}>
413
+ {zone.name}
414
+ </option>
415
+ ))}
416
+ </Form.Control>
417
+ )}
418
+ rules={{
419
+ required: {
420
+ value: providerHasBookingManagement,
421
+ message: t("Validation:fieldRequired", {
422
+ attribute: t("zone"),
423
+ }),
424
+ },
425
+ }}
426
+ />
427
+ <Form.Control.Feedback type="invalid">
428
+ {HookFormService.getErrors<ProductSetFormValues>(
429
+ `${fieldNamePrefix}.zoneId`,
430
+ errors
431
+ )}
432
+ </Form.Control.Feedback>
433
+ </Form.Group>
434
+ </Col>
435
+ </Row>
436
+ </>
372
437
  )}
373
438
  </Col>
374
439
 
@@ -384,6 +449,7 @@ export function ProductCategoryControl({
384
449
  <Form.Check.Input
385
450
  checked={expanded}
386
451
  onChange={handleExpand}
452
+ disabled={isOverride}
387
453
  type="checkbox"
388
454
  />
389
455
  <Form.Check.Label>{t("showAdvancedOptions")}</Form.Check.Label>
@@ -452,7 +518,7 @@ export function ProductCategoryControl({
452
518
  name={name}
453
519
  value={Boolean(value)}
454
520
  onChange={onChange}
455
- disabled={isLoading}
521
+ disabled={isLoading || isOverride}
456
522
  />
457
523
  )}
458
524
  control={control}
@@ -476,7 +542,7 @@ export function ProductCategoryControl({
476
542
  name={name}
477
543
  value={Boolean(value)}
478
544
  onChange={onChange}
479
- disabled={isLoading}
545
+ disabled={isLoading || isOverride}
480
546
  />
481
547
  )}
482
548
  control={control}
@@ -499,7 +565,7 @@ export function ProductCategoryControl({
499
565
  name={name}
500
566
  value={Boolean(value)}
501
567
  onChange={onChange}
502
- disabled={isLoading}
568
+ disabled={isLoading || isOverride}
503
569
  />
504
570
  )}
505
571
  control={control}
@@ -527,7 +593,7 @@ export function ProductCategoryControl({
527
593
  `${fieldNamePrefix}.remainderExpireAfter` as const,
528
594
  errors
529
595
  )}
530
- disabled={isLoading}
596
+ disabled={isLoading || isOverride}
531
597
  name={name}
532
598
  />
533
599
  )}
@@ -1,9 +1,7 @@
1
- import { DateTime } from "luxon";
2
1
  import React from "react";
3
2
  import { Col, Row } from "react-bootstrap";
4
3
  import { useFormContext } from "react-hook-form";
5
4
  import { useTranslation } from "react-i18next";
6
- import { TIME_FORMAT } from "@licklist/core/dist/Config";
7
5
  import { WorkingHoursInputValues } from ".";
8
6
  import { useWeekdays } from "./utils";
9
7
 
@@ -25,22 +23,10 @@ export function WorkingHoursInputDescription() {
25
23
  <Row key={i}>
26
24
  <Col xs="auto">{weekdays[i]}:</Col>
27
25
  <Col>
28
- {weekday?.end
29
- ? weekday.start
30
- ? t("timeInterval", {
31
- start: DateTime.fromISO(weekday.start).toFormat(
32
- TIME_FORMAT
33
- ),
34
- end: DateTime.fromISO(weekday.start).toFormat(
35
- TIME_FORMAT
36
- ),
37
- })
38
- : t("timeFrom", {
39
- start: DateTime.fromISO(weekday.start).toFormat(
40
- TIME_FORMAT
41
- ),
42
- })
43
- : null}
26
+ {t("timeInterval", {
27
+ start: weekday.start,
28
+ end: weekday.end,
29
+ })}
44
30
  </Col>
45
31
  </Row>
46
32
  );
@@ -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
+ }
@@ -0,0 +1,136 @@
1
+ import React, { useEffect } from "react";
2
+ import { DateTime } from "luxon";
3
+ import { Col, Form, Row } from "react-bootstrap";
4
+ import { useTranslation } from "react-i18next";
5
+ import { RegisterOptions, useFormContext } from "react-hook-form";
6
+ import { RecurringDatePickerInputValues } from "./RecurringDatePickerInput";
7
+
8
+ interface RecurrenceIntervalAndFrequencyInputProps {
9
+ disabled?: boolean;
10
+ minDate?: string;
11
+ startDateLabel?: string;
12
+ startTimeLabel?: string;
13
+ endDateLabel?: string;
14
+ endTimeLabel?: string;
15
+ startTimeRules?: Pick<
16
+ RegisterOptions,
17
+ "max" | "min" | "validate" | "required" | "pattern"
18
+ >;
19
+ endTimeRules?: Pick<
20
+ RegisterOptions,
21
+ "max" | "min" | "validate" | "required" | "pattern"
22
+ >;
23
+ }
24
+
25
+ function RecurrenceAndFrequencyInput({
26
+ disabled = false,
27
+ minDate,
28
+ startDateLabel,
29
+ startTimeLabel,
30
+ endTimeLabel,
31
+ startTimeRules,
32
+ endTimeRules,
33
+ }: RecurrenceIntervalAndFrequencyInputProps) {
34
+ const { t } = useTranslation(["Design", "Notification", "App"]);
35
+
36
+ const {
37
+ getValues,
38
+ formState: { errors },
39
+ register,
40
+ trigger,
41
+ } = useFormContext<RecurringDatePickerInputValues>();
42
+
43
+ const startDate = getValues("startDate");
44
+ const startTime = getValues("startTime");
45
+ const endTime = getValues("endTime");
46
+
47
+ useEffect(() => {
48
+ if (!startTime || !endTime) {
49
+ return;
50
+ }
51
+ trigger("endTime");
52
+ // eslint-disable-next-line react-hooks/exhaustive-deps
53
+ }, [startTime]);
54
+
55
+ return (
56
+ <>
57
+ <Row>
58
+ <Col xs={12} sm={6}>
59
+ <Form.Group>
60
+ <Form.Label>{startDateLabel ?? t("Design:date")}</Form.Label>
61
+ <Form.Control
62
+ type="date"
63
+ {...register("startDate", { required: true })}
64
+ defaultValue={startDate}
65
+ className={startDate && "date-input-with-value"}
66
+ disabled={disabled}
67
+ min={minDate}
68
+ isInvalid={Boolean(errors.startDate)}
69
+ />
70
+ <Form.Control.Feedback type="invalid">
71
+ {errors.startDate?.message}
72
+ </Form.Control.Feedback>
73
+ </Form.Group>
74
+ </Col>
75
+ </Row>
76
+
77
+ <Row>
78
+ <Col xs={12} sm={6}>
79
+ <Form.Group>
80
+ <Form.Label>
81
+ {startTimeLabel ?? t("Design:availableFrom")}
82
+ </Form.Label>
83
+ <Form.Control
84
+ type="time"
85
+ {...register("startTime", { required: false, ...startTimeRules })}
86
+ placeholder="hh:mm"
87
+ defaultValue={startTime}
88
+ disabled={disabled}
89
+ isInvalid={Boolean(errors.startTime)}
90
+ />
91
+ <Form.Control.Feedback type="invalid">
92
+ {errors.startTime?.message}
93
+ </Form.Control.Feedback>
94
+ </Form.Group>
95
+ </Col>
96
+
97
+ <Col xs={12} sm={6}>
98
+ <Form.Group>
99
+ <Form.Label>{endTimeLabel ?? t("Design:availableTo")}</Form.Label>
100
+ <Form.Control
101
+ type="time"
102
+ {...register("endTime", {
103
+ required: false,
104
+ validate: (time) => {
105
+ if (!startTime || !time) {
106
+ return true;
107
+ }
108
+ const currentStartTime = DateTime.fromISO(startTime);
109
+ const currentEndTime = DateTime.fromISO(time);
110
+
111
+ return currentEndTime?.diff(currentStartTime, ["minutes"])
112
+ ?.minutes >= 0
113
+ ? true
114
+ : `${t(`Validation:fieldLaterDate`, {
115
+ attribute: t("Design:endTimeSmall"),
116
+ min: t("Design:startTimeSmall"),
117
+ })}`;
118
+ },
119
+ ...endTimeRules,
120
+ })}
121
+ placeholder="hh:mm"
122
+ defaultValue={endTime}
123
+ disabled={disabled}
124
+ isInvalid={Boolean(errors.endTime)}
125
+ />
126
+ <Form.Control.Feedback type="invalid">
127
+ {errors.endTime?.message}
128
+ </Form.Control.Feedback>
129
+ </Form.Group>
130
+ </Col>
131
+ </Row>
132
+ </>
133
+ );
134
+ }
135
+
136
+ export default RecurrenceAndFrequencyInput;
@@ -12,9 +12,14 @@ import {
12
12
  import { usePreviousValue } from "@licklist/plugins/dist/hooks/Value/usePreviousValue";
13
13
  import { FormProvider, useForm } from "react-hook-form";
14
14
  import { Form } from "react-bootstrap";
15
+ import { WorkHour } from "@licklist/core/dist/DataMapper/Provider/WorkHourDataMapper";
15
16
  import RecurrenceIntervalAndFrequencyInput from "./RecurrenceIntervalAndFrequencyInput";
16
17
  import RecurrenceWeekdaysInput from "./RecurrenceWeekdaysInput";
17
- import { parseAndValidateRRule, SupportedFrequency } from "./utils";
18
+ import {
19
+ parseAndValidateRRule,
20
+ SupportedFrequency,
21
+ useWorkHoursValidationRules,
22
+ } from "./utils";
18
23
  import { ConfirmModal } from "../modals";
19
24
  import { DeleteFieldButton } from "../product-set/elements";
20
25
 
@@ -26,6 +31,7 @@ export interface RecurringDatePickerInputProps {
26
31
  initialFrequency?: Frequency;
27
32
  setInitialStartDateAfterSelect?: boolean;
28
33
  minDate?: string;
34
+ workHours?: WorkHour[];
29
35
  }
30
36
 
31
37
  export interface RecurringDatePickerInputValues {
@@ -51,6 +57,7 @@ export function RecurringDatePickerInput({
51
57
  setInitialStartDateAfterSelect = false,
52
58
  children,
53
59
  minDate,
60
+ workHours,
54
61
  }: PropsWithChildren<RecurringDatePickerInputProps>) {
55
62
  const { t } = useTranslation(["Design"]);
56
63
 
@@ -84,6 +91,8 @@ export function RecurringDatePickerInput({
84
91
  byWeekDay,
85
92
  });
86
93
 
94
+ const validationRules = useWorkHoursValidationRules(byWeekDay, workHours);
95
+
87
96
  const onSubmit = (nextState: RecurringDatePickerInputValues) => {
88
97
  const end = getDateTimeObject(endDate, endTime || "23:59:59");
89
98
 
@@ -188,6 +197,7 @@ export function RecurringDatePickerInput({
188
197
  <RecurrenceIntervalAndFrequencyInput
189
198
  disabled={disabled}
190
199
  minDate={minDate}
200
+ {...validationRules}
191
201
  />
192
202
 
193
203
  {children}
@@ -336,7 +346,10 @@ const useFormattedDuration = ({
336
346
  }, [start, end, byWeekDay, formatList, formatNumber]);
337
347
  };
338
348
 
339
- const getDateTimeObject = (date: string, time: string): DateTime | string => {
349
+ export const getDateTimeObject = (
350
+ date: string,
351
+ time: string
352
+ ): DateTime | string => {
340
353
  const dateTime = DateTime.fromFormat(`${date} ${time}`, DATE_TIME_FORMAT);
341
354
 
342
355
  if (dateTime.isValid) {
@@ -1,4 +1,8 @@
1
+ import { TIME_FORMAT } from "@licklist/core/dist/Config";
2
+ import { WorkHour } from "@licklist/core/dist/DataMapper/Provider/WorkHourDataMapper";
3
+ import { dateTimesSortFn } from "@licklist/plugins/dist/utils/dateTime";
1
4
  import { DateTime } from "luxon";
5
+ import { useTranslation } from "react-i18next";
2
6
  import RRule, { Frequency, Weekday } from "rrule";
3
7
 
4
8
  export const getWeekdayForFrequency = ({
@@ -11,6 +15,7 @@ export const getWeekdayForFrequency = ({
11
15
  const parsedDate = DateTime.fromISO(date);
12
16
  return new Weekday(
13
17
  parsedDate.weekday - 1,
18
+ // eslint-disable-next-line no-nested-ternary
14
19
  frequency !== Frequency.MONTHLY
15
20
  ? undefined
16
21
  : parsedDate.day + 7 > parsedDate.daysInMonth
@@ -109,3 +114,73 @@ export const parseAndValidateRRule = ({
109
114
  until: options.until,
110
115
  } as ParsedRRuleOptions;
111
116
  };
117
+
118
+ export const useWorkHoursValidationRules = (
119
+ byWeekDay: Weekday[] = [],
120
+ workHours: WorkHour[]
121
+ ) => {
122
+ const { t } = useTranslation("Validation");
123
+ // workhours of selected days, all if no days selected
124
+ const selectedWorkHours = byWeekDay.length
125
+ ? byWeekDay.map(({ weekday }) =>
126
+ workHours.find(({ day }) => day === weekday)
127
+ )
128
+ : workHours;
129
+
130
+ /**
131
+ * start time
132
+ */
133
+ const startTimes = selectedWorkHours
134
+ .map((workhour) => DateTime.fromFormat(workhour.start, TIME_FORMAT))
135
+ .sort(dateTimesSortFn("desc"));
136
+
137
+ const latestStartTime = startTimes[0];
138
+
139
+ const startTimeRules = {
140
+ validate: (date: string) => {
141
+ const selectedDate = DateTime.fromFormat(date, TIME_FORMAT);
142
+ if (selectedDate >= latestStartTime) return true;
143
+
144
+ return t("fieldTimeBefore", {
145
+ attribute: t("Design:startTimeSmall"),
146
+ time: latestStartTime.toFormat(TIME_FORMAT),
147
+ });
148
+ },
149
+ };
150
+
151
+ /**
152
+ * end time
153
+ */
154
+ const endTimes = selectedWorkHours
155
+ .map<string>(({ start, end }) => {
156
+ const startDateTime = DateTime.fromFormat(start, TIME_FORMAT);
157
+ const endDateTime = DateTime.fromFormat(end, TIME_FORMAT);
158
+
159
+ if (startDateTime <= endDateTime) return end;
160
+
161
+ // if end is before start, then it means that end is on the next day
162
+ // so count only to the end of current day
163
+ return "23:59";
164
+ })
165
+ .map((workhour) => DateTime.fromFormat(workhour, TIME_FORMAT))
166
+ .sort(dateTimesSortFn("asc"));
167
+
168
+ const earliestEndTime = endTimes[0];
169
+
170
+ const endTimeRules = {
171
+ validate: (date: string) => {
172
+ const selectedDate = DateTime.fromFormat(date, TIME_FORMAT);
173
+ if (selectedDate <= earliestEndTime) return true;
174
+
175
+ return t("fieldTimeAfter", {
176
+ attribute: t("Design:endTimeSmall"),
177
+ time: earliestEndTime.toFormat(TIME_FORMAT),
178
+ });
179
+ },
180
+ };
181
+
182
+ return {
183
+ startTimeRules,
184
+ endTimeRules,
185
+ };
186
+ };