@licklist/design 0.53.0-dev.4 → 0.53.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 (109) hide show
  1. package/dist/auth/Login/LoginComponent.d.ts.map +1 -1
  2. package/dist/auth/Login/LoginComponent.js +1 -1
  3. package/dist/calendar/Calendar.d.ts +8 -3
  4. package/dist/calendar/Calendar.d.ts.map +1 -1
  5. package/dist/calendar/Calendar.js +1 -1
  6. package/dist/calendar/components/CalendarButtons/CalendarButtons.d.ts +2 -2
  7. package/dist/calendar/components/CalendarButtons/CalendarButtons.d.ts.map +1 -1
  8. package/dist/calendar/components/CalendarButtons/CalendarButtons.js +1 -1
  9. package/dist/calendar/components/CalendarDates/CalendarDates.d.ts +2 -2
  10. package/dist/calendar/components/CalendarDates/CalendarDates.d.ts.map +1 -1
  11. package/dist/calendar/components/CalendarDates/CalendarDates.js +1 -1
  12. package/dist/calendar/utils/index.d.ts +2 -0
  13. package/dist/calendar/utils/index.d.ts.map +1 -1
  14. package/dist/calendar/utils/index.js +1 -1
  15. package/dist/date-time-button/DateTimeButton.d.ts +3 -3
  16. package/dist/date-time-button/DateTimeButton.d.ts.map +1 -1
  17. package/dist/events/edit-event-modal/IntervalInput.d.ts.map +1 -1
  18. package/dist/events/edit-event-modal/IntervalInput.js +1 -1
  19. package/dist/events/event-venue-map/components/Scrollbars/Scrollbars.js +1 -1
  20. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts +1 -1
  21. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts.map +1 -1
  22. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.js +1 -1
  23. package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.d.ts +1 -2
  24. package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.d.ts.map +1 -1
  25. package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.js +1 -1
  26. package/dist/iframe/order-process/components/BookingSummary/components/ProductsByMenuStep/ProductsByMenuStep.d.ts +1 -2
  27. package/dist/iframe/order-process/components/BookingSummary/components/ProductsByMenuStep/ProductsByMenuStep.d.ts.map +1 -1
  28. package/dist/iframe/order-process/components/BookingSummary/components/ProductsByMenuStep/ProductsByMenuStep.js +1 -1
  29. package/dist/iframe/order-process/components/BookingSummary/components/ToggleHeader/ToggleHeader.js +1 -1
  30. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts +0 -1
  31. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts.map +1 -1
  32. package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts.map +1 -1
  33. package/dist/iframe/order-process/components/BookingSummary/utils/index.js +1 -1
  34. package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.d.ts.map +1 -1
  35. package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.js +1 -1
  36. package/dist/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.d.ts.map +1 -1
  37. package/dist/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.js +1 -1
  38. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts +1 -2
  39. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts.map +1 -1
  40. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.js +1 -1
  41. package/dist/index.js +1 -1
  42. package/dist/notification/email-template/control/EmailTemplateControl.d.ts.map +1 -1
  43. package/dist/notification/email-template/control/EmailTemplateControl.js +1 -1
  44. package/dist/sales/booking/results/components/ResultCard.d.ts.map +1 -1
  45. package/dist/sales/booking/results/components/ResultCard.js +1 -1
  46. package/dist/sales/manual-booking/summary/ManualBookingSummary.d.ts +1 -2
  47. package/dist/sales/manual-booking/summary/ManualBookingSummary.d.ts.map +1 -1
  48. package/dist/sales/manual-booking/summary/ManualBookingSummary.js +1 -1
  49. package/dist/snippet/snippet-template/preview/Preview.d.ts.map +1 -1
  50. package/dist/snippet/snippet-template/preview/Preview.js +1 -1
  51. package/dist/static/date-range-input/DateRangeInput.d.ts.map +1 -1
  52. package/dist/static/date-range-input/DateRangeInput.js +1 -1
  53. package/dist/styles/resources-blocking/_index.scss +0 -6
  54. package/dist/styles/sales/BookingFilter.scss +2 -24
  55. package/dist/styles/sales/BookingResults.scss +1 -1
  56. package/dist/styles/sales/BookingTabs.scss +5 -63
  57. package/dist/styles/sales/LifeTimeSales.scss +0 -1
  58. package/dist/styles/sales/ManualBooking.scss +3 -62
  59. package/dist/styles/sales/SourceOfSales.scss +0 -3
  60. package/dist/styles/snippet-templates/SnippetTemplate.scss +11 -17
  61. package/dist/styles/snippet-templates/SnippetTemplateCard.scss +2 -3
  62. package/dist/styles/static/Tabs.scss +0 -6
  63. package/dist/styles/themes/bookedit/_index.scss +8 -9
  64. package/dist/styles/themes/bookedit/_variables.scss +0 -2
  65. package/package.json +3 -3
  66. package/src/auth/Login/LoginComponent.tsx +1 -9
  67. package/src/calendar/Calendar.tsx +16 -9
  68. package/src/calendar/components/CalendarButtons/CalendarButtons.tsx +5 -8
  69. package/src/calendar/components/CalendarDates/CalendarDates.tsx +13 -12
  70. package/src/calendar/utils/index.ts +19 -0
  71. package/src/date-time-button/DateTimeButton.tsx +3 -3
  72. package/src/events/edit-event-modal/IntervalInput.tsx +80 -8
  73. package/src/iframe/order-process/components/BookingSummary/BookingSummary.tsx +0 -2
  74. package/src/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.tsx +6 -12
  75. package/src/iframe/order-process/components/BookingSummary/components/ProductsByMenuStep/ProductsByMenuStep.tsx +0 -3
  76. package/src/iframe/order-process/components/BookingSummary/types/index.ts +0 -1
  77. package/src/iframe/order-process/components/BookingSummary/utils/index.ts +4 -2
  78. package/src/iframe/order-process/components/CategoryProduct/CategoryProduct.tsx +23 -16
  79. package/src/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.tsx +3 -10
  80. package/src/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.tsx +3 -9
  81. package/src/notification/email-template/control/EmailTemplateControl.tsx +15 -5
  82. package/src/sales/booking/results/components/ResultCard.tsx +4 -6
  83. package/src/sales/manual-booking/summary/ManualBookingSummary.tsx +1 -9
  84. package/src/snippet/snippet-template/preview/Preview.tsx +0 -3
  85. package/src/static/date-range-input/DateRangeInput.tsx +2 -23
  86. package/src/static/switch/BooleanSwitch.tsx +1 -1
  87. package/src/styles/resources-blocking/_index.scss +0 -6
  88. package/src/styles/sales/BookingFilter.scss +2 -24
  89. package/src/styles/sales/BookingResults.scss +1 -1
  90. package/src/styles/sales/BookingTabs.scss +5 -63
  91. package/src/styles/sales/LifeTimeSales.scss +0 -1
  92. package/src/styles/sales/ManualBooking.scss +3 -62
  93. package/src/styles/sales/SourceOfSales.scss +0 -3
  94. package/src/styles/snippet-templates/SnippetTemplate.scss +11 -17
  95. package/src/styles/snippet-templates/SnippetTemplateCard.scss +2 -3
  96. package/src/styles/static/Tabs.scss +0 -6
  97. package/src/styles/themes/bookedit/_index.scss +8 -9
  98. package/src/styles/themes/bookedit/_variables.scss +0 -2
  99. package/dist/events/edit-event-modal/hooks/index.d.ts +0 -3
  100. package/dist/events/edit-event-modal/hooks/index.d.ts.map +0 -1
  101. package/dist/events/edit-event-modal/hooks/useFormattedDuration.d.ts +0 -2
  102. package/dist/events/edit-event-modal/hooks/useFormattedDuration.d.ts.map +0 -1
  103. package/dist/events/edit-event-modal/hooks/useFormattedDuration.js +0 -1
  104. package/dist/events/edit-event-modal/hooks/useValidationOptions.d.ts +0 -11
  105. package/dist/events/edit-event-modal/hooks/useValidationOptions.d.ts.map +0 -1
  106. package/dist/events/edit-event-modal/hooks/useValidationOptions.js +0 -1
  107. package/src/events/edit-event-modal/hooks/index.ts +0 -2
  108. package/src/events/edit-event-modal/hooks/useFormattedDuration.tsx +0 -40
  109. package/src/events/edit-event-modal/hooks/useValidationOptions.tsx +0 -36
