@licklist/design 0.44.486-dev.2 → 0.44.486-dev.21

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 (182) hide show
  1. package/dist/assets/iframe/available.svg.js +1 -0
  2. package/dist/assets/iframe/limited.svg.js +1 -0
  3. package/dist/assets/iframe/soldOut.svg.js +1 -0
  4. package/dist/collapsible-input-group/CollapsibleInputGroup.js +1 -1
  5. package/dist/date-time-button/DateTimeButton.d.ts +5 -1
  6. package/dist/date-time-button/DateTimeButton.d.ts.map +1 -1
  7. package/dist/date-time-button/DateTimeButton.js +1 -1
  8. package/dist/events/edit-event-modal/IntervalInput.d.ts.map +1 -1
  9. package/dist/events/edit-event-modal/IntervalInput.js +1 -1
  10. package/dist/events/event-venue-map/hooks/useImage.d.ts.map +1 -1
  11. package/dist/events/event-venue-map/hooks/useImage.js +1 -1
  12. package/dist/iframe/activity-card/ActivityCard.d.ts +17 -0
  13. package/dist/iframe/activity-card/ActivityCard.d.ts.map +1 -0
  14. package/dist/iframe/activity-card/ActivityCard.js +1 -0
  15. package/dist/iframe/activity-card/index.d.ts +2 -0
  16. package/dist/iframe/activity-card/index.d.ts.map +1 -0
  17. package/dist/iframe/event/event-calendar/EventCalendar.d.ts +5 -3
  18. package/dist/iframe/event/event-calendar/EventCalendar.d.ts.map +1 -1
  19. package/dist/iframe/event/event-calendar/EventCalendar.js +1 -1
  20. package/dist/iframe/event/event-calendar/components/CalendarDate/CalendarDate.d.ts +3 -2
  21. package/dist/iframe/event/event-calendar/components/CalendarDate/CalendarDate.d.ts.map +1 -1
  22. package/dist/iframe/event/event-calendar/components/CalendarDate/CalendarDate.js +1 -1
  23. package/dist/iframe/event/event-calendar/components/CalendarDates/CalendarDates.d.ts +5 -3
  24. package/dist/iframe/event/event-calendar/components/CalendarDates/CalendarDates.d.ts.map +1 -1
  25. package/dist/iframe/event/event-calendar/components/CalendarDates/CalendarDates.js +1 -1
  26. package/dist/iframe/index.d.ts +1 -1
  27. package/dist/iframe/index.d.ts.map +1 -1
  28. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts +1 -1
  29. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts.map +1 -1
  30. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.js +1 -1
  31. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts +1 -0
  32. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts.map +1 -1
  33. package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts.map +1 -1
  34. package/dist/iframe/order-process/components/BookingSummary/utils/index.js +1 -1
  35. package/dist/iframe/order-process/components/CalendarStepsForm/CalendarStepsForm.d.ts +1 -1
  36. package/dist/iframe/order-process/components/CalendarStepsForm/CalendarStepsForm.d.ts.map +1 -1
  37. package/dist/iframe/order-process/components/CalendarStepsForm/CalendarStepsForm.js +1 -1
  38. package/dist/iframe/order-process/components/utils/useCategoryVerification.d.ts +3 -2
  39. package/dist/iframe/order-process/components/utils/useCategoryVerification.d.ts.map +1 -1
  40. package/dist/iframe/order-process/components/utils/useCategoryVerification.js +1 -1
  41. package/dist/iframe/page/components/PageBody/components/LeftBlock/LeftBlock.d.ts.map +1 -1
  42. package/dist/iframe/page/components/PageBody/components/LeftBlock/LeftBlock.js +1 -1
  43. package/dist/iframe/payment/order-items-table/hooks/useTableData.d.ts.map +1 -1
  44. package/dist/iframe/payment/order-items-table/hooks/useTableData.js +1 -1
  45. package/dist/iframe/payment/order-items-table/types/index.d.ts +7 -1
  46. package/dist/iframe/payment/order-items-table/types/index.d.ts.map +1 -1
  47. package/dist/iframe/payment/order-items-table/types/index.js +1 -0
  48. package/dist/iframe/payment/order-items-table/utils/paymentSummary.d.ts +3 -0
  49. package/dist/iframe/payment/order-items-table/utils/paymentSummary.d.ts.map +1 -0
  50. package/dist/iframe/payment/order-items-table/utils/paymentSummary.js +1 -0
  51. package/dist/index.js +1 -1
  52. package/dist/notification/email-template/control/EmailTemplateControl.d.ts.map +1 -1
  53. package/dist/notification/email-template/control/EmailTemplateControl.js +1 -1
  54. package/dist/product-set/form/ProductCategoriesControl.d.ts.map +1 -1
  55. package/dist/product-set/form/ProductCategoriesControl.js +1 -1
  56. package/dist/product-set/form/ProductsControl.d.ts +3 -1
  57. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  58. package/dist/product-set/form/ProductsControl.js +1 -1
  59. package/dist/product-set/product/ProductControl.d.ts +2 -1
  60. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  61. package/dist/product-set/product/ProductControl.js +1 -1
  62. package/dist/product-set/product/duration/ProductDurationControl.js +1 -1
  63. package/dist/product-set/product-category/ProductCategoryControl.d.ts.map +1 -1
  64. package/dist/product-set/product-category/ProductCategoryControl.js +1 -1
  65. package/dist/provider/working-hours-input/WorkingHoursInputDescription.d.ts.map +1 -1
  66. package/dist/provider/working-hours-input/WorkingHoursInputDescription.js +1 -1
  67. package/dist/recurrence-input/RecurrenceEndInput.d.ts +2 -1
  68. package/dist/recurrence-input/RecurrenceEndInput.d.ts.map +1 -1
  69. package/dist/recurrence-input/RecurrenceEndInput.js +1 -1
  70. package/dist/recurrence-input/RecurrenceInput.d.ts +2 -1
  71. package/dist/recurrence-input/RecurrenceInput.d.ts.map +1 -1
  72. package/dist/recurrence-input/RecurrenceInput.js +1 -1
  73. package/dist/recurring-date-picker-input/RecurrenceIntervalAndFrequencyInput.d.ts +4 -1
  74. package/dist/recurring-date-picker-input/RecurrenceIntervalAndFrequencyInput.d.ts.map +1 -1
  75. package/dist/recurring-date-picker-input/RecurrenceIntervalAndFrequencyInput.js +1 -1
  76. package/dist/report/form/ReportForm.d.ts.map +1 -1
  77. package/dist/snippet/snippet-template/preview/Preview.js +1 -1
  78. package/dist/static/CountryCodeSelect.d.ts.map +1 -1
  79. package/dist/static/CountryCodeSelect.js +1 -1
  80. package/dist/static/RestrictedAccess.d.ts.map +1 -1
  81. package/dist/static/form-number-input/FormNumberInput.d.ts +2 -1
  82. package/dist/static/form-number-input/FormNumberInput.d.ts.map +1 -1
  83. package/dist/static/form-number-input/FormNumberInput.js +1 -1
  84. package/dist/styles/{iframe-customers-journey/ActivitiesCard.scss → activity-card/GridActivitiesCard.scss} +1 -1
  85. package/dist/styles/{iframe-customers-journey/ActivitiesSelectedCard.scss → activity-card/ListActivitiesCard.scss} +2 -1
  86. package/dist/styles/activity-card/_index.scss +2 -0
  87. package/dist/styles/{iframe-customers-journey → date-time-button}/DateTimeButton.scss +3 -6
  88. package/dist/styles/date-time-button/_index.scss +1 -0
  89. package/dist/styles/iframe-events/Calendar.scss +14 -14
  90. package/dist/styles/iframe-page/PageBody.scss +3 -2
  91. package/dist/styles/notification/Notification.scss +4 -0
  92. package/dist/styles/packages.scss +2 -1
  93. package/dist/styles/resources-blocking/_index.scss +5 -0
  94. package/dist/styles/themes/bookedit/_index.scss +1 -0
  95. package/dist/zone/form/components/AvailableTimesControl.d.ts.map +1 -1
  96. package/dist/zone/form/components/AvailableTimesControl.js +1 -1
  97. package/dist/zone/form/components/GameDurationControl.d.ts +7 -0
  98. package/dist/zone/form/components/GameDurationControl.d.ts.map +1 -0
  99. package/dist/zone/form/components/GameDurationControl.js +1 -0
  100. package/dist/zone/form/components/ZoneControl.d.ts.map +1 -1
  101. package/dist/zone/form/components/ZoneControl.js +1 -1
  102. package/dist/zone/form/components/ZoneRecurrencesControl.d.ts.map +1 -1
  103. package/dist/zone/form/components/ZoneRecurrencesControl.js +1 -1
  104. package/dist/zone/form/utils/dates.d.ts.map +1 -1
  105. package/dist/zone/form/utils/dates.js +1 -1
  106. package/package.json +1 -1
  107. package/src/collapsible-input-group/CollapsibleInputGroup.tsx +1 -1
  108. package/src/date-time-button/DateTimeButton.stories.tsx +17 -0
  109. package/src/date-time-button/DateTimeButton.tsx +42 -20
  110. package/src/events/edit-event-modal/IntervalInput.tsx +3 -0
  111. package/src/events/event-venue-map/hooks/useImage.tsx +17 -8
  112. package/src/iframe/{activity-cards/activity-card → activity-card}/ActivityCard.stories.tsx +24 -1
  113. package/src/iframe/activity-card/ActivityCard.tsx +77 -0
  114. package/src/iframe/activity-card/index.ts +1 -0
  115. package/src/iframe/event/event-calendar/EventCalendar.stories.tsx +20 -21
  116. package/src/iframe/event/event-calendar/EventCalendar.tsx +10 -3
  117. package/src/iframe/event/event-calendar/components/CalendarDate/CalendarDate.tsx +10 -2
  118. package/src/iframe/event/event-calendar/components/CalendarDates/CalendarDates.tsx +6 -2
  119. package/src/iframe/index.ts +1 -1
  120. package/src/iframe/order-process/components/BookingSummary/BookingSummary.tsx +2 -0
  121. package/src/iframe/order-process/components/BookingSummary/types/index.ts +1 -0
  122. package/src/iframe/order-process/components/BookingSummary/utils/index.ts +2 -0
  123. package/src/iframe/order-process/components/CalendarStepsForm/CalendarStepsForm.tsx +2 -2
  124. package/src/iframe/order-process/components/utils/useCategoryVerification.ts +28 -29
  125. package/src/iframe/page/components/PageBody/components/LeftBlock/LeftBlock.tsx +6 -1
  126. package/src/iframe/payment/order-items-table/hooks/useTableData.tsx +11 -99
  127. package/src/iframe/payment/order-items-table/types/index.ts +18 -1
  128. package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +118 -0
  129. package/src/iframe/payment/payment-page/PaymentPage.tsx +4 -4
  130. package/src/notification/email-template/control/EmailTemplateControl.tsx +26 -1
  131. package/src/product-set/form/ProductCategoriesControl.tsx +2 -0
  132. package/src/product-set/form/ProductSetForm.stories.tsx +1 -0
  133. package/src/product-set/form/ProductsControl.tsx +10 -0
  134. package/src/product-set/product/ProductControl.tsx +31 -8
  135. package/src/product-set/product/duration/ProductDurationControl.tsx +1 -1
  136. package/src/product-set/product-category/ProductCategoryControl.tsx +15 -5
  137. package/src/provider/location-input/LocationInputDescription.tsx +2 -2
  138. package/src/provider/working-hours-input/WorkingHoursInputDescription.tsx +10 -8
  139. package/src/recurrence-input/RecurrenceEndInput.tsx +27 -9
  140. package/src/recurrence-input/RecurrenceInput.tsx +3 -0
  141. package/src/recurring-date-picker-input/RecurrenceIntervalAndFrequencyInput.tsx +24 -21
  142. package/src/report/form/ReportForm.tsx +1 -1
  143. package/src/static/CountryCodeSelect.tsx +3 -5
  144. package/src/static/RestrictedAccess.tsx +1 -1
  145. package/src/static/form-number-input/FormNumberInput.tsx +8 -1
  146. package/src/styles/{iframe-customers-journey/ActivitiesCard.scss → activity-card/GridActivitiesCard.scss} +1 -1
  147. package/src/styles/{iframe-customers-journey/ActivitiesSelectedCard.scss → activity-card/ListActivitiesCard.scss} +2 -1
  148. package/src/styles/activity-card/_index.scss +2 -0
  149. package/src/styles/{iframe-customers-journey → date-time-button}/DateTimeButton.scss +3 -6
  150. package/src/styles/date-time-button/_index.scss +1 -0
  151. package/src/styles/iframe-events/Calendar.scss +14 -14
  152. package/src/styles/iframe-page/PageBody.scss +3 -2
  153. package/src/styles/notification/Notification.scss +4 -0
  154. package/src/styles/packages.scss +2 -1
  155. package/src/styles/resources-blocking/_index.scss +5 -0
  156. package/src/styles/themes/bookedit/_index.scss +1 -0
  157. package/src/typings.d.ts +11 -0
  158. package/src/zone/form/components/AvailableTimesControl.tsx +4 -9
  159. package/src/zone/form/components/GameDurationControl.tsx +46 -0
  160. package/src/zone/form/components/ZoneControl.tsx +2 -0
  161. package/src/zone/form/components/ZoneRecurrencesControl.tsx +27 -35
  162. package/src/zone/form/utils/dates.ts +29 -36
  163. package/dist/iframe/activity-cards/activity-card/ActivityCard.d.ts +0 -12
  164. package/dist/iframe/activity-cards/activity-card/ActivityCard.d.ts.map +0 -1
  165. package/dist/iframe/activity-cards/activity-card/ActivityCard.js +0 -1
  166. package/dist/iframe/activity-cards/index.d.ts +0 -3
  167. package/dist/iframe/activity-cards/index.d.ts.map +0 -1
  168. package/dist/iframe/activity-cards/list-activity-card/ListActivityCard.d.ts +0 -12
  169. package/dist/iframe/activity-cards/list-activity-card/ListActivityCard.d.ts.map +0 -1
  170. package/dist/iframe/activity-cards/list-activity-card/ListActivityCard.js +0 -1
  171. package/dist/styles/iframe-customers-journey/_index.scss +0 -3
  172. package/src/iframe/activity-cards/activity-card/ActivityCard.tsx +0 -38
  173. package/src/iframe/activity-cards/index.ts +0 -2
  174. package/src/iframe/activity-cards/list-activity-card/ListActivityCard.stories.tsx +0 -52
  175. package/src/iframe/activity-cards/list-activity-card/ListActivityCard.tsx +0 -49
  176. package/src/styles/iframe-customers-journey/_index.scss +0 -3
  177. /package/dist/assets/iframe/{dateInfo/available.svg → available.svg} +0 -0
  178. /package/dist/assets/iframe/{dateInfo/limited.svg → limited.svg} +0 -0
  179. /package/dist/assets/iframe/{dateInfo/soldOut.svg → soldOut.svg} +0 -0
  180. /package/src/assets/iframe/{dateInfo/available.svg → available.svg} +0 -0
  181. /package/src/assets/iframe/{dateInfo/limited.svg → limited.svg} +0 -0
  182. /package/src/assets/iframe/{dateInfo/soldOut.svg → soldOut.svg} +0 -0
