@licklist/design 0.62.3 → 0.63.0-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 (150) hide show
  1. package/bitbucket-pipelines.yml +0 -8
  2. package/dist/date-time-button/DateTimeButton.js +1 -1
  3. package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.d.ts +3 -1
  4. package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.d.ts.map +1 -1
  5. package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.js +1 -1
  6. package/dist/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.d.ts +3 -1
  7. package/dist/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.d.ts.map +1 -1
  8. package/dist/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.js +1 -1
  9. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.d.ts +3 -1
  10. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.d.ts.map +1 -1
  11. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.js +1 -1
  12. package/dist/iframe/payment/order-items-table/utils/paymentSummary.js +1 -1
  13. package/dist/iframe/ryft/RyftPaymentForm.d.ts.map +1 -1
  14. package/dist/iframe/ryft/RyftPaymentForm.js +1 -1
  15. package/dist/iframe/ryft/utils/ryft-form.d.ts.map +1 -1
  16. package/dist/iframe/ryft/utils/ryft-form.js +1 -1
  17. package/dist/product-set/control/DateAndRecurrenceInput.d.ts +1 -5
  18. package/dist/product-set/control/DateAndRecurrenceInput.d.ts.map +1 -1
  19. package/dist/product-set/control/DateAndRecurrenceInput.js +1 -1
  20. package/dist/product-set/control/DateInput.d.ts.map +1 -1
  21. package/dist/product-set/control/DateInput.js +1 -1
  22. package/dist/product-set/control/ProductSetControl.d.ts +4 -3
  23. package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
  24. package/dist/product-set/control/utils.d.ts +5 -0
  25. package/dist/product-set/control/utils.d.ts.map +1 -0
  26. package/dist/product-set/control/utils.js +1 -0
  27. package/dist/product-set/form/ProductSetForm.d.ts +4 -1
  28. package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
  29. package/dist/product-set/hooks/useSortableTreeFunctions.d.ts.map +1 -1
  30. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  31. package/dist/product-set/product/ProductControl.js +1 -1
  32. package/dist/product-set/product/fixed-duration-fields/FixedDurationOptions.d.ts.map +1 -1
  33. package/dist/provider/working-hours-input/WorkingHoursInputDescription.d.ts.map +1 -1
  34. package/dist/provider/working-hours-input/WorkingHoursInputDescription.js +1 -1
  35. package/dist/recurring-date-picker-input/RecurrenceAndFrequencyInput.d.ts.map +1 -1
  36. package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts +3 -1
  37. package/dist/recurring-date-picker-input/RecurringDatePickerInput.d.ts.map +1 -1
  38. package/dist/recurring-date-picker-input/RecurringDatePickerInput.js +1 -1
  39. package/dist/recurring-date-picker-input/utils.d.ts +12 -0
  40. package/dist/recurring-date-picker-input/utils.d.ts.map +1 -1
  41. package/dist/recurring-date-picker-input/utils.js +1 -1
  42. package/dist/sales/booking/results/components/ResultCard.d.ts.map +1 -1
  43. package/dist/sales/booking/results/components/ResultCard.js +1 -1
  44. package/dist/sales/coupon/control/CouponFormControl.d.ts +2 -1
  45. package/dist/sales/coupon/control/CouponFormControl.d.ts.map +1 -1
  46. package/dist/sales/coupon/control/CouponFormControl.js +1 -1
  47. package/dist/sales/coupon/form/CouponFrom.d.ts +2 -2
  48. package/dist/sales/coupon/form/CouponFrom.d.ts.map +1 -1
  49. package/dist/sales/coupon/utils/index.d.ts +7 -0
  50. package/dist/sales/coupon/utils/index.d.ts.map +1 -0
  51. package/dist/sales/coupon/utils/index.js +1 -0
  52. package/dist/setting/admin/AdminSettingForm.d.ts +2 -2
  53. package/dist/setting/admin/AdminSettingForm.d.ts.map +1 -1
  54. package/dist/setting/dashboard/DashboardSettingForm.d.ts +1 -0
  55. package/dist/setting/dashboard/DashboardSettingForm.d.ts.map +1 -1
  56. package/dist/setting/dashboard/DashboardSettingForm.js +1 -1
  57. package/dist/styles/ryft-payment-form/RyftPaymentForm.scss +99 -113
  58. package/dist/styles/sales/BookingResults.scss +1 -1
  59. package/dist/typeahead/Typeahead.d.ts +2 -1
  60. package/dist/typeahead/Typeahead.d.ts.map +1 -1
  61. package/dist/typeahead/Typeahead.js +1 -1
  62. package/dist/zone/form/ZoneForm.d.ts +2 -2
  63. package/dist/zone/form/ZoneForm.d.ts.map +1 -1
  64. package/dist/zone/form/ZoneForm.js +1 -1
  65. package/dist/zone/form/components/AvailableTimesControl.d.ts +0 -2
  66. package/dist/zone/form/components/AvailableTimesControl.d.ts.map +1 -1
  67. package/dist/zone/form/components/ZoneControl.d.ts +2 -2
  68. package/dist/zone/form/components/ZoneControl.d.ts.map +1 -1
  69. package/dist/zone/form/components/ZoneControl.js +1 -1
  70. package/dist/zone/form/components/ZoneRecurrencesControl.d.ts +4 -4
  71. package/dist/zone/form/components/ZoneRecurrencesControl.d.ts.map +1 -1
  72. package/dist/zone/form/components/ZoneRecurrencesControl.js +1 -1
  73. package/dist/zone/form/utils/dates.d.ts.map +1 -1
  74. package/package.json +10 -35
  75. package/src/date-time-button/DateTimeButton.stories.tsx +2 -1
  76. package/src/date-time-button/DateTimeButton.tsx +7 -5
  77. package/src/events/edit-event-modal/component/EditEventForm/EditEventForm.tsx +4 -0
  78. package/src/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.tsx +10 -8
  79. package/src/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.tsx +4 -0
  80. package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +6 -6
  81. package/src/iframe/ryft/RyftPaymentForm.tsx +12 -4
  82. package/src/iframe/ryft/utils/ryft-form.ts +8 -4
  83. package/src/product-set/control/DateAndRecurrenceInput.tsx +48 -14
  84. package/src/product-set/control/DateInput.tsx +2 -4
  85. package/src/product-set/control/ProductSetControl.stories.tsx +1 -1
  86. package/src/product-set/control/ProductSetControl.tsx +5 -8
  87. package/src/product-set/control/utils.ts +25 -0
  88. package/src/product-set/form/ProductCategoriesControl.tsx +1 -1
  89. package/src/product-set/form/ProductSetForm.stories.tsx +1 -2
  90. package/src/product-set/form/ProductSetForm.tsx +5 -1
  91. package/src/product-set/hooks/useSortableTreeFunctions.ts +2 -0
  92. package/src/product-set/product/ProductControl.tsx +38 -38
  93. package/src/product-set/product/fixed-duration-fields/FixedDurationOptions.tsx +0 -2
  94. package/src/provider/working-hours-input/WorkingHoursInputDescription.tsx +4 -18
  95. package/src/recurring-date-picker-input/RecurrenceAndFrequencyInput.tsx +0 -1
  96. package/src/recurring-date-picker-input/RecurringDatePickerInput.tsx +11 -1
  97. package/src/recurring-date-picker-input/utils.ts +77 -0
  98. package/src/sales/booking/results/BookingResults.stories.tsx +3 -2
  99. package/src/sales/booking/results/components/ResultCard.tsx +2 -5
  100. package/src/sales/coupon/control/CouponFormControl.tsx +28 -51
  101. package/src/sales/coupon/form/CouponFrom.tsx +5 -15
  102. package/src/sales/coupon/utils/index.ts +13 -0
  103. package/src/setting/admin/AdminSettingForm.tsx +2 -2
  104. package/src/setting/dashboard/DashboardSettingForm.tsx +13 -0
  105. package/src/sortable-tree/SortableTreeItem.tsx +1 -1
  106. package/src/static/switch/BooleanSwitch.tsx +1 -1
  107. package/src/styles/ryft-payment-form/RyftPaymentForm.scss +99 -113
  108. package/src/styles/sales/BookingResults.scss +1 -1
  109. package/src/typeahead/Typeahead.tsx +16 -3
  110. package/src/zone/form/ZoneForm.tsx +3 -2
  111. package/src/zone/form/components/AvailableTimesControl.tsx +0 -2
  112. package/src/zone/form/components/ZoneControl.tsx +3 -3
  113. package/src/zone/form/components/ZoneRecurrencesControl.tsx +7 -5
  114. package/src/zone/form/utils/dates.ts +9 -10
  115. package/jest.config.js +0 -29
  116. package/tests/Auth/Authorizer.test.tsx +0 -194
  117. package/tests/Auth/Layout/UserNavDropDown.test.tsx +0 -43
  118. package/tests/Auth/Layout/UserNavDropDownToggle.test.tsx +0 -33
  119. package/tests/Auth/Login/LoginComponent.test.tsx +0 -246
  120. package/tests/Auth/Login/LoginFormComponent.test.tsx +0 -182
  121. package/tests/Auth/Register/RegisterComponent.test.tsx +0 -285
  122. package/tests/Auth/Register/RegisterFormComponent.test.tsx +0 -170
  123. package/tests/Auth/Settings/Dashboard/IpInput.test.tsx +0 -130
  124. package/tests/Auth/Social/SocialCallbackComponent.test.tsx +0 -133
  125. package/tests/Auth/Social/SocialFormComponent.test.tsx +0 -118
  126. package/tests/FileUpload/FileUpload.test.tsx +0 -42
  127. package/tests/Notification/EmailTemplate.test.tsx +0 -82
  128. package/tests/ProductSet/ProductSetPopover.test.tsx +0 -40
  129. package/tests/Report/Report.test.tsx +0 -48
  130. package/tests/Sales/Coupon.test.tsx +0 -51
  131. package/tests/Sales/SalesAndVIews.test.tsx +0 -63
  132. package/tests/SnippetTemplates/SnippetTemplates.test.tsx +0 -56
  133. package/tests/Table/FilterHelperComponent.test.tsx +0 -88
  134. package/tests/Table/PaginationHelperComponent.test.tsx +0 -109
  135. package/tests/Table/PerPageHelperComponent.test.tsx +0 -34
  136. package/tests/Table/TableHelperComponent.test.tsx +0 -295
  137. package/tests/TipTapEditor/TipTapEditor.test.tsx +0 -28
  138. package/tests/__mock__/hooks/useAuthApi.ts +0 -13
  139. package/tests/__mock__/hooks/useAuthMock.ts +0 -13
  140. package/tests/__mock__/hooks/useFormMock.ts +0 -27
  141. package/tests/__mock__/hooks/useNotificationMock.ts +0 -13
  142. package/tests/__mock__/hooks/useQueryMock.ts +0 -16
  143. package/tests/__mock__/hooks/useSocialApiMock.ts +0 -20
  144. package/tests/__mock__/hooks/useTranslationMock.ts +0 -17
  145. package/tests/__mock__/hooks/useUserApiMock.ts +0 -18
  146. package/tests/__mock__/hooks/useUserMock.ts +0 -13
  147. package/tests/__mock__/styleMock.js +0 -1
  148. package/tests/__mock__/windowMock.ts +0 -5
  149. package/tests/packages/react-query.tsx +0 -28
  150. package/tests/setupTests.ts +0 -10