@@ -13,9 +13,6 @@
13
13
 
14
14
  &__pie-chart {
15
15
  height: 100%;
16
- @include media-breakpoint-down(sm) {
17
- height: 12rem;
18
- }
19
16
  }
20
17
 
21
18
  .colors-0 {
@@ -59,8 +59,7 @@
59
59
  color: $snippet-elements-button-color;
60
60
  border: none;
61
61
  background-color: $snippet-elements-button-background-color;
62
- box-shadow: 0 0 0 $input-btn-focus-width
63
- $snippet-elements-button-background-color;
62
+ box-shadow: 0 0 0 $input-btn-focus-width $snippet-elements-button-background-color;
64
63
  }
65
64
 
66
65
  &:disabled {
@@ -73,14 +72,14 @@
73
72
  &:focus,
74
73
  &.focus {
75
74
  &:not(:disabled) {
76
- opacity: 0.7;
75
+ opacity: .7;
77
76
  }
78
77
  }
79
78
 
80
79
  &:active,
81
80
  &.active {
82
81
  &:not(:disabled) {
83
- opacity: 0.8;
82
+ opacity: .8;
84
83
  }
85
84
  }
86
85
  }
@@ -91,7 +90,7 @@
91
90
  }
92
91
 
93
92
  &__label {
94
- font-size: 0.8rem;
93
+ font-size: .8rem;
95
94
  margin-top: 1rem;
96
95
  margin-bottom: 0.2rem;
97
96
  }