@@ -1,8 +1,35 @@
1
1
  import React, { ReactElement } from "react";
2
2
  import clsx from "clsx";
3
3
  import { DateTime } from "luxon";
4
+ import { useTranslation } from "react-i18next";
5
+ import { ReactComponent as AvailableIcon } from "../assets/iframe/available.svg";
6
+ import { ReactComponent as LimitedIcon } from "../assets/iframe/limited.svg";
7
+ import { ReactComponent as SoldOutIcon } from "../assets/iframe/soldOut.svg";
4
8
  import { DateContent } from "./DateContent";
5
9
 
10
+ const LOTS_OF_SPACE_LIMIT = 0.2;
11
+ const LIMITED_LIMIT = 0.8;
12
+
13
+ const getAvailability = (
14
+ booked: number,
15
+ total: number
16
+ ): { label: string; icon: ReactElement } => {
17
+ if (booked === total) {
18
+ return { label: "soldOut", icon: <SoldOutIcon className="logo" /> };
19
+ }
20
+
21
+ // lots of space if less than 80% booked
22
+ if (booked / total <= LOTS_OF_SPACE_LIMIT) {
23
+ return { label: "lotsOfSpace", icon: <AvailableIcon className="logo" /> };
24
+ }
25
+
26
+ if (booked / total >= LIMITED_LIMIT) {
27
+ return { label: "limited", icon: <LimitedIcon className="logo" /> };
28
+ }
29
+
30
+ return { label: "available", icon: <AvailableIcon className="logo" /> };
31
+ };
32
+
6
33
  export type DateTimeButtonProps<T = DateTime | string> = {
7
34
  date: T;
8
35
  isSelected?: boolean;
@@ -10,6 +37,10 @@ export type DateTimeButtonProps<T = DateTime | string> = {
10
37
  onSelect: (date: T) => void;
11
38
  isOnlyTimeContainer?: boolean;
12
39
  price?: string | number | ReactElement | null;
40
+ resources?: {
41
+ booked: number;
42
+ total: number;
43
+ };
13
44
  };
14
45
 
15
46
  export const DateTimeButton = <T extends DateTime | string>({
@@ -19,22 +50,14 @@ export const DateTimeButton = <T extends DateTime | string>({
19
50
  onSelect,
20
51
  isOnlyTimeContainer,
21
52
  price,
53
+ resources,
22
54
  }: DateTimeButtonProps<T>) => {
23
- // const infoLogo = useMemo(() => {
24
- // if (info?.logo === infoLogoType.LIMIT) {
25
- // return <LimitedSvg />;
26
- // }
27
- // if (info?.logo === infoLogoType.AVAILABLE) {
28
- // return <AvailableSvg />;
29
- // }
30
- // if (info?.logo === infoLogoType.SOLD_OUT) {
31
- // return <SoldOutSvg />;
32
- // }
33
- // return null;
34
- // }, [info]);
35
-
55
+ const { t } = useTranslation("Design");
36
56
  const isTimeVariant = typeof date === "string";
37
57
 
58
+ const availability =
59
+ resources && getAvailability(resources.booked, resources.total);
60
+
38
61
  return (
39
62
  <button
40
63
  type="button"
@@ -59,15 +82,14 @@ export const DateTimeButton = <T extends DateTime | string>({
59
82
  />
60
83
  )}
61
84
 
62
- {price && <div className="price">{price}</div>}
85
+ {price && !isDisabled && <div className="price">{price}</div>}
63
86
 
64
- {/* TODO uncomment when adding availability */}
65
- {/* {info && (
66
- <div className="info">
67
- {info.logo && <Logo className="logo" logo={infoLogo} />}
68
- <div>{info.description}</div>
87
+ {availability && (
88
+ <div className="resources">
89
+ {availability.icon}
90
+ <div>{t(availability.label)}</div>
69
91
  </div>
70
- )} */}
92
+ )}
71
93
  </button>
72
94
  );
73
95
  };
@@ -168,6 +168,9 @@ export function IntervalInput({
168
168
  value={value}
169
169
  onChange={onChange}
170
170
  date={start}
171
+ minDate={DateTime.fromISO(start)
172
+ .plus({ day: 1 })
173
+ .toFormat("yyyy-MM-dd")}
171
174
  disabled={disabled}
172
175
  />
173
176
  )}
@@ -12,21 +12,30 @@ export const useImage = (
12
12
  height: 0,
13
13
  });