@@ -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[] | undefined;
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}
@@ -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,75 @@ 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[] | undefined
121
+ ) => {
122
+ const { t } = useTranslation("Validation");
123
+ if (!workHours) return {};
124
+
125
+ // workhours of selected days, all if no days selected
126
+ const selectedWorkHours = byWeekDay.length
127
+ ? byWeekDay.map(({ weekday }) =>
128
+ workHours.find(({ day }) => day === weekday)
129
+ )
130
+ : workHours;
131
+
132
+ /**
133
+ * start time
134
+ */
135
+ const startTimes = selectedWorkHours
136
+ .map((workhour) => DateTime.fromFormat(workhour.start, TIME_FORMAT))
137
+ .sort(dateTimesSortFn("desc"));
138
+
139
+ const latestStartTime = startTimes[0];
140
+
141
+ const startTimeRules = {
142
+ validate: (date: string) => {
143
+ const selectedDate = DateTime.fromFormat(date, TIME_FORMAT);
144
+ if (selectedDate >= latestStartTime) return true;
145
+
146
+ return t("fieldTimeAfter", {
147
+ attribute: t("Design:startTimeSmall"),
148
+ time: latestStartTime.toFormat(TIME_FORMAT),
149
+ });
150
+ },
151
+ };
152
+
153
+ /**
154
+ * end time
155
+ */
156
+ const endTimes = selectedWorkHours
157
+ .map<string>(({ start, end }) => {
158
+ const startDateTime = DateTime.fromFormat(start, TIME_FORMAT);
159
+ const endDateTime = DateTime.fromFormat(end, TIME_FORMAT);
160
+
161
+ if (startDateTime <= endDateTime) return end;
162
+
163
+ // if end is before start, then it means that end is on the next day
164
+ // so count only to the end of current day
165
+ return "23:59";
166
+ })
167
+ .map((workhour) => DateTime.fromFormat(workhour, TIME_FORMAT))
168
+ .sort(dateTimesSortFn("asc"));
169
+
170
+ const earliestEndTime = endTimes[0];
171
+
172
+ const endTimeRules = {
173
+ validate: (date: string) => {
174
+ const selectedDate = DateTime.fromFormat(date, TIME_FORMAT);
175
+ if (selectedDate <= earliestEndTime) return true;
176
+
177
+ return t("fieldTimeBefore", {
178
+ attribute: t("Design:endTimeSmall"),
179
+ time: earliestEndTime.toFormat(TIME_FORMAT),
180
+ });
181
+ },
182
+ };
183
+
184
+ return {
185
+ startTimeRules,
186
+ endTimeRules,
187
+ };
188
+ };
@@ -3,11 +3,12 @@ import { Meta } from "@storybook/react";
3
3
  import { Event } from "@licklist/core/dist/DataMapper/Provider/EventDataMapper";