@@ -104,8 +103,8 @@
104
103
  position: absolute;
105
104
  top: 0;
106
105
  right: 0;
107
- margin-right: 0.5rem;
108
- margin-top: 0.5rem;
106
+ margin-right: .5rem;
107
+ margin-top: .5rem;
109
108
  }
110
109
 
111
110
  .form-label {
@@ -182,8 +181,7 @@
182
181
  color: $snippet-elements-button-color;
183
182
  border: none;
184
183
  background-color: $snippet-elements-button-background-color;
185
- box-shadow: 0 0 0 $input-btn-focus-width
186
- $snippet-elements-button-background-color;
184
+ box-shadow: 0 0 0 $input-btn-focus-width $snippet-elements-button-background-color;
187
185
  }
188
186
 
189
187
  &:disabled {
@@ -196,14 +194,14 @@
196
194
  &:focus,
197
195
  &.focus {
198
196
  &:not(:disabled) {
199
- opacity: 0.7;
197
+ opacity: .7;
200
198
  }
201
199
  }
202
200
 
203
201
  &:active,
204
202
  &.active {
205
203
  &:not(:disabled) {
206
- opacity: 0.8;
204
+ opacity: .8;
207
205
  }
208
206
  }
209
207
  }
@@ -338,8 +336,7 @@
338
336
  }
339
337
  }
340
338
 
341
- .bottom-wrapper,
342
- .snippet-template__form {
339
+ .bottom-wrapper, .snippet-template__form {
343
340
  .btn {
344
341
  border-radius: 0.25rem;
345
342
  width: 100%;
@@ -384,10 +381,6 @@
384
381
  }
385
382
  }
386
383
 
387
- .disabled-number-input-button {
388
- background-color: $snippet-calendar-disabled-button-font-color !important;
389
- border-color: $snippet-calendar-disabled-button-font-color !important;
390
- }
391
384
  .color-picker {
392
385
  &__color {
393
386
  position: absolute;
@@ -449,6 +442,7 @@
449
442
  }
450
443
  }
451
444
  }
445
+
452
446
  }
453
447
 
454
448
  @include media-breakpoint-down(xs) {
@@ -28,13 +28,12 @@ $snippet-template-card-button-transition: $product-set-card-transition !default;
28
28
  border: 1px solid #ccc;
29
29
  border-radius: $border-radius;
30
30
  height: 10rem;
31
- min-width: 15rem;
31
+ width: 15rem;
32
32
  padding: 1rem;
33
33
 
34
34
  @include media-breakpoint-down(sm) {
35
35
  height: 100%;
36
36
  max-height: 10rem;
37
- width: 100%;
38
37
  }
39
38
 
40
39
  p {
@@ -110,4 +109,4 @@ $snippet-template-card-button-transition: $product-set-card-transition !default;
110
109
  &:hover {
111
110
  border: 2px solid $blue;
112
111
  }
113
- }
112
+ }
@@ -11,12 +11,6 @@ $tab-nav-link-active-border-bottom: 1px solid $tab-nav-link-active-color !defaul
11
11
  margin-left: -1.25rem;
12
12
  border-bottom: 1px solid $nav-tabs-border-color;
13
13
 