14
14
 
15
+ const setImageEventHandler = function setImageEventHandler(
16
+ this: HTMLImageElement
17
+ ) {
18
+ imageRef.current = this;
19
+
20
+ setImageAttributes({
21
+ width: this.naturalWidth,
22
+ height: this.naturalHeight,
23
+ });
24
+ };
25
+
15
26
  const loadImage = useCallback((imageUrl?: string) => {
16
27
  imageRef.current = new window.Image();
17
28
  imageRef.current.src = imageUrl;
18
- imageRef.current.addEventListener("load", function () {
19
- imageRef.current = this;
20
-
21
- setImageAttributes({
22
- width: this.naturalWidth,
23
- height: this.naturalHeight,
24
- });
25
- });
29
+ imageRef.current.addEventListener("load", setImageEventHandler);
26
30
  }, []);
27
31
 
28
32
  useEffect(() => {
29
33
  loadImage(url);
34
+
35
+ return () => {
36
+ imageRef.current.removeEventListener("load", setImageEventHandler);
37
+ imageRef.current = undefined;
38
+ };
30
39
  }, [url, loadImage]);
31
40
 
32
41
  const memoizedImageAttributes = useMemo(() => {
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
  import { Meta, Story } from "@storybook/react";
3
- import { ActivityCard, ActivityCardProps } from "./ActivityCard";
3
+ import { ActivityCard, ActivityCardProps, LAYOUT_LIST } from "./ActivityCard";
4
4
 
5
5
  export default {
6
6
  title: "Iframe/ActivityCard",
@@ -50,3 +50,26 @@ Selected.args = {
50
50
  onSelect: () => null,
51
51
  isSelected: true,
52
52
  };
53
+
54
+ export const ListView: Story<ActivityCardProps> = (props) => {
55
+ return <ActivityCard {...props} />;
56
+ };
57
+
58
+ Default.args = {
59
+ layout: LAYOUT_LIST,
60
+ title: "Clay Pigeons & Axe Thowing",
61
+ duration: "60 mins",
62
+ price: "from £20",
63
+ image: {
64
+ hash: "0b37b130e22aa2d3",
65
+ id: 195,
66
+ imageType: "cover",
67
+ imageableId: 25,
68
+ imageableType: "zone",
69
+ path: "images/original/000/000/000/000/195-0b37b130e22aa2d3.jpeg",
70
+ // eslint-disable-next-line max-len
71
+ url: "https://cdn.lickli.st/doNktZRze1yuz3Uo2OPrLSvXVtUcdUsF/images/original/000/000/000/000/195-0b37b130e22aa2d3.jpeg",
72
+ },
73
+ onSelect: () => null,
74
+ isSelected: false,
75
+ };
@@ -0,0 +1,77 @@
1
+ import React, { ReactNode } from "react";
2
+ import clsx from "clsx";
3
+ import { Image } from "@licklist/core/dist/DataMapper/Media/ImageDataMapper";
4
+
5
+ export const LAYOUT_GRID = "grid";
6
+ export const LAYOUT_LIST = "list";
7
+
8
+ type Layout = typeof LAYOUT_GRID | typeof LAYOUT_LIST;
9
+
10
+ export type ActivityCardProps = {
11
+ title: ReactNode;
12
+ duration: ReactNode;
13
+ price: ReactNode;
14
+ image?: Image | null;
15
+ onSelect: () => void;
16
+ isSelected: boolean;
17
+ layout?: Layout;
18
+ };
19
+
20
+ export const ActivityCard = ({
21
+ title,
22
+ duration,
23
+ price,
24
+ image,
25
+ onSelect,
26
+ isSelected,
27
+ layout = LAYOUT_GRID,
28
+ }: ActivityCardProps) => {
29
+ if (layout === LAYOUT_GRID) {
30
+ return (
31
+ <button
32
+ type="button"
33
+ className={clsx("activity-card", isSelected && "active")}
34
+ onClick={onSelect}
35
+ >
36
+ {image && (
37
+ <img className="activity-card-image" alt="" src={image.url} />
38
+ )}
39
+ <div className={clsx("d-flex", "flex-column", !image && "no-image")}>
40
+ <div className="activity-card-title">{title}</div>
41
+
42
+ {duration && <div>{duration}</div>}
43
+
44
+ {price && <div>{price}</div>}
45
+ </div>
46
+ </button>
47
+ );
48
+ }
49
+
50
+ return (
51
+ <div role="button" onClick={onSelect} onKeyPress={onSelect} tabIndex={0}>
52
+ <div
53
+ className={clsx("list-activity-card", {
54
+ active: isSelected,
55
+ })}
56
+ >
57
+ <div className="description">
58
+ <div className="title">{title}</div>
59
+ {duration && (
60
+ <div>
61
+ <p>{duration}</p>
62
+ </div>
63
+ )}
64
+
65
+ {price && <div>{price}</div>}
66
+ </div>
67
+
68
+ {image && (
69
+ <div className="image-container">
70
+ <img className="image" src={image.url} alt="" />
71
+ </div>
72
+ )}
73
+ </div>
74
+ <hr className="list-activity-card-hr" />
75
+ </div>
76
+ );
77
+ };
@@ -0,0 +1 @@
1
+ export * from "./ActivityCard";
@@ -1,37 +1,36 @@
1
1
  import React from "react";
2
2
  import { DateTime } from "luxon";
3
3
  import { Meta, Story } from "@storybook/react";
4
- import { boolean } from "@storybook/addon-knobs";
5
- import { EventCalendarProvider } from "@licklist/plugins/dist/context/event/EventCalendarContext";
6
- import { EventCalendar } from "./EventCalendar";
4
+ import {
5
+ EventCalendarProvider,
6
+ getMonthCalendarDates,
7
+ } from "@licklist/plugins/dist/context/event/EventCalendarContext";
8
+ import { EventCalendar, EventCalendarProps } from "./EventCalendar";
7
9
 
8
10
  export default {
9
11
  title: "Iframe/Event/Calendar",
10
12
  component: EventCalendar,
11
13
  } as Meta;
12
14
 
13
- export const Default: Story<any> = (args) => {
14
- const now = DateTime.now().set({
15
- hour: 0,
16
- second: 0,
17
- millisecond: 0,
18
- minute: 0,
19
- });
20
- const disabledDates = [now.minus({ day: 2 }), now, now.plus({ day: 2 })];
21
-
22
- const isLoading = boolean("isLoading", false);
23
-
15
+ export const Default: Story<EventCalendarProps> = (args) => {
24
16
  return (
25
- <EventCalendarProvider>
17
+ <EventCalendarProvider getCalendarDates={getMonthCalendarDates}>
26
18
  <div style={{ backgroundColor: "white" }}>
27
- <EventCalendar
28
- {...args}
29
- disabledDates={disabledDates}
30
- isLoading={isLoading}
31
- />
19
+ <EventCalendar {...args} />
32
20
  </div>
33
21
  </EventCalendarProvider>
34
22
  );
35
23
  };
36
24
 
37
- Default.args = {};
25
+ const now = DateTime.now().set({
26
+ hour: 0,
27
+ second: 0,
28
+ millisecond: 0,
29
+ minute: 0,
30
+ });
31
+
32
+ Default.args = {
33
+ disabledDates: [now.minus({ day: 2 }), now, now.plus({ day: 2 })],
34
+ isLoading: false,
35
+ fromPrice: "from £10",
36
+ };
@@ -1,19 +1,26 @@
1
- import React from "react";
1
+ import React, { ReactElement } from "react";
2
2
  import { CalendarButtons } from "./components/CalendarButtons";
3
3
  import { CalendarDates } from "./components/CalendarDates";
4
4
  import { CalendarBaseProps } from "./types";
5
5
 
6
- export type EventCalendarProps = CalendarBaseProps;
6
+ export type EventCalendarProps = CalendarBaseProps & {
7
+ fromPrice?: string | ReactElement | null;
8
+ };
7
9
 
8
10
  export const EventCalendar = ({
9
11
  disabledDates = [],
10
12
  isLoading = false,
13
+ fromPrice,
11
14
  }: EventCalendarProps) => {
12
15
  return (
13
16
  <div className="calendar-wrapper">
14
17
  <div className="calendar">
15
18
  <CalendarButtons disabledDates={disabledDates} isLoading={isLoading} />
16
- <CalendarDates disabledDates={disabledDates} isLoading={isLoading} />
19
+ <CalendarDates
20
+ disabledDates={disabledDates}
21
+ isLoading={isLoading}
22
+ fromPrice={fromPrice}
23
+ />
17
24
  </div>
18
25
  </div>
19
26
  );
@@ -1,4 +1,4 @@
1
- import React from "react";
1
+ import React, { ReactElement } from "react";
2
2
  import { Button } from "react-bootstrap";
3
3
  import { DateTime } from "luxon";
4
4
  import clsx from "clsx";
@@ -9,6 +9,7 @@ export type CalendarDateProps = {
9
9
  selectedDate?: DateTime;
10
10
  setSelectedDate: (date: DateTime) => void;
11
11
  isDisabled?: boolean;
12
+ fromPrice?: string | ReactElement | null;
12
13
  };
13
14
 
14
15
  export const CalendarDate = ({
@@ -17,6 +18,7 @@ export const CalendarDate = ({
17
18
  selectedDate,
18
19
  setSelectedDate,
19
20
  isDisabled = false,
21
+ fromPrice,
20
22
  }: CalendarDateProps) => {
21
23
  const onClick = () => {
22
24
  if (isDisabled) return;
@@ -37,7 +39,13 @@ export const CalendarDate = ({
37
39
  )}
38
40
  onClick={onClick}
39
41
  >
40
- {currentDate.day}
42
+ <div>{currentDate.day}</div>
43
+
44
+ {typeof fromPrice === "string" ? (
45
+ <div>{fromPrice}</div>
46
+ ) : (
47
+ <>{fromPrice}</>
48
+ )}
41
49
  </Button>
42
50
  );
43
51
  };
@@ -1,4 +1,4 @@
1
- import React, { useContext, useMemo } from "react";
1
+ import React, { ReactElement, useContext, useMemo } from "react";
2
2
  import { DateTime } from "luxon";
3
3
  import { EventCalendarContext } from "@licklist/plugins/dist/context/event/EventCalendarContext";
4
4
  import { CalendarWeekdays } from "../CalendarWeekdays";
@@ -6,11 +6,14 @@ import { CalendarDate } from "../CalendarDate";
6
6
  import { CalendarBaseProps } from "../../types";
7
7
  import { isSelectedDateDisabled } from "../../utils";
8
8
 
9
- export type CalendarDatesProps = CalendarBaseProps;
9
+ export type CalendarDatesProps = CalendarBaseProps & {
10
+ fromPrice?: string | ReactElement | null;
11
+ };
10
12
 
11
13
  export const CalendarDates = ({
12
14
  disabledDates = [],
13
15
  isLoading = false,
16
+ fromPrice,
14
17
  }: CalendarDatesProps) => {
15
18
  const { calendarDates, initialDate, selectedDate, setSelectedDate } =
16
19
  useContext(EventCalendarContext);
@@ -52,6 +55,7 @@ export const CalendarDates = ({
52
55
  selectedDate={selectedDate}
53
56
  setSelectedDate={setSelectedDate}
54
57
  isDisabled={isDisabled}
58
+ fromPrice={fromPrice}
55
59
  />
56
60
  );
57
61
  })}
@@ -43,5 +43,5 @@ export {
43
43
  export { BackButton } from "./back-button";
44
44
  export { PoweredBy } from "./powered-by";
45
45
  export * from "./page";
46
- export * from "./activity-cards";
46
+ export * from "./activity-card";
47
47
  export { CustomDateField, CustomDateFieldProps } from "./custom-fields";
@@ -11,6 +11,7 @@ import { BookingSummaryAccordion } from "./components/BookingSummaryAccordion";
11
11
 
12
12
  export const BookingSummary = ({
13
13
  date,
14
+ time,
14
15
  menuSteps,
15
16
  formValues,
16
17
  isNotShownPeopleAmount,
@@ -47,6 +48,7 @@ export const BookingSummary = ({
47
48
  <div className="event-info">
48
49
  <p className="m-0 title event-name">{eventName}</p>
49
50
  <p className="m-0">{date}</p>
51
+ {time && <p className="m-0">{time}</p>}
50
52
  </div>
51
53
  <hr />
52
54
 
@@ -6,6 +6,7 @@ export const ACCORDION_KEY = "booking-summary";
6
6
 
7
7
  export type BookingSummaryProps = {
8
8
  date: string;
9
+ time?: string;
9
10
  menuSteps?: MenuStep[];
10
11
  formValues?: {
11
12
  [key: string]: Order;
@@ -5,6 +5,8 @@ export const cartSumByOrderProducts = (orderProducts?: Order[]) => {
5
5
  return 0;
6
6
  }
7
7
  return orderProducts.reduce((prevSumValue: number, product) => {
8
+ if (!product) return 0;
9
+
8
10
  return (
9
11
  prevSumValue + (product?.deposit || product?.price) * product.quantity
10
12
  );
@@ -20,8 +20,8 @@ import { Step } from "@licklist/core/dist/DataMapper/Product/StepDataMapper";
20
20
  import { useTranslation } from "react-i18next";
21
21
  import { Product } from "@licklist/core/dist/DataMapper/Product/ProductDataMapper";
22
22
  import { QuantityCheckProductInfo } from "@licklist/plugins/dist/types/Api/verifyStock";
23
+ import { MenuStep } from "@licklist/plugins/dist/types/context/sale/menuSteps";
23
24
  import { Category } from "./components/Category";
24
- import { MenuStep } from "../../../../types";
25
25
  import { STEP_FORM_ID } from "../../constants";
26
26
  import { ErrorModal } from "../ErrorModal/ErrorModal";
27
27
  import { PageBody } from "../../../page/components/PageBody";
@@ -117,7 +117,7 @@ export const CalendarStepsForm = forwardRef<
117
117
  );
118
118
  return;
119
119
  }
120
- const categoryError = verifyCategoryItems(values, step);
120
+ const categoryError = verifyCategoryItems(values, step.productCategories);
121
121
 
122
122
  if (categoryError) {
123
123
  setStepFormError(categoryError.message);
@@ -1,5 +1,6 @@
1
+ import { ProductCategory } from "@licklist/core/dist/DataMapper/Product/ProductCategoryDataMapper";
1
2
  import { useTranslation } from "react-i18next";
2
- import { MenuStep, Order } from "src/types";
3
+ import { Order } from "src/types";
3
4
 
4
5
  interface CategoryError {
5
6
  message: string;
@@ -12,41 +13,39 @@ export const useCategoryVerification = () => {
12
13
 
13
14
  return (
14
15
  values: Record<Order["id"], Order>,
15
- step: MenuStep
16
+ productCategories?: ProductCategory[]
16
17
  ): CategoryError | void => {
17
- let errorMessage;
18
+ let errorMessage: { id: number; message: string } | void;
18
19
 
19
20
  const productArray = Object.values(values).filter(
20
21
  (product) => product?.quantity > 0
21
22
  );
22
23
 
23
- step?.productCategories.forEach(
24
- ({ minSubItems, maxSubItems, id, name }) => {
25
- if (!minSubItems && !maxSubItems) return;
26
-
27
- const categoryProductsQuantity = productArray.filter(
28
- (product) => product?.productsCategoryId === id
29
- ).length;
30
-
31
- if (minSubItems && categoryProductsQuantity < minSubItems) {
32
- const message = t("Validation:fieldMinNumber", {
33
- min: minSubItems,
34
- attribute: `number of products in the ${name} category`,
35
- });
36
- errorMessage = { id, message };
37
-
38
- return;
39
- }
40
-
41
- if (maxSubItems && categoryProductsQuantity > maxSubItems) {
42
- const message = t("Validation:fieldMaxNumber", {
43
- max: maxSubItems,
44
- attribute: `number of products in the ${name} category`,
45
- });
46
- errorMessage = { id, message };
47
- }
24
+ productCategories.forEach(({ minSubItems, maxSubItems, id, name }) => {
25
+ if (!minSubItems && !maxSubItems) return;
26
+
27
+ const categoryProductsQuantity = productArray.filter(
28
+ (product) => product?.productsCategoryId === id
29
+ ).length;
30
+
31
+ if (minSubItems && categoryProductsQuantity < minSubItems) {
32
+ const message = t("Validation:fieldMinNumber", {
33
+ min: minSubItems,
34
+ attribute: `number of products in the ${name} category`,
35
+ });
36
+ errorMessage = { id, message };
37
+
38
+ return;
48
39
  }
49
- );
40
+
41
+ if (maxSubItems && categoryProductsQuantity > maxSubItems) {
42
+ const message = t("Validation:fieldMaxNumber", {
43
+ max: maxSubItems,
44
+ attribute: `number of products in the ${name} category`,
45
+ });
46
+ errorMessage = { id, message };
47
+ }
48
+ });
50
49
 
51
50
  return errorMessage;
52
51
  };
@@ -26,7 +26,12 @@ export const LeftBlock = ({
26
26
  <div className={clsx("left-block", className)} {...props}>
27
27
  {pageTitle && (
28
28
  <div className="navigation">
29
- <div className="title">{pageTitle}</div>
29
+ {typeof pageTitle === "string" ? (
30
+ <div className="title">{pageTitle}</div>
31
+ ) : (
32
+ pageTitle
33
+ )}
34
+
30
35
  {component}
31
36
  </div>
32
37
  )}