4
4
  import { User } from "@licklist/core/dist/DataMapper/User/UserDataMapper";
5
5
  import { Product } from "@licklist/core/dist/DataMapper/Product/ProductDataMapper";
6
- import { Order } from "@licklist/core/dist/DataMapper/Order/OrderDataMapper";
7
6
  import {
7
+ Order,
8
8
  ORDER_SOURCE_IFRAME,
9
9
  ORDER_SOURCE_MANUAL,
10
- } from "@licklist/core/src/DataMapper/Order/OrderDataMapper";
10
+ } from "@licklist/core/dist/DataMapper/Order/OrderDataMapper";
11
+
11
12
  import { BookingResults } from "./BookingResults";
12
13
 
13
14
  export default {
@@ -12,7 +12,6 @@ import { TIME_FORMAT } from "@licklist/core/dist/Config";
12
12
  import * as Config from "@licklist/core/dist/Config";
13
13
  import { formatDateStringForEvent } from "@licklist/plugins/dist/utils/formatDate";
14
14
  import { getOrderSourceTitle } from "@licklist/plugins/dist/utils/sourceTitle";
15
-
16
15
  import Icon from "../../../../static/Icon";
17
16
 
18
17
  export type ResultCardProps = {
@@ -22,8 +21,6 @@ export type ResultCardProps = {
22
21
  onCardClick?: (id: number) => void;
23
22
  };
24
23
 
25
- // @TODO integrate when API will be available
26
- // activity and staff keys
27
24
  export const ResultCard = ({
28
25
  order,
29
26
  className,
@@ -41,10 +38,10 @@ export const ResultCard = ({
41
38
  startDate,
42
39
  products,
43
40
  source,
44
- totalAmount,
45
41
  event,
46
42
  menu,
47
43
  remainingToPay,
44
+ paidAmount,
48
45
  } = order;
49
46
 
50
47
  const productList = products.map((product) => product.name)?.join(", ") || "";
@@ -108,7 +105,7 @@ export const ResultCard = ({
108
105
  )}
109
106
  <p>
110
107
  {t("paidAmount")}:{" "}
111
- {formatNumber(totalAmount, {
108
+ {formatNumber(paidAmount, {
112
109
  style: "currency",
113
110
  currency: Config.Currency.GBP,
114
111
  })}
@@ -21,12 +21,14 @@ import couponCodeRules from "@licklist/plugins/dist/validation/Rules/couponCodeR
21
21
  // import { useId } from "@react-aria/utils";
22
22
 
23
23
  import HTMLInputDateElement from "../../../types/static/HTMLInputDateElement";
24
+ import { Typeahead, TypeaheadOptions } from "../../../typeahead";
25
+ import { convertToTypeaheadOptions } from "../utils";
24
26
 
25
27
  export interface CouponFormValues {
26
28
  name?: string;
27
29
  code: string;
28
30
  discountType: CouponType;
29
- productGroupIds: string[];
31
+ productGroupIds: Array<TypeaheadOptions | ProductGroup>;
30
32
  discount: number;
31
33
  totalType: CouponTotalType;
32
34
  startFrom: string;
@@ -58,9 +60,9 @@ export const CouponFormControl = ({
58
60
  watch,
59
61
  } = useFormContext<CouponFormValues>();
60
62
  const { t } = useTranslation(["Design", "Notification", "App"]);
61
- const [selectedProductGroups, setSelectedProductGroups] = useState<string[]>(
62
- []
63
- );
63
+ const [selectedProductGroups, setSelectedProductGroups] = useState<
64
+ TypeaheadOptions[]
65
+ >([]);
64
66
  /* TODO: Show Recurrent date, when reccurent date bugs are fixed */
65
67
  // const rrule = watch("rrule");
66
68
  // const [recurrent, setRecurrent] = useState(Boolean(rrule));
@@ -85,15 +87,20 @@ export const CouponFormControl = ({
85
87
  [COUPON_TOTAL_TYPE_TOTAL]: t("Design:depositTotal"),
86
88
  };
87
89
 
88
- // Set pre-selected Product Groups
89
90
  useEffect(() => {
90
- setSelectedProductGroups(getValues("productGroupIds"));
91
+ const defaultProductGroup = getValues("productGroupIds");
92
+
93
+ setSelectedProductGroups(
94
+ convertToTypeaheadOptions(defaultProductGroup as ProductGroup[])
95
+ );
91
96
  }, [getValues]);
92
97
 
93
98
  useEffect(() => {
94
99
  setValue("productGroupIds", selectedProductGroups);
95
100
  }, [getValues, setValue, selectedProductGroups]);
96
101
 
102
+ const productGroupList = convertToTypeaheadOptions(productGroups);
103
+
97
104
  /* TODO: Show Recurrent date, when reccurent date bugs are fixed */
98
105
  // useEffect(() => {
99
106
  // if (!recurrent && rrule) {
@@ -251,51 +258,21 @@ export const CouponFormControl = ({
251
258
  </Form.Group>
252
259
  </Col>
253
260
  </Row>
254
- {productGroups && productGroups?.length > 0 && (
255
- <Row>
256
- <Col md={12}>
257
- <h5 className="mt-4">{t("Design:productGroups")}</h5>
258
- <Form.Group className="d-flex flex-wrap justify-content-between mt-4 mb-5">
259
- {productGroups?.map((productGroup) => {
260
- const isGroupSelected =
261
- getValues("productGroupIds")?.includes(
262
- String(productGroup.id)
263
- ) ?? false;
264
-
265
- return (
266
- <Form.Check
267
- key={productGroup.id}
268
- label={productGroup.name}
269
- defaultChecked={isGroupSelected}
270
- disabled={isLoading}
271
- onChange={(e) => {
272
- if (e.target.checked) {
273
- setSelectedProductGroups((prevGroups) =>
274
- Array.from(
275
- new Set([...prevGroups, String(productGroup.id)])
276
- )
277
- );
278
- } else {
279
- setSelectedProductGroups((prevGroups) => {
280
- return prevGroups.filter(
281
- (id) => String(productGroup.id) !== id
282
- );
283
- });
284
- }
285
- }}
286
- />
287
- );
288
- })}
289
- <Form.Control
290
- {...register("productGroupIds")}
291
- hidden
292
- value={selectedProductGroups}
293
- disabled={isLoading}
294
- />
295
- </Form.Group>
296
- </Col>
297
- </Row>
298
- )}
261
+ <Row>
262
+ <Col>
263
+ <Form.Group className="mb-3">
264
+ <Form.Label>{t("Design:productGroups")}</Form.Label>
265
+ <Typeahead
266
+ name="productGroupIds"
267
+ options={productGroupList}
268
+ isMultipleChoise
269
+ isCouponForm
270
+ placeholder={t("Design:choose")}
271
+ noOptionsMessage={t("Design:noSelectedProductGroups")}
272
+ />
273
+ </Form.Group>
274
+ </Col>
275
+ </Row>
299
276
 
300
277
  {/* TODO: Show Recurrent date, when reccurent date bugs are fixed */}
301
278
  {/* {startFromValue && (
@@ -1,5 +1,8 @@
1
1
  import React, { useEffect } from "react";
2
- import { ProductGroup } from "@licklist/core/dist/DataMapper/Product/ProductGroupDataMapper";
2
+ import {
3
+ ProductGroup,
4
+ ProductGroupDTO,
5
+ } from "@licklist/core/dist/DataMapper/Product/ProductGroupDataMapper";
3
6
  import {
4
7
  CouponTotalType,
5
8
  CouponType,
@@ -16,7 +19,7 @@ export interface CouponFormValues {
16
19
  name?: string;
17
20
  code: string;
18
21
  discountType: CouponType;
19
- productGroupIds: string[];
22
+ productGroupIds: ProductGroupDTO[];
20
23
  discount: number;
21
24
  totalType: CouponTotalType;
22
25
  startFrom: string;
@@ -54,19 +57,6 @@ export const CouponForm = ({
54
57
  const { setError } = form;
55
58
  const { t } = useTranslation(["Design", "Notification", "App"]);
56
59
 
57
- // @TODO: dont need for v1 release
58
- // const [selectedProductGroups, setSelectedProductGroups] = useState<string[]>(
59
- // []
60
- // );
61
- // Set pre-selected Product Groups
62
- // useEffect(() => {
63
- // setSelectedProductGroups(getValues("productGroupIds"));
64
- // }, [getValues]);
65
-
66
- // useEffect(() => {
67
- // setValue("productGroupIds", selectedProductGroups);
68
- // }, [getValues, setValue, selectedProductGroups]);
69
-
70
60
  useEffect(() => {
71
61
  FormErrorService.handleServerErrors(serverErrors, setError);
72
62
  }, [serverErrors, setError]);
@@ -0,0 +1,13 @@
1
+ import { ProductGroup } from "@licklist/core/dist/DataMapper/Product/ProductGroupDataMapper";
2
+
3
+ export const convertToTypeaheadOptions = (productGroups?: ProductGroup[]) => {
4
+ if (!productGroups || !productGroups.length) {
5
+ return [];
6
+ }
7
+
8
+ return productGroups.map(({ id, name }: ProductGroup) => ({
9
+ id: Number(id),
10
+ value: name,
11
+ label: name,
12
+ }));
13
+ };
@@ -11,7 +11,7 @@ import Row from "react-bootstrap/Row";
11
11
  import Col from "react-bootstrap/Col";
12
12
  import { Link } from "react-router-dom";
13
13
  import HookFormService from "@licklist/plugins/dist/services/Form/HookFormService";
14
- import { ProviderType } from "@licklist/core/dist/DataMapper/Provider/ProvidableDataMapper";
14
+ import { ProvidableType } from "@licklist/core/dist/DataMapper/Provider/ProvidableDataMapper";
15
15
  import Icon from "../../static/Icon";
16
16
  import { PaymentFeeForm, PaymentFeeFormFieldValues } from "./PaymentFeeForm";
17
17
  import { Currency } from "../../types/currency";
@@ -33,7 +33,7 @@ export interface AdminSettingFormProps extends HasPermissionProp {
33
33
  providerMetadata: {
34
34
  country?: string;
35
35
  providableId?: number;
36
- providerType?: ProviderType;
36
+ providerType?: ProvidableType;
37
37
  };
38
38
  }
39
39
 
@@ -31,6 +31,7 @@ export type DashboardSettingFormFieldValues = {
31
31
  isEnquiryOnly: boolean;
32
32
  hasUserVerification: boolean;
33
33
  metaPixelId?: number;
34
+ eventDeadlineErrorMessage?: string;
34
35
  } & EventSettingFormFieldValues &
35
36
  ProviderSettingFormFieldValues;
36
37
 
@@ -81,6 +82,7 @@ export const DashboardSettingForm = ({
81
82
  const orderReportFormatId = useId();
82
83
  const userVerificationId = useId();
83
84
  const metaPixelId = useId();
85
+ const eventDeadlineErrorMessageId = useId();
84
86
 
85
87
  const orderReportFormatList: SelectItem[] = [
86
88
  { id: 1, value: t("groupItemsByOrder") },
@@ -234,6 +236,17 @@ export const DashboardSettingForm = ({
234
236
  <EventSettingForm isLoading={isLoading} />
235
237
 
236
238
  <ProviderSettingForm isLoading={isLoading} />
239
+ <Form.Group controlId={eventDeadlineErrorMessageId}>
240
+ <Form.Label>{t("eventDeadlineErrorMessage")}</Form.Label>
241
+ <Form.Control
242
+ {...register("eventDeadlineErrorMessage")}
243
+ isInvalid={Boolean(errors.eventDeadlineErrorMessage)}
244
+ disabled={isLoading}
245
+ />
246
+ <Form.Control.Feedback type="invalid">
247
+ {errors.eventDeadlineErrorMessage?.message}
248
+ </Form.Control.Feedback>
249
+ </Form.Group>
237
250
  </FormProvider>
238
251
  {hasPermission && (
239
252
  <Button
@@ -374,7 +374,7 @@ export function SortableTreeItem({
374
374
  items={sortableItems}
375
375
  strategy={verticalListSortingStrategy}
376
376
  >
377
- <Collapse in={expanded}>
377
+ <Collapse in={expanded}>
378
378
  <div className="ml-0">{children}</div>
379
379
  </Collapse>
380
380
  </SortableContext>
@@ -23,7 +23,7 @@ export function BooleanSwitch({
23
23
  const { t } = useTranslation("Design");
24
24
 
25
25
  const options: SelectItem[] = [
26
- { id: 1, value: firstValueTitle ?? t("yes") },
26
+ { id: 1, value: firstValueTitle ?? t("yes") },
27
27
  { id: 0, value: secondValueTitle ?? t("no") },
28
28
  ];
29
29
 
@@ -47,141 +47,127 @@
47
47
  margin-left: 0.5rem;
48
48
  }
49
49
 
50
- .ryft-payment-form {
51
- .submit-button-wrapper {
52
- margin: -1rem 0 1rem;
53
-
54
- button {
55
- width: 100%;
56
- }
57
- }
58
- #mobile-pay-divider-container {
59
- display: flex;
60
- position: relative;
61
- margin-bottom: 1rem;
62
- #mobile-pay-divider-text {
63
- margin-right: 1rem;
64
- font-size: 0.875rem;
65
- font-weight: 600;
66
- }
67
- #mobile-pay-divider {
68
- width: 100%;
69
- border-bottom: 1px #dfdfdf solid;
70
- margin-bottom: 0.6rem;
71
- }
72
- }
73
-
74
- #card-title-container {
75
- height: auto;
76
- border: none;
77
- margin-bottom: 0.5rem;
78
- text-align: left;
79
- :first-child {
80
- font-size: 1rem;
81
- font-weight: 600;
82
- margin-bottom: 1rem;
83
- }
84
-
85
- .form-label {
86
- margin-bottom: 0.5rem;
87
- }
88
- }
89
- .mobile-pay-title {
90
- display: block;
91
- font-weight: 600;
92
- font-size: 1rem;
93
- color: black;
94
- padding: 0;
95
- font-style: normal;
96
- font-family: inherit;
97
- margin-bottom: 1rem;
98
- }
99
- }
100
50
  .form {
101
51
  .input {
102
52
  border: 2px solid #525252 !important;
103
53
  }
104
54
  }
105
55
 
106
- .ryft-payment-form {
107
- @include media-breakpoint-up(md) {
108
- .submit-button-wrapper {
109
- max-width: 15.5rem;
110
- }
111
- }
112
-
113
- // it's style for Google and Apple pay container, for unknown reasons we can't move this html elements with appendChild or replaceChild
114
- .ryft-pay-grid {
115
- width: 100%;
116
- max-width: 15.5rem;
117
- margin-bottom: 1rem;
56
+ @include media-breakpoint-down(sm) {
57
+ .left-block-container {
58
+ max-height: 100%;
59
+ overflow: visible;
118
60
  }
119
- .ryft-pay-apple-pay-button {
120
- border-radius: 0.25rem;
121
- }
122
- }
123
-
124
- .divider {
125
- display: none !important;
126
- }
127
- }
128
- @include media-breakpoint-down(sm) {
129
- .left-block-container {
130
- max-height: 100%;
131
- overflow: visible;
132
61
  }
133
62
  }
134
- }
135
-
136
- @include media-breakpoint-down(sm) {
137
- flex-direction: column-reverse;
138
- overflow: scroll;
139
63
 
140
64
  @include media-breakpoint-down(sm) {
141
- .left-block {
142
- min-height: 100%;
143
- }
144
- .right-block {
145
- margin: 0 auto;
146
- width: 100%;
147
- .children-wrapper {
148
- .accordion {
149
- .collapse {
150
- overflow: visible;
151
- overflow-x: unset;
152
- scrollbar-width: unset;
65
+ flex-direction: column-reverse;
66
+ overflow: scroll;
67
+
68
+ @include media-breakpoint-down(sm) {
69
+ .left-block {
70
+ min-height: 100%;
71
+ }
72
+ .right-block {
73
+ margin: 0 auto;
74
+ width: 100%;
75
+ .children-wrapper {
76
+ .accordion {
77
+ .collapse {
78
+ overflow: visible;
79
+ overflow-x: unset;
80
+ scrollbar-width: unset;
81
+ }
153
82
  }
154
83
  }
155
84
  }
156
85
  }
157
86
  }
158
87
  }
159
- }
160
- ::-webkit-scrollbar {
161
- display: none;
162
- scrollbar-width: none;
88
+ ::-webkit-scrollbar {
89
+ display: none;
90
+ scrollbar-width: none;
91
+ }
163
92
  }
164
93
  }
165
94
 
166
- @include media-breakpoint-down(md) {
167
- .payment_link {
168
- .page-body {
169
- .left-block {
170
- .left-block-container {
171
- .ryft-payment-form {
172
- position: relative;
173
- max-height: 300px !important;
174
- .ryft-pay-grid {
175
- width: 100%;
176
- max-width: 100%;
177
- }
178
- }
179
- }
180
- }
95
+ #ryft-threeDSMethodIframe {
96
+ display: none;
97
+ }
98
+
99
+ .ryft-payment-form {
100
+ .submit-button-wrapper {
101
+ margin: -1rem 0 1rem;
102
+
103
+ button {
104
+ width: 100%;
181
105
  }
182
106
  }
107
+ #mobile-pay-divider-container {
108
+ display: flex;
109
+ position: relative;
110
+ margin-bottom: 1rem;
111
+ #mobile-pay-divider-text {
112
+ margin-right: 1rem;
113
+ font-size: 0.875rem;
114
+ font-weight: 600;
115
+ }
116
+ #mobile-pay-divider {
117
+ width: 100%;
118
+ border-bottom: 1px #dfdfdf solid;
119
+ margin-bottom: 0.6rem;
120
+ }
121
+ }
122
+
123
+ #card-title-container {
124
+ height: auto;
125
+ border: none;
126
+ margin-bottom: 0.5rem;
127
+ text-align: left;
128
+ :first-child {
129
+ font-size: 1rem;
130
+ font-weight: 600;
131
+ margin-bottom: 1rem;
132
+ }
133
+
134
+ .form-label {
135
+ margin-bottom: 0.5rem;
136
+ }
137
+ }
138
+ .mobile-pay-title {
139
+ display: block;
140
+ font-weight: 600;
141
+ font-size: 1rem;
142
+ color: black;
143
+ padding: 0;
144
+ font-style: normal;
145
+ font-family: inherit;
146
+ margin-bottom: 1rem;
147
+ }
183
148
  }
184
149
 
185
- #ryft-threeDSMethodIframe {
186
- display: none;
150
+ @include media-breakpoint-up(md) {
151
+ .ryft-payment-form,
152
+ .iframe-payment-form {
153
+ position: relative;
154
+ max-height: 300px !important;
155
+ .submit-button-wrapper {
156
+ max-width: 15.5rem;
157
+ }
158
+ }
159
+
160
+ // it's style for Google and Apple pay container, for unknown reasons we can't move this html elements with appendChild or replaceChild
161
+ .ryft-pay-grid {
162
+ width: 100%;
163
+ max-width: 15.5rem;
164
+ margin-bottom: 1rem;
165
+ }
166
+ .ryft-pay-apple-pay-button {
167
+ border-radius: 0.25rem;
168
+ }
169
+
170
+ .divider {
171
+ display: none !important;
172
+ }
187
173
  }
@@ -5,7 +5,7 @@
5
5
  flex-wrap: wrap;
6
6
 
7
7
  .result-card {
8
- height: 14.25rem;
8
+ height: 14rem;
9
9
  border: 1px solid $gray-400;
10
10
  max-width: calc(50% - 0.75rem);
11
11
  flex: 0 0 calc(50% - 0.75rem);