14
- @include media-breakpoint-down(sm) {
15
- display: flex;
16
- flex-direction: column;
17
- white-space: nowrap;
18
- }
19
-
20
14
  .nav-link {
21
15
  color: $tab-nav-link-color;
22
16
  background-color: transparent;
@@ -98,8 +98,7 @@
98
98
  color: gray("600");
99
99
 
100
100
  &.sortable {
101
- &::before,
102
- &::after {
101
+ &::before, &::after {
103
102
  opacity: 1;
104
103
  }
105
104
 
@@ -133,20 +132,20 @@
133
132
  width: 2.5rem;
134
133
  height: 2.5rem;
135
134
  background-color: transparent;
136
-
135
+
137
136
  svg {
138
137
  margin-bottom: 2.5px;
139
138
  }
140
139
 
141
140
  &:hover {
142
141
  cursor: pointer;
143
- border-radius: 0.5rem;
142
+ border-radius: .5rem;
144
143
  background-color: lighten($primary, 40);
145
144
  }
146
145
  }
147
146
 
148
147
  .page-item {
149
- margin-left: 0.4rem;
148
+ margin-left: .4rem;
150
149
  min-width: 15px;
151
150
  width: 2.5rem;
152
151
  height: 2.5rem;
@@ -154,7 +153,7 @@
154
153
  .page-link {
155
154
  border: 0;
156
155
  padding: 0;
157
- border-radius: 0.5rem;
156
+ border-radius: .5rem;
158
157
  height: 100%;
159
158
  display: flex;
160
159
  align-items: center;
@@ -163,13 +162,13 @@
163
162
  color: $black;
164
163
  font-weight: 600;
165
164
  font-size: 0.875rem;
166
-
165
+
167
166
  &:hover {
168
- border-radius: 0.5rem;
167
+ border-radius: .5rem;
169
168
  background-color: lighten($primary, 40);
170
169
  }
171
170
  }
172
-
171
+
173
172
  &.active {
174
173
  .page-link {
175
174
  border: 2px solid $primary;
@@ -197,7 +197,6 @@ $grid-breakpoints: (
197
197
  md: 768px,
198
198
  lg: 992px,
199
199
  xl: 1200px,
200
- xxl: 1500px,
201
200
  ) !default;
202
201
 
203
202
  @include _assert-ascending($grid-breakpoints, "$grid-breakpoints");
@@ -212,7 +211,6 @@ $container-max-widths: (
212
211
  md: 720px,
213
212
  lg: 960px,
214
213
  xl: 1140px,
215
- xxl: 1500px,
216
214
  ) !default;
217
215
 
218
216
  @include _assert-ascending($container-max-widths, "$container-max-widths");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@licklist/design",
3
- "version": "0.53.0-dev.4",
3
+ "version": "0.53.0",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@bitbucket.org/artelogicsoft/licklist_design.git"
@@ -53,9 +53,9 @@
53
53
  "@fortawesome/free-brands-svg-icons": "5.15.2",
54
54
  "@fortawesome/free-solid-svg-icons": "5.15.2",
55
55
  "@fortawesome/react-fontawesome": "0.1.9",
56
- "@licklist/core": ">=0.15.41-dev.0 < 0.15.41",
56
+ "@licklist/core": "^0.17.0",
57
57
  "@licklist/eslint-config": "0.3.4",
58
- "@licklist/plugins": ">=0.24.0-dev.0 < 0.24.0",
58
+ "@licklist/plugins": "^0.25.0",
59
59
  "@mdx-js/react": "1.6.22",
60
60
  "@popperjs/core": "2.11.8",
61
61
  "@react-aria/utils": "3.9.0",
@@ -1,4 +1,4 @@
1
- import React, { useContext, useEffect, useState } from "react";
1
+ import React, { useContext, useState } from "react";
2
2
  import Row from "react-bootstrap/Row";
3
3
  import Col from "react-bootstrap/Col";
4
4
  import { Trans, useTranslation } from "react-i18next";
@@ -90,14 +90,6 @@ const LoginComponent = ({
90
90
  RouteService.redirectTo("/");
91
91
  };
92
92
 
93
- useEffect(() => {
94
- if (!user.profile || !auth.secrets) {
95
- return;
96
- }
97
-
98
- RouteService.redirectTo("/");
99
- }, [user.profile, auth.secrets]);
100
-
101
93
  return (
102
94
  <Router>
103
95
  <Row className="justify-content-center">
@@ -1,9 +1,12 @@
1
1
  import React, { Dispatch, ReactElement, SetStateAction } from "react";
2
2
  import { DateTime } from "luxon";
3
- import { DateTimeButtonProps } from "src/date-time-button";
3
+ import { ZoneResourcesAvailability } from "@licklist/core/dist/DataMapper/Order/ZoneResourcesAvailabilityDataMapper";
4
4
  import { CalendarButtons } from "./components/CalendarButtons";
5
5
  import { CalendarDates } from "./components/CalendarDates";
6
6
 
7
+ // same as apps/iframe/src/types/availability.ts
8
+ export type AvailableTimes = Record<string, string[]>;
9
+
7
10
  export const defaultStartDay = DateTime.now().set({
8
11
  millisecond: 0,
9
12
  second: 0,
@@ -15,28 +18,32 @@ export type CalendarProps = {
15
18
  currentDate: DateTime;
16
19
  setCurrentDate: Dispatch<SetStateAction<DateTime>>;
17
20
  calendarDates: DateTime[];
21
+ disabledDates?: DateTime[];
18
22
  selectedDate: DateTime | null;
19
23
  setSelectedDate: Dispatch<SetStateAction<DateTime | null>>;
20
24
  fromPrice?: string | ReactElement | null;
21
25
  isLoading?: boolean;
22
26
  initialDate?: DateTime;
23
- getDateTimeButtonProps: (
24
- date: DateTime
25
- ) => Pick<
26
- DateTimeButtonProps,
27
- "resources" | "showResources" | "shouldCalculateResources" | "isDisabled"
28
- >;
27
+ getAvailability?: (date: DateTime) => ZoneResourcesAvailability | null;
28
+ includeAvailability?: boolean;
29
+ availableTimes?: AvailableTimes;
30
+ shouldCalculateResources?: boolean;
29
31
  };
30
32
 
31
33
  export const Calendar = ({
34
+ disabledDates = [],
32
35
  initialDate = defaultStartDay,
33
36
  ...props
34
37
  }: CalendarProps) => {
35
38
  return (
36
39
  <div className="calendar-wrapper">
37
40
  <div className="calendar">
38
- <CalendarButtons initialDate={initialDate} {...props} />
39
- <CalendarDates {...props} />
41
+ <CalendarButtons
42
+ disabledDates={disabledDates}
43
+ initialDate={initialDate}
44
+ {...props}
45
+ />
46
+ <CalendarDates disabledDates={disabledDates} {...props} />
40
47
  </div>
41
48
  </div>
42
49
  );
@@ -4,25 +4,26 @@ import { useTranslation } from "react-i18next";
4
4
  import { range } from "lodash";
5
5
  import { ReactComponent as SelectArrow } from "../../../assets/iframe/selectArrow.svg";
6
6
  import { CalendarSelect } from "../CalendarSelect";
7
+ import { isDateDisabled } from "../../utils";
7
8
  import { CalendarProps } from "../../Calendar";
8
9
 
9
10
  type CalendarButtonsProps = Pick<
10
11
  CalendarProps,
11
12
  | "isLoading"
13
+ | "disabledDates"
12
14
  | "initialDate"
13
15
  | "currentDate"
14
16
  | "setCurrentDate"
15
17
  | "setSelectedDate"
16
- | "getDateTimeButtonProps"
17
18
  >;
18
19
 
19
20
  export const CalendarButtons = ({
21
+ disabledDates = [],
20
22
  isLoading = false,
21
23
  initialDate,
22
24
  currentDate,
23
25
  setCurrentDate,
24
26
  setSelectedDate,
25
- getDateTimeButtonProps,
26
27
  }: CalendarButtonsProps) => {
27
28
  const { t } = useTranslation("Design");
28
29
 
@@ -65,9 +66,7 @@ export const CalendarButtons = ({
65
66
  const onTodayClick = () => {
66
67
  setCurrentDate(initialDate);
67
68
 
68
- const { isDisabled } = getDateTimeButtonProps(initialDate);
69
-
70
- if (isDisabled) return;
69
+ if (isDateDisabled(initialDate, disabledDates)) return;
71
70
 
72
71
  setSelectedDate(initialDate);
73
72
  };
@@ -76,9 +75,7 @@ export const CalendarButtons = ({
76
75
  const nextDate = initialDate.set({ day: initialDate.day + 1 });
77
76
  setCurrentDate(nextDate);
78
77
 
79
- const { isDisabled } = getDateTimeButtonProps(initialDate);
80
-
81
- if (isDisabled) return;
78
+ if (isDateDisabled(nextDate, disabledDates)) return;
82
79
 
83
80
  setSelectedDate(nextDate);
84
81
  };
@@ -2,25 +2,25 @@ import React, { useMemo } from "react";
2
2
  import { DateTime } from "luxon";
3
3
  import { DateTimeButton, Variant } from "../../../date-time-button";
4
4
  import { CalendarWeekdays } from "../CalendarWeekdays";
5
+ import { isDateDisabled } from "../../utils";
5
6
  import { CalendarProps } from "../../Calendar";
6
7
 
7
- export type CalendarDatesProps = Pick<
8
+ export type CalendarDatesProps = Omit<
8
9
  CalendarProps,
9
- | "isLoading"
10
- | "calendarDates"
11
- | "selectedDate"
12
- | "setSelectedDate"
13
- | "fromPrice"
14
- | "getDateTimeButtonProps"
10
+ "currentDate" | "setCurrentDate" | "initialDate"
15
11
  >;
16
12
 
17
13
  export const CalendarDates = ({
14
+ disabledDates = [],
18
15
  isLoading = false,
19
16
  calendarDates,
20
17
  selectedDate,
21
18
  setSelectedDate,
22
19
  fromPrice,
23
- getDateTimeButtonProps,
20
+ getAvailability,
21
+ includeAvailability,
22
+ shouldCalculateResources,
23
+ availableTimes,
24
24
  }: CalendarDatesProps) => {
25
25
  const fillCalendarDates = useMemo(() => {
26
26
  let firstDayOfWeek = calendarDates[0]?.weekday ?? 0;
@@ -46,9 +46,8 @@ export const CalendarDates = ({
46
46
  {fillCalendarDates.map((date: DateTime | null) => {
47
47
  if (date === null) return <div />;
48
48
 
49
- const props = getDateTimeButtonProps(date);
50
-
51
- const isDisabled = isLoading || props.isDisabled;
49
+ const isDisabled =
50
+ isLoading || isDateDisabled(date, disabledDates, availableTimes);
52
51
 
53
52
  return (
54
53
  <DateTimeButton
@@ -60,8 +59,10 @@ export const CalendarDates = ({
60
59
  date={date}
61
60
  onSelect={() => setSelectedDate(date)}
62
61
  price={fromPrice}
62
+ resources={getAvailability?.(date)}
63
+ showResources={includeAvailability}
63
64
  variant={Variant.month}
64
- {...props}
65
+ shouldCalculateResources={shouldCalculateResources}
65
66
  />
66
67
  );
67
68
  })}
@@ -1,4 +1,23 @@
1
1
  import { DateTime, Interval } from "luxon";
2
+ import isEqual from "lodash/isEqual";
3
+ import { DATE_FORMAT } from "@licklist/core/dist/Config";
4
+ import { AvailableTimes } from "../Calendar";
5
+
6
+ export const isDateDisabled = (
7
+ date: DateTime,
8
+ disabledDates: DateTime[] = [],
9
+ availableTimes?: AvailableTimes
10
+ ): boolean => {
11
+ const disabledByDates = !!disabledDates.find((disabledDate) =>
12
+ isEqual(disabledDate.toObject(), date.toObject())
13
+ );
14
+
15
+ const noAvailableTimes = availableTimes
16
+ ? !availableTimes?.[date.toFormat(DATE_FORMAT)]
17
+ : false;
18
+
19
+ return disabledByDates || noAvailableTimes;
20
+ };
2
21
 
3
22
  export const getMonthCalendarDates = (initialDate: DateTime): DateTime[] => {
4
23
  const startOfMonth = initialDate.startOf("month");
@@ -14,12 +14,12 @@ export enum Variant {
14
14
 
15
15
  export type DateTimeButtonProps = {
16
16
  date: DateTime;
17
- isSelected: boolean;
18
- isDisabled: boolean;
17
+ isSelected?: boolean;
18
+ isDisabled?: boolean;
19
19
  isSoldOut?: boolean;
20
20
  onSelect: (date: DateTime) => void;
21
21
  price?: string | number | ReactElement | null;
22
- resources?: ZoneResourcesAvailability | null;
22
+ resources: ZoneResourcesAvailability | null | undefined;
23
23
  showResources?: boolean;
24
24
  shouldCalculateResources?: boolean;
25
25
  variant: Variant;
@@ -1,8 +1,9 @@
1
- import React, { useState, useRef, useEffect } from "react";
2
- import { DateTime } from "luxon";
1
+ import React, { useMemo, useState, useRef, useEffect } from "react";
2
+ import { DateTime, Interval } from "luxon";
3
3
  import { Col, Form } from "react-bootstrap";
4
- import { Controller, useFormContext, useWatch } from "react-hook-form";
4
+ import { Controller, RegisterOptions, useFormContext } from "react-hook-form";
5
5
  import { useTranslation } from "react-i18next";
6
+ import { useIntl } from "react-intl";
6
7
 
7
8
  import { useId } from "@react-aria/utils";
8
9
  import { ProductSet } from "@licklist/core/dist/DataMapper/Product/ProductSetDataMapper";
@@ -10,7 +11,6 @@ import HTMLInputDateElement from "../../types/static/HTMLInputDateElement";
10
11
  import { RecurrenceInput } from "../../recurrence-input";
11
12
  import { WarningMessage } from "../../static";
12
13
  import { ProductSetFormValues } from "../../product-set/form";
13
- import { useFormattedDuration, useValidationOptions } from "./hooks";
14
14
 
15
15
  interface IntervalInputProps {
16
16
  editedProductSet?: ProductSetFormValues;
@@ -35,6 +35,7 @@ export function IntervalInput({
35
35
  const {
36
36
  register,
37
37
  formState: { errors },
38
+ watch,
38
39
  control,
39
40
  trigger,
40
41
  setValue,
@@ -43,9 +44,9 @@ export function IntervalInput({
43
44
  const formattedDuration = useFormattedDuration();
44
45
  const validationOptions = useValidationOptions();
45
46
 
46
- const rrule = useWatch({ control, name: "rrule" });
47
- const start = useWatch({ control, name: "start" });
48
- const end = useWatch({ control, name: "end" });
47
+ const rrule = watch("rrule");
48
+ const start = watch("start");
49
+ const end = watch("end");
49
50
  const [recurrent, setRecurrent] = useState(Boolean(rrule));
50
51
  const [isOverriden, setIsOverriden] = useState(false);
51
52
  const recurrentId = useId();
@@ -122,7 +123,6 @@ export function IntervalInput({
122
123
  onChangeEndDate(nextEndtDate)
123
124
  }
124
125
  min={start}
125
- required
126
126
  isInvalid={Boolean(errors.end)}
127
127
  onClick={() => endDateInput?.current?.showPicker()}
128
128
  ref={endDateInput}
@@ -180,3 +180,75 @@ export function IntervalInput({
180
180
  </>
181
181
  );
182
182
  }
183
+
184
+ const useFormattedDuration = () => {
185
+ const { watch } = useFormContext<IntervalInputValues>();
186
+ const start = watch("start");
187
+ const end = watch("end");
188
+ const { formatList, formatNumber } = useIntl();
189
+
190
+ return useMemo(() => {
191
+ const interval = Interval.fromDateTimes(
192
+ DateTime.fromISO(start),
193
+ DateTime.fromISO(end)
194
+ ).toDuration(["days", "hours", "minutes"]);
195
+
196
+ if (!interval.isValid) return undefined;
197
+
198
+ const formatUnit = (value: number, unit: string) =>
199
+ formatNumber(value, { style: "unit", unit, unitDisplay: "long" });
200
+
201
+ const units = (
202
+ [
203
+ [interval.days, "day"],
204
+ [interval.hours, "hour"],
205
+ [interval.minutes, "minute"],
206
+ ] as Parameters<typeof formatUnit>[]
207
+ ).filter(([value]) => value);
208
+
209
+ return formatList(
210
+ units.map((args) => formatUnit(...args)),
211
+ { style: "long", type: "unit" }
212
+ );
213
+ // eslint-disable-next-line react-hooks/exhaustive-deps
214
+ }, [start, end]);
215
+ };
216
+
217
+ const useValidationOptions = () => {
218
+ const { watch } = useFormContext();
219
+ const { t } = useTranslation(["Design", "Validation"]);
220
+ const start = watch("start");
221
+ const end = watch("end");
222
+
223
+ return {
224
+ start: useMemo<RegisterOptions>(
225
+ () => ({
226
+ required: t("Validation:fieldRequired", {
227
+ attribute: t("start"),
228
+ }) as string,
229
+ // TODO: uncomment when event splitting is implemented
230
+ // and extract into plugins
231
+ validate: (value) =>
232
+ DateTime.fromISO(value).diffNow().toMillis() > 0 ||
233
+ (t("Validation:fieldValidEventStart") as string),
234
+ }),
235
+ // eslint-disable-next-line react-hooks/exhaustive-deps
236
+ []
237
+ ),
238
+
239
+ end: useMemo<RegisterOptions>(
240
+ () => ({
241
+ // TODO: uncomment when event splitting is implemented
242
+ // and extract into plugins
243
+ validate: (value) =>
244
+ // endAt not required
245
+ value
246
+ ? DateTime.fromISO(value).diff(DateTime.fromISO(start)).toMillis() >
247
+ 0 || (t("Validation:fieldValidEventEnd") as string)
248
+ : true,
249
+ }),
250
+ // eslint-disable-next-line react-hooks/exhaustive-deps
251
+ [start, end]
252
+ ),
253
+ };
254
+ };
@@ -20,7 +20,6 @@ export const BookingSummary = ({
20
20
  productsWithErrors = [],
21
21
  isLoading,
22
22
  hasPeopleInput,
23
- isPaymentLink,
24
23
  peopleAmount,
25
24
  }: Omit<BookingSummaryProps, "totallWithDiscount">) => {
26
25
  const { t } = useTranslation("Design");
@@ -50,7 +49,6 @@ export const BookingSummary = ({
50
49
  <div className="products-by-menu-step">
51
50
  {menuSteps.map((menuStep) => (
52
51
  <ProductsByMenuStep
53
- isPaymentLink={isPaymentLink}
54
52
  key={menuStep.id}
55
53
  orderItems={formValues}
56
54
  step={menuStep}
@@ -8,27 +8,21 @@ type ProductSummaryProps = {
8
8
  name?: string;
9
9
  productQuantityError?: string;
10
10
  orderProduct: OrderItem;
11
- isPaymentLink?: boolean;
12
11
  };
13
12
 
14
13
  export const ProductSummary = ({
15
14
  name,
16
15
  productQuantityError,
17
16
  orderProduct,
18
- isPaymentLink,
19
17
  }: ProductSummaryProps) => {
20
18
  const { t } = useTranslation("Design");
21
19
  const { formatNumber } = useIntl();
22
20
 
23
- const priceForOneProduct =
24
- !isPaymentLink && orderProduct?.hasDeposit
25
- ? orderProduct?.deposit
26
- : orderProduct?.price;
27
-
28
- const fullPrice = formatNumber(priceForOneProduct * orderProduct?.quantity, {
29
- style: "currency",
30
- currency: Config.Currency.GBP,
31
- });
21
+ const price = formatNumber(
22
+ (orderProduct?.deposit || orderProduct?.price || 0) *
23
+ orderProduct?.quantity,
24
+ { style: "currency", currency: Config.Currency.GBP }
25
+ );
32
26
 
33
27
  return (
34
28
  <div className="product">
@@ -38,7 +32,7 @@ export const ProductSummary = ({
38
32
  {t("shortQuantity")}:&nbsp;{orderProduct?.quantity}
39
33
  </p>
40
34
 
41
- <p className="price">{fullPrice}</p>
35
+ <p className="price">{price}</p>
42
36
  </div>
43
37
 
44
38
  {productQuantityError && (
@@ -29,14 +29,12 @@ export type ProductsByMenuStepsProps = {
29
29
  orderItems: OrderItems;
30
30
  step: MenuStep;
31
31
  productsWithErrors?: QuantityCheckProductInfo[];
32
- isPaymentLink?: boolean;
33
32
  };
34
33
 
35
34
  export const ProductsByMenuStep = ({
36
35
  orderItems,
37
36
  step,
38
37
  productsWithErrors = [],
39
- isPaymentLink,
40
38
  }: ProductsByMenuStepsProps) => {
41
39
  const { productCategories } = step;
42
40
 
@@ -64,7 +62,6 @@ export const ProductsByMenuStep = ({
64
62
 
65
63
  return (
66
64
  <ProductSummary
67
- isPaymentLink={isPaymentLink}
68
65
  key={orderItem.id}
69
66
  name={orderItem.name}
70
67
  productQuantityError={productQuantityError}
@@ -19,5 +19,4 @@ export type BookingSummaryProps = {
19
19
  productsWithErrors?: QuantityCheckProductInfo[];
20
20
  isLoading?: boolean;
21
21
  peopleAmount: number;
22
- isPaymentLink?: boolean;
23
22
  };