@licklist/design 0.69.2 → 0.69.3-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 (187) hide show
  1. package/dist/affiliate/form/AffiliateForm.d.ts.map +1 -1
  2. package/dist/auth/Login/LoginComponent.js +2 -1
  3. package/dist/events/edit-event-modal/component/EditEventForm/EditEventForm.d.ts +2 -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 +3 -2
  6. package/dist/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.d.ts +2 -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 +53 -24
  9. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.js +1 -0
  10. package/dist/events/edit-event-modal/utils/getDefaultProductSet.d.ts.map +1 -1
  11. package/dist/events/edit-event-modal/utils/getDefaultProductSet.js +3 -2
  12. package/dist/iframe/activity-card/ActivityCard.d.ts +5 -4
  13. package/dist/iframe/activity-card/ActivityCard.d.ts.map +1 -1
  14. package/dist/iframe/activity-card/ActivityCard.js +52 -40
  15. package/dist/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.d.ts.map +1 -1
  16. package/dist/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.js +13 -0
  17. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts.map +1 -1
  18. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.js +2 -0
  19. package/dist/iframe/payment/order-items-table/utils/paymentSummary.d.ts.map +1 -1
  20. package/dist/iframe/ryft/RyftPaymentForm.d.ts +2 -2
  21. package/dist/iframe/ryft/RyftPaymentForm.d.ts.map +1 -1
  22. package/dist/iframe/ryft/RyftPaymentForm.js +8 -2
  23. package/dist/iframe/ryft/utils/ryft-form.d.ts +2 -1
  24. package/dist/iframe/ryft/utils/ryft-form.d.ts.map +1 -1
  25. package/dist/iframe/ryft/utils/ryft-form.js +20 -1
  26. package/dist/index.js +1 -0
  27. package/dist/layout/DropDown.d.ts +2 -1
  28. package/dist/layout/DropDown.d.ts.map +1 -1
  29. package/dist/modals/confirmation/ConfirmModal.d.ts +3 -1
  30. package/dist/modals/confirmation/ConfirmModal.d.ts.map +1 -1
  31. package/dist/modals/confirmation/ConfirmModal.js +172 -8
  32. package/dist/notification/email-template/control/EmailTemplateControl.d.ts.map +1 -1
  33. package/dist/notification/email-template/control/EmailTemplateControl.js +3 -0
  34. package/dist/product-set/card/ProductSetCard.d.ts +6 -2
  35. package/dist/product-set/card/ProductSetCard.d.ts.map +1 -1
  36. package/dist/product-set/card/ProductSetCard.js +30 -11
  37. package/dist/product-set/control/DateInput.d.ts.map +1 -1
  38. package/dist/product-set/control/DateInput.js +2 -2
  39. package/dist/product-set/control/ProductSetControl.d.ts +4 -0
  40. package/dist/product-set/control/ProductSetControl.d.ts.map +1 -1
  41. package/dist/product-set/control/ProductSetControl.js +24 -3
  42. package/dist/product-set/control/ProductSetImageControl.d.ts +2 -0
  43. package/dist/product-set/control/ProductSetImageControl.d.ts.map +1 -0
  44. package/dist/product-set/control/ProductSetImageControl.js +279 -0
  45. package/dist/product-set/form/ProductCategoriesControl.d.ts.map +1 -1
  46. package/dist/product-set/form/ProductCategoriesControl.js +48 -2
  47. package/dist/product-set/form/ProductSetForm.d.ts +4 -1
  48. package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
  49. package/dist/product-set/form/ProductSetForm.js +64 -1
  50. package/dist/product-set/form/ProductSetNameControl.d.ts +6 -0
  51. package/dist/product-set/form/ProductSetNameControl.d.ts.map +1 -0
  52. package/dist/product-set/form/ProductSetNameControl.js +35 -0
  53. package/dist/product-set/form/ProductZonesControl.d.ts.map +1 -1
  54. package/dist/product-set/form/ProductZonesControl.js +0 -2
  55. package/dist/product-set/form/ProductsControl.js +1 -0
  56. package/dist/product-set/form/SelectCategoryModal.d.ts +12 -0
  57. package/dist/product-set/form/SelectCategoryModal.d.ts.map +1 -1
  58. package/dist/product-set/form/SelectCategoryModal.js +1 -1
  59. package/dist/product-set/form/SubProductsControl.d.ts.map +1 -1
  60. package/dist/product-set/form/SubProductsControl.js +0 -3
  61. package/dist/product-set/form/VenueMapsControl.d.ts.map +1 -1
  62. package/dist/product-set/form/VenueMapsControl.js +0 -3
  63. package/dist/product-set/form/index.d.ts +1 -0
  64. package/dist/product-set/form/index.d.ts.map +1 -1
  65. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  66. package/dist/product-set/product/booking-management/ProductBookingManagementControl.d.ts.map +1 -1
  67. package/dist/product-set/product/booking-management/ProductBookingManagementControl.js +6 -0
  68. package/dist/product-set/product/deposit/ProductDepositControl.d.ts.map +1 -1
  69. package/dist/product-set/product/deposit/ProductDepositControl.js +3 -0
  70. package/dist/product-set/product/duration/ProductDurationControl.d.ts.map +1 -1
  71. package/dist/product-set/product/duration/ProductDurationControl.js +6 -0
  72. package/dist/product-set/product/price/ProductPriceControl.d.ts.map +1 -1
  73. package/dist/product-set/product/price/ProductPriceControl.js +3 -0
  74. package/dist/product-set/product/quantity/ProductQuantityConstantControl.d.ts.map +1 -1
  75. package/dist/product-set/product/quantity/ProductQuantityConstantControl.js +6 -0
  76. package/dist/product-set/product/quantity/ProductQuantityControl.d.ts.map +1 -1
  77. package/dist/product-set/product/quantity/ProductQuantityControl.js +6 -0
  78. package/dist/product-set/product/quantity/ProductQuantityRechargingControl.d.ts.map +1 -1
  79. package/dist/product-set/product/quantity/ProductQuantityRechargingControl.js +4 -1
  80. package/dist/product-set/product-category/ProductCategoryControl.d.ts.map +1 -1
  81. package/dist/product-set/product-category/ProductCategoryControl.js +12 -0
  82. package/dist/product-set/utils/index.d.ts +7 -0
  83. package/dist/product-set/utils/index.d.ts.map +1 -1
  84. package/dist/product-set/utils/index.js +10 -1
  85. package/dist/recurrence-input/RecurrenceEndInput.d.ts.map +1 -1
  86. package/dist/recurrence-input/RecurrenceEndInput.js +3 -0
  87. package/dist/recurring-date-picker-input/RecurrenceEndInput.d.ts.map +1 -1
  88. package/dist/resource/form/components/CapacityControl.d.ts.map +1 -1
  89. package/dist/resource/form/components/CapacityControl.js +3 -0
  90. package/dist/resource/form/components/SortControl.d.ts.map +1 -1
  91. package/dist/resource/form/components/SortControl.js +3 -0
  92. package/dist/sales/booking/results/components/ResultCard.d.ts.map +1 -1
  93. package/dist/sales/booking/results/components/ResultCard.js +0 -2
  94. package/dist/sales/coupon/control/CouponFormControl.d.ts.map +1 -1
  95. package/dist/sales/coupon/control/CouponFormControl.js +21 -0
  96. package/dist/setting/admin/PaymentFeeForm.d.ts.map +1 -1
  97. package/dist/setting/admin/PaymentFeeForm.js +16 -1
  98. package/dist/setting/dashboard/DashboardSettingForm.d.ts.map +1 -1
  99. package/dist/setting/dashboard/DashboardSettingForm.js +4 -1
  100. package/dist/snippet/snippet-template/preview/Preview.d.ts.map +1 -1
  101. package/dist/snippet/snippet-template/preview/Preview.js +6 -0
  102. package/dist/sortable-tree/SortableTreeItem.d.ts +2 -1
  103. package/dist/sortable-tree/SortableTreeItem.d.ts.map +1 -1
  104. package/dist/sortable-tree/SortableTreeItem.js +10 -4
  105. package/dist/static/CurrencyNumberInput.d.ts.map +1 -1
  106. package/dist/static/CurrencyNumberInput.js +3 -0
  107. package/dist/static/form-number-input/FormNumberInput.d.ts.map +1 -1
  108. package/dist/static/form-number-input/FormNumberInput.js +3 -0
  109. package/dist/static/number-input/NumberInput.d.ts.map +1 -1
  110. package/dist/static/number-input/NumberInput.js +3 -0
  111. package/dist/styles/activity-card/{GridActivitiesCard.scss → ActivitiesCard.scss} +19 -5
  112. package/dist/styles/activity-card/ListActivitiesCard.scss +12 -42
  113. package/dist/styles/activity-card/_index.scss +1 -1
  114. package/dist/styles/iframe-external-modal/IframeExternalModal.scss +2 -2
  115. package/dist/styles/product-set/ProductSetForm.scss +22 -0
  116. package/dist/styles/ryft-payment-form/RyftPaymentForm.scss +28 -1
  117. package/dist/styles/sales/BookingResults.scss +1 -1
  118. package/dist/typeahead/Typeahead.d.ts +5 -1
  119. package/dist/typeahead/Typeahead.d.ts.map +1 -1
  120. package/dist/typeahead/Typeahead.js +9 -2
  121. package/dist/zone/form/components/GameDurationControl.d.ts.map +1 -1
  122. package/dist/zone/form/components/GameDurationControl.js +3 -0
  123. package/dist/zone/form/components/SortControl.d.ts.map +1 -1
  124. package/dist/zone/form/components/SortControl.js +3 -0
  125. package/package.json +8 -6
  126. package/src/affiliate/form/AffiliateForm.tsx +1 -0
  127. package/src/auth/Login/LoginComponent.tsx +1 -1
  128. package/src/events/edit-event-modal/component/EditEventForm/EditEventForm.tsx +3 -2
  129. package/src/events/edit-event-modal/component/SelectEventProductSet/SelectEventProductSet.tsx +91 -86
  130. package/src/events/edit-event-modal/utils/getDefaultProductSet.ts +2 -1
  131. package/src/iframe/activity-card/ActivityCard.tsx +35 -24
  132. package/src/iframe/order-process/components/CategoryProduct/components/NumberInput/NumberInput.tsx +9 -0
  133. package/src/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.tsx +1 -0
  134. package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +1 -0
  135. package/src/iframe/ryft/RyftPaymentForm.tsx +13 -5
  136. package/src/iframe/ryft/utils/ryft-form.ts +26 -2
  137. package/src/layout/DropDown.tsx +1 -1
  138. package/src/modals/confirmation/ConfirmModal.tsx +19 -3
  139. package/src/notification/email-template/control/EmailTemplateControl.tsx +1 -0
  140. package/src/product-set/card/ProductSetCard.tsx +47 -8
  141. package/src/product-set/control/DateInput.tsx +2 -1
  142. package/src/product-set/control/ProductSetControl.tsx +46 -52
  143. package/src/product-set/control/ProductSetImageControl.tsx +97 -0
  144. package/src/product-set/form/ProductCategoriesControl.tsx +37 -1
  145. package/src/product-set/form/ProductSetForm.tsx +24 -2
  146. package/src/product-set/form/ProductSetNameControl.tsx +27 -0
  147. package/src/product-set/form/ProductZonesControl.tsx +1 -4
  148. package/src/product-set/form/SelectCategoryModal.tsx +2 -2
  149. package/src/product-set/form/SubProductsControl.tsx +0 -3
  150. package/src/product-set/form/VenueMapsControl.tsx +0 -3
  151. package/src/product-set/form/index.ts +1 -0
  152. package/src/product-set/product/ProductControl.tsx +0 -1
  153. package/src/product-set/product/advanced-options/AdvancedOptions.tsx +1 -1
  154. package/src/product-set/product/booking-management/ProductBookingManagementControl.tsx +2 -0
  155. package/src/product-set/product/deposit/ProductDepositControl.tsx +1 -0
  156. package/src/product-set/product/duration/ProductDurationControl.tsx +2 -0
  157. package/src/product-set/product/price/ProductPriceControl.tsx +1 -0
  158. package/src/product-set/product/quantity/ProductQuantityConstantControl.tsx +2 -0
  159. package/src/product-set/product/quantity/ProductQuantityControl.tsx +2 -0
  160. package/src/product-set/product/quantity/ProductQuantityRechargingControl.tsx +1 -0
  161. package/src/product-set/product-category/ProductCategoryControl.tsx +4 -0
  162. package/src/product-set/product-zone/ProductZoneControl.tsx +1 -1
  163. package/src/product-set/utils/index.ts +11 -0
  164. package/src/recurrence-input/RecurrenceEndInput.tsx +1 -0
  165. package/src/recurring-date-picker-input/RecurrenceEndInput.tsx +1 -0
  166. package/src/resource/form/components/CapacityControl.tsx +1 -0
  167. package/src/resource/form/components/SortControl.tsx +1 -0
  168. package/src/sales/booking/results/components/ResultCard.tsx +0 -2
  169. package/src/sales/coupon/control/CouponFormControl.tsx +7 -0
  170. package/src/setting/admin/PaymentFeeForm.tsx +5 -0
  171. package/src/setting/dashboard/DashboardSettingForm.tsx +1 -0
  172. package/src/snippet/snippet-template/preview/Preview.tsx +6 -0
  173. package/src/sortable-tree/SortableTreeItem.tsx +6 -0
  174. package/src/static/CurrencyNumberInput.tsx +1 -0
  175. package/src/static/form-number-input/FormNumberInput.tsx +1 -0
  176. package/src/static/number-input/NumberInput.tsx +1 -0
  177. package/src/styles/activity-card/{GridActivitiesCard.scss → ActivitiesCard.scss} +19 -5
  178. package/src/styles/activity-card/ListActivitiesCard.scss +12 -42
  179. package/src/styles/activity-card/_index.scss +1 -1
  180. package/src/styles/iframe-external-modal/IframeExternalModal.scss +2 -2
  181. package/src/styles/product-set/ProductSetForm.scss +22 -0
  182. package/src/styles/ryft-payment-form/RyftPaymentForm.scss +28 -1
  183. package/src/styles/sales/BookingResults.scss +1 -1
  184. package/src/typeahead/Typeahead.tsx +15 -1
  185. package/src/zone/form/components/GameDurationControl.tsx +1 -0
  186. package/src/zone/form/components/SortControl.tsx +1 -0
  187. package/yarn.lock +61 -35
@@ -9,15 +9,20 @@ import RouteService from '@licklist/plugins/dist/services/Route/RouteService'
9
9
  import { FaEllipsisH, FaEye, FaTrashAlt } from 'react-icons/fa'
10
10
  import { ConfirmModal } from '../../modals'
11
11
  import { MenuButton } from '../../table/MenuButton'
12
+ import { ProductSetNameControl } from '../form/ProductSetNameControl'
12
13
 
13
14
  export interface ProductSetCardProps extends HasPermissionProp {
14
15
  name: string
15
16
  rrule?: string
16
17
  href: string
17
- onCopy: () => void
18
+ duplicateProductSetName: string
19
+ onChangeDuplicateProductSetName: (value: string) => void
20
+ onCopy: () => Promise<boolean | undefined>
18
21
  onRemove: () => void
22
+ isLoading?: boolean
19
23
  className?: string
20
24
  override?: number
25
+ duplicateProductSetError?: string
21
26
  }
22
27
 
23
28
  export function ProductSetCard({
@@ -26,6 +31,10 @@ export function ProductSetCard({
26
31
  href,
27
32
  onCopy,
28
33
  onRemove,
34
+ onChangeDuplicateProductSetName,
35
+ duplicateProductSetName,
36
+ duplicateProductSetError,
37
+ isLoading,
29
38
  className = '',
30
39
  hasPermission = true,
31
40
  override = 0,
@@ -35,19 +44,23 @@ export function ProductSetCard({
35
44
  const productSetCardClasses = `product-set-card ${className}`
36
45
  const [isOverlayVisibile, setIsOverlayVisible] = useState(false)
37
46
 
47
+ const onCardClick = () => {
48
+ RouteService.redirectTo(href)
49
+ }
38
50
  return (
51
+ // eslint-disable-next-line jsx-a11y/click-events-have-key-events
39
52
  <div
40
53
  role='button'
41
54
  tabIndex={0}
42
55
  className='border-0 product-set-card-wrapper w-100 pb-0'
43
- onClick={() => RouteService.redirectTo(href)}
44
- onKeyUp={() => RouteService.redirectTo(href)}
56
+ onClick={onCardClick}
45
57
  >
46
58
  <div className={productSetCardClasses}>
47
59
  <div className='product-set-card-link'>
48
60
  <div className='d-flex flex-column'>
49
61
  <div>
50
- {name} {rrule && `(${RRule.fromString(rrule).toText()})`}
62
+ {name}
63
+ {rrule && `(${RRule.fromString(rrule).toText()})`}
51
64
  </div>
52
65
  {!!override && (
53
66
  <div className='h6 bold ml-1'>
@@ -79,14 +92,33 @@ export function ProductSetCard({
79
92
  >
80
93
  {hasPermission && (
81
94
  <>
82
- <ListGroup.Item action as='div'>
95
+ <ListGroup.Item
96
+ action
97
+ as='div'
98
+ role='button'
99
+ tabIndex={0}
100
+ onClick={(e) => e.stopPropagation()}
101
+ >
83
102
  {Boolean(onCopy) && (
84
- <ConfirmModal>
103
+ <ConfirmModal
104
+ // confirm function memoize the callback function and it leads to bugs
105
+ confirmationHandler={onCopy}
106
+ disabledButtons={isLoading}
107
+ content={
108
+ <ProductSetNameControl
109
+ value={duplicateProductSetName}
110
+ onChange={onChangeDuplicateProductSetName}
111
+ error={duplicateProductSetError}
112
+ />
113
+ }
114
+ >
85
115
  {(confirm) => (
86
116
  <MenuButton
87
117
  onClick={() => {
88
118
  setIsOverlayVisible(false)
89
- confirm(onCopy)
119
+ onChangeDuplicateProductSetName(name)
120
+ // confirm function memoize the callback function and it leads to bugs
121
+ confirm(() => {})
90
122
  }}
91
123
  name={t('duplicate')}
92
124
  className='product-set-card-menu-item-text'
@@ -95,7 +127,14 @@ export function ProductSetCard({
95
127
  </ConfirmModal>
96
128
  )}
97
129
  </ListGroup.Item>
98
- <ListGroup.Item action className='text-danger' as='div'>
130
+ <ListGroup.Item
131
+ action
132
+ className='text-danger'
133
+ as='div'
134
+ role='button'
135
+ tabIndex={0}
136
+ onClick={(e) => e.stopPropagation()}
137
+ >
99
138
  {Boolean(onRemove) && (
100
139
  <ConfirmModal>
101
140
  {(confirm) => (
@@ -247,7 +247,8 @@ export const DateInput = ({
247
247
  menuRecurrence={menuRecurrence}
248
248
  onEdit={() => handleOnEdit(menuRecurrence, index)}
249
249
  errorMessage={
250
- errors?.menuRecurrences?.[`${index}`]?.availableTimes?.message
250
+ errors?.menuRecurrences?.[`${index}`]?.availableTimes
251
+ ?.message || errors?.menuRecurrences?.[`${index}`]?.message
251
252
  }
252
253
  />
253
254
  ))}
@@ -22,12 +22,11 @@ import HookFormService from '@licklist/plugins/dist/services/Form/HookFormServic
22
22
  import { ruleForUrlWithProtocol } from '@licklist/plugins/dist/validation/Rules/urlRule'
23
23
  import { WorkHour } from '@licklist/core/dist/DataMapper/Provider/WorkHourDataMapper'
24
24
  import { checkIfZoneCategory } from '@licklist/plugins'
25
+ import { Image } from '@licklist/core/dist/DataMapper/Media/ImageDataMapper'
25
26
  import { WarningMessage } from '../../static'
26
27
  import { SelectItem } from '../../types/generic/SelectItem'
27
28
  import {
28
29
  DateAndRecurrenceInput,
29
- // TODO: Show Date Component, when reccurent date bugs are fixed
30
- // DateAndRecurrenceInput,
31
30
  DateAndRecurrenceInputValues,
32
31
  } from './DateAndRecurrenceInput'
33
32
  import TutorialGifCard from './TutorialGifCard'
@@ -35,6 +34,7 @@ import { Step } from '../types'
35
34
  import { StepsControl } from '../form/StepsControl'
36
35
  import { Typeahead } from '../../typeahead'
37
36
  import { DateInput } from './DateInput'
37
+ import { ProductSetImageControl } from './ProductSetImageControl'
38
38
 
39
39
  const OPERATIONAL_COST_TITLES = {
40
40
  [OPERATIONAL_COST_PROVIDER]: 'operationalCostProvider',
@@ -47,6 +47,8 @@ const RELY_ON_PEOPLE_TYPE_TITLES = {
47
47
  [RELY_ON_PEOPLE_QUANTITY]: 'peopleQuantity',
48
48
  }
49
49
 
50
+ const MAX_DESCRIPTION_LENGTH = 500
51
+
50
52
  export interface TemplateItem {
51
53
  id: string
52
54
  value: EmailTemplate | SmsTemplate
@@ -55,6 +57,8 @@ export interface TemplateItem {
55
57
 
56
58
  export interface ProductSetControlValues extends DateAndRecurrenceInputValues {
57
59
  name: string
60
+ description?: string
61
+ image?: Image
58
62
  type: ProductSetType
59
63
  termsAndConditions: string
60
64
  thankYouPageUrl: string
@@ -65,6 +69,7 @@ export interface ProductSetControlValues extends DateAndRecurrenceInputValues {
65
69
  steps: Step[]
66
70
  emailTemplates?: TemplateItem[]
67
71
  smsTemplates?: TemplateItem[]
72
+ localImageBlobURL?: string
68
73
  }
69
74
 
70
75
  export interface ProductSetControlShared {
@@ -122,6 +127,7 @@ export function ProductSetControl({
122
127
  const steps = watch('steps')
123
128
 
124
129
  const nameId = useId()
130
+ const descriptionId = useId()
125
131
  const termsAndConditionsId = useId()
126
132
  const relyOnPeopleTypeId = useId()
127
133
 
@@ -174,6 +180,22 @@ export function ProductSetControl({
174
180
  </Form.Control.Feedback>
175
181
  </Form.Group>
176
182
 
183
+ <Form.Group controlId={descriptionId}>
184
+ <Form.Label>{t('Design:description')}</Form.Label>
185
+ <Form.Control
186
+ {...register('description', {
187
+ maxLength: MAX_DESCRIPTION_LENGTH,
188
+ })}
189
+ as='textarea'
190
+ isInvalid={Boolean(errors.description)}
191
+ />
192
+ <Form.Control.Feedback type='invalid'>
193
+ {errors.description?.message}
194
+ </Form.Control.Feedback>
195
+ </Form.Group>
196
+
197
+ <ProductSetImageControl />
198
+
177
199
  {showDateSelector ? (
178
200
  <DateInput
179
201
  workHours={isZoneAdded ? workHours : undefined}
@@ -207,27 +229,6 @@ export function ProductSetControl({
207
229
  </Col>
208
230
  <Col md={6} sm={12}>
209
231
  <div className='second-column'>
210
- {/* <Controller
211
- control={control}
212
- name="type"
213
- render={({ field }) => (
214
- <Form.Group className="d-flex flex-column flex-grow-1 align-items-start">
215
- <Form.Label>{t("Design:checkoutType")}</Form.Label>
216
- <Switch
217
- name={field.name}
218
- options={PRODUCT_SET_TYPES.map((type) => ({
219
- key: type,
220
- id: type,
221
- value: t(type),
222
- }))}
223
- value={field.value}
224
- onChange={field.onChange}
225
- disabled={isLoading}
226
- />
227
- </Form.Group>
228
- )}
229
- /> */}
230
-
231
232
  <Form.Group>
232
233
  <Form.Label className='mb-0'>
233
234
  {t('Design:operationalCost')}
@@ -364,35 +365,28 @@ export function ProductSetControl({
364
365
  <Controller
365
366
  control={control}
366
367
  name='fieldSetId'
367
- render={({ field }) => {
368
- const fieldValue = Number(field.value)
369
-
370
- return (
371
- <>
372
- <Form.Label>{t('Design:customFields')}</Form.Label>
373
- <Form.Control
374
- onChange={field.onChange}
375
- value={fieldValue}
376
- as='select'
377
- disabled={isOverrides}
378
- isInvalid={HookFormService.isInvalid(
379
- 'fieldSetId',
380
- errors,
381
- )}
382
- >
383
- <option value=''>{t('Design:choose')}</option>
384
- {fieldSets?.map((fieldSet) => (
385
- <option value={fieldSet.id} key={fieldSet.id}>
386
- {fieldSet.name}
387
- </option>
388
- ))}
389
- </Form.Control>
390
- <Form.Control.Feedback type='invalid'>
391
- {HookFormService.getErrors('fieldSetId', errors)}
392
- </Form.Control.Feedback>
393
- </>
394
- )
395
- }}
368
+ render={({ field }) => (
369
+ <>
370
+ <Form.Label>{t('Design:customFields')}</Form.Label>
371
+ <Form.Control
372
+ onChange={field.onChange}
373
+ value={Number(field.value)}
374
+ as='select'
375
+ disabled={isOverrides}
376
+ isInvalid={HookFormService.isInvalid('fieldSetId', errors)}
377
+ >
378
+ <option value=''>{t('Design:choose')}</option>
379
+ {fieldSets?.map((fieldSet) => (
380
+ <option value={fieldSet.id} key={fieldSet.id}>
381
+ {fieldSet.name}
382
+ </option>
383
+ ))}
384
+ </Form.Control>
385
+ <Form.Control.Feedback type='invalid'>
386
+ {HookFormService.getErrors('fieldSetId', errors)}
387
+ </Form.Control.Feedback>
388
+ </>
389
+ )}
396
390
  />
397
391
  </Form.Group>
398
392
 
@@ -0,0 +1,97 @@
1
+ import { useFormContext } from 'react-hook-form'
2
+ import { HookFormService, useImages } from '@licklist/plugins'
3
+ import { IMAGE_TYPE_IMAGE } from '@licklist/core/dist/DataMapper/Media/ImageDataMapper'
4
+ import { useCallback, useEffect } from 'react'
5
+ import { Form } from 'react-bootstrap'
6
+ import { FileUpload } from 'src/file-upload'
7
+ import { useTranslation } from 'react-i18next'
8
+ import { isEqual } from 'lodash'
9
+ import { ProductSetControlValues } from '..'
10
+
11
+ export const ProductSetImageControl = () => {
12
+ const { t } = useTranslation('Design')
13
+
14
+ const {
15
+ formState: { errors },
16
+ setValue,
17
+ watch,
18
+ clearErrors,
19
+ } = useFormContext<ProductSetControlValues>()
20
+ const currentProductSet: ProductSetControlValues = watch()
21
+
22
+ const {
23
+ images,
24
+ handleImageRemove,
25
+ handleImageUploading,
26
+ isLoading: isImageUploading,
27
+ setImages,
28
+ } = useImages(null)
29
+
30
+ const onFilesChange = useCallback(
31
+ async (files: File[]) => {
32
+ const uploadedFiles = await handleImageUploading(files, IMAGE_TYPE_IMAGE)
33
+
34
+ if (!uploadedFiles) return
35
+
36
+ setValue('localImageBlobURL', URL.createObjectURL(files[0]) as never)
37
+ },
38
+ // eslint-disable-next-line react-hooks/exhaustive-deps
39
+ [handleImageUploading],
40
+ )
41
+
42
+ const onImageRemove = useCallback(
43
+ (id, path) => {
44
+ handleImageRemove(id, path)
45
+ setValue('localImageBlobURL', undefined as never)
46
+ },
47
+ // eslint-disable-next-line react-hooks/exhaustive-deps
48
+ [handleImageRemove],
49
+ )
50
+
51
+ useEffect(() => {
52
+ if (!currentProductSet || !currentProductSet.image) return
53
+
54
+ setImages([
55
+ {
56
+ ...currentProductSet.image,
57
+ url:
58
+ currentProductSet.image.url || currentProductSet?.localImageBlobURL,
59
+ },
60
+ ])
61
+ // eslint-disable-next-line react-hooks/exhaustive-deps
62
+ }, [currentProductSet?.image])
63
+
64
+ useEffect(() => {
65
+ if (isEqual(images[0], currentProductSet?.image)) return
66
+
67
+ setValue('image', (images[0] || null) as never)
68
+
69
+ if (images[0]) {
70
+ clearErrors('image')
71
+ }
72
+ // eslint-disable-next-line react-hooks/exhaustive-deps
73
+ }, [images])
74
+
75
+ return (
76
+ <Form.Group controlId='name'>
77
+ <Form.Control
78
+ isInvalid={HookFormService.isInvalid('image', errors)}
79
+ hidden
80
+ />
81
+ <FileUpload
82
+ onFilesChange={onFilesChange}
83
+ allowedExtensions={['jpeg', 'jpg', 'png']}
84
+ subTitle='.jpeg .jpg .png'
85
+ enablePreview
86
+ onFileRemove={onImageRemove}
87
+ defaultFiles={images}
88
+ isLoading={isImageUploading}
89
+ withIcon
90
+ title={t('Design:addImage')}
91
+ />
92
+ <Form.Control.Feedback type='invalid'>
93
+ {HookFormService.getErrors('image', errors)}
94
+ </Form.Control.Feedback>
95
+ </Form.Group>
96
+ )
97
+ }
@@ -8,6 +8,7 @@ import {
8
8
  useFormContext,
9
9
  useWatch,
10
10
  } from 'react-hook-form'
11
+ import { FaBars, FaBowlingBall, FaCalendar, FaTicketAlt } from 'react-icons/fa'
11
12
  import { useTranslation } from 'react-i18next'
12
13
  import { useSensor, MouseSensor } from '@dnd-kit/core'
13
14
  import {
@@ -25,7 +26,11 @@ import { ProductCategoryControl } from '../product-category'
25
26
  import { ProductCategory } from '../types'
26
27
  import { ProductsControl } from './ProductsControl'
27
28
  import { ProductSetFormValues, WithIsLoading } from './ProductSetForm'
28
- import { SelectCategoryModal } from './SelectCategoryModal'
29
+ import {
30
+ SelectCategoryModal,
31
+ CATEGORY_TYPES_NAMES,
32
+ CategoryConfig,
33
+ } from './SelectCategoryModal'
29
34
  import { ProductSetLoadingContext } from './context'
30
35
  import { VenueMapSetModal } from './VenueMapSetModal'
31
36
  import { moveArrayElements, sortArrayByIndex } from '../utils'
@@ -33,6 +38,29 @@ import { useSortableTreeFunctions } from '../hooks/useSortableTreeFunctions'
33
38
  // @TODO not for first release
34
39
  // import Popover from "./ProductSetFormPopover";
35
40
 
41
+ const CATEGORIES_TYPE: Partial<Record<CategoryType, CategoryConfig>> = {
42
+ [CATEGORY_TYPES_NAMES.tickets]: {
43
+ label: 'tickets',
44
+ icon: <FaTicketAlt color='#0e8ce2' size={10} />,
45
+ },
46
+ [CATEGORY_TYPES_NAMES.bookings]: {
47
+ label: 'bookings',
48
+ icon: <FaCalendar color='#0e8ce2' size={10} />,
49
+ },
50
+ [CATEGORY_TYPES_NAMES.menuItems]: {
51
+ label: 'menuItems',
52
+ icon: <FaBars color='#0e8ce2' size={10} />,
53
+ },
54
+ [CATEGORY_TYPES_NAMES.game]: {
55
+ label: 'game',
56
+ icon: <FaBowlingBall color='#0e8ce2' size={10} />,
57
+ },
58
+ [CATEGORY_TYPES_NAMES.fixedDuration]: {
59
+ label: 'fixedDuration',
60
+ icon: <FaCalendar color='#0e8ce2' size={10} />,
61
+ },
62
+ }
63
+
36
64
  interface ProductCategoriesControlProps extends WithIsLoading {
37
65
  stepIndex: number
38
66
  isOverrides?: boolean
@@ -228,6 +256,8 @@ export function ProductCategoriesControl({
228
256
  setIsExpanded(productCategoryId)
229
257
  }
230
258
 
259
+ const categoryType = CATEGORIES_TYPE[productCategory.type]
260
+
231
261
  return (
232
262
  <Controller
233
263
  key={`product-category-${productCategory._id}`}
@@ -272,6 +302,12 @@ export function ProductCategoriesControl({
272
302
  )}
273
303
  modalClass={ProductSetModalClasses.category}
274
304
  isNewAdded={showCategoryModal}
305
+ itemButton={
306
+ <div className='btn-outline-primary item-icon sm border border-primary rounded-sm'>
307
+ {categoryType.icon}
308
+ <span className='ml-2'>{t(categoryType.label)}</span>
309
+ </div>
310
+ }
275
311
  body={
276
312
  <ProductCategoryControl
277
313
  isLoading={isLoading}
@@ -1,4 +1,4 @@
1
- import { useEffect } from 'react'
1
+ import { useEffect, useState } from 'react'
2
2
  import { FormValues } from '@licklist/plugins/dist/types/services/Form/hook-form-service'
3
3
  import { Button, Form, Col, Row } from 'react-bootstrap'
4
4
  import { FormProvider, useForm } from 'react-hook-form'
@@ -12,6 +12,7 @@ import { isEqual } from 'lodash'
12
12
  import { ProviderBookingManagementSetting } from '@licklist/core/dist/DataMapper/Provider/ProviderBookingManagementSettingDataMapper'
13
13
  import { Zone } from '@licklist/core/dist/DataMapper/Provider/ZoneDataMapper'
14
14
  import { WorkHour } from '@licklist/core/dist/DataMapper/Provider/WorkHourDataMapper'
15
+ import { transformErrorToMessage } from '@licklist/plugins/dist/utils/error'
15
16
  import { Dialog, useDialogContext } from '../../modals/dialog'
16
17
  import {
17
18
  ProductSetControl,
@@ -22,16 +23,21 @@ import { Step } from '../types'
22
23
  import { ProductSetContextProvider, ProductSetLoadingContext } from './context'
23
24
  import { SelectItem } from '../../types/generic/SelectItem'
24
25
  import { checkAvailableTimesErrors, getFilteredTemplates } from '../utils'
26
+ import { ErrorModal } from '../../iframe/order-process/components/ErrorModal'
25
27
 
26
28
  export interface WithIsLoading {
27
29
  isLoading: boolean
28
30
  }
31
+ export interface WithIdOptional {
32
+ id?: number
33
+ }
34
+
29
35
  export interface WithId {
30
36
  id: number
31
37
  }
32
38
  export interface ProductSetFormValues
33
39
  extends FormValues,
34
- WithId,
40
+ WithIdOptional,
35
41
  ProductSetControlValues {
36
42
  steps: Step[]
37
43
  isOverrides?: boolean
@@ -84,6 +90,7 @@ export function ProductSetForm({
84
90
  onApproveDialog,
85
91
  onDeclineDialog,
86
92
  } = useDialogContext()
93
+ const [errorMessage, setErrorMessage] = useState('')
87
94
 
88
95
  const form = useForm<ProductSetFormValues>({
89
96
  defaultValues,
@@ -121,6 +128,15 @@ export function ProductSetForm({
121
128
  if (!serverErrors) {
122
129
  return
123
130
  }
131
+ if (!Array.isArray(serverErrors)) {
132
+ setErrorMessage(transformErrorToMessage(serverErrors))
133
+ return
134
+ }
135
+
136
+ if (Array.isArray(serverErrors) && serverErrors[0]) {
137
+ setErrorMessage(serverErrors[0])
138
+ }
139
+
124
140
  FormErrorService.handleServerErrors(serverErrors, setError)
125
141
  }, [serverErrors, setError])
126
142
 
@@ -156,6 +172,12 @@ export function ProductSetForm({
156
172
  onDecline={onDeclineDialog}
157
173
  />
158
174
 
175
+ <ErrorModal
176
+ message={errorMessage}
177
+ isOpen={!!errorMessage}
178
+ onClose={() => setErrorMessage('')}
179
+ />
180
+
159
181
  <FormProvider {...form}>
160
182
  <Form onSubmit={form.handleSubmit(submitHandler(onSubmitAndRedirect))}>
161
183
  <ProductSetLoadingContext.Consumer>
@@ -0,0 +1,27 @@
1
+ import { Form } from 'react-bootstrap'
2
+ import { useTranslation } from 'react-i18next'
3
+
4
+ export const ProductSetNameControl = ({
5
+ value,
6
+ onChange,
7
+ error,
8
+ }: {
9
+ value: string
10
+ onChange: (value: string) => void
11
+ error?: string
12
+ }) => {
13
+ const { t } = useTranslation(['Design'])
14
+ return (
15
+ <Form.Group>
16
+ <Form.Label>{t('Design:ProductSetName')}*</Form.Label>
17
+ <Form.Control
18
+ value={value}
19
+ maxLength={255}
20
+ onChange={(e) => onChange(e.target.value)}
21
+ placeholder={t('Design:placeholderProductSetName')}
22
+ isInvalid={Boolean(error)}
23
+ />
24
+ <Form.Control.Feedback type='invalid'>{error}</Form.Control.Feedback>
25
+ </Form.Group>
26
+ )
27
+ }
@@ -1,7 +1,4 @@
1
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
2
- // @ts-nocheck
3
- import React, { useContext, useState } from 'react'
4
-
1
+ import { useContext, useState } from 'react'
5
2
  import {
6
3
  ArrayPath,
7
4
  Controller,
@@ -25,7 +25,7 @@ import {
25
25
  } from 'react-icons/fa'
26
26
  import { ProductSetLoadingContext } from './context'
27
27
 
28
- const CATEGORY_TYPES_NAMES = {
28
+ export const CATEGORY_TYPES_NAMES = {
29
29
  menuItems: CATEGORY_TYPE_MENU_ITEMS,
30
30
  tickets: CATEGORY_TYPE_TICKETS,
31
31
  bookings: CATEGORY_TYPE_BOOKINGS,
@@ -33,7 +33,7 @@ const CATEGORY_TYPES_NAMES = {
33
33
  fixedDuration: CATEGORY_TYPE_FIXED_DURATION,
34
34
  } as const
35
35
 
36
- type CategoryConfig = { label: string; icon: ReactElement }
36
+ export type CategoryConfig = { label: string; icon: ReactElement }
37
37
 
38
38
  const MAIN_CATEGORIES: Partial<Record<CategoryType, CategoryConfig>> = {
39
39
  [CATEGORY_TYPES_NAMES.tickets]: {
@@ -70,9 +70,6 @@ export function SubProductsControl({
70
70
  images: subProducts[index]?.images as Image[],
71
71
  }
72
72
  // @ts-expect-error TS2345
73
- // @TODO fix prod type error
74
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
75
- // @ts-ignore
76
73
  append(subProductCopy)
77
74
  }}
78
75
  />
@@ -46,9 +46,6 @@ export const VenueMapsControl = ({
46
46
  url={image.url}
47
47
  name={name}
48
48
  points={points}
49
- // @TODO fix prod type error
50
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
51
- // @ts-ignore
52
49
  products={products}
53
50
  pointProducts={pointProducts}
54
51
  onPointProductsChange={onPointProductsChange}
@@ -1 +1,2 @@
1
1
  export * from './ProductSetForm'
2
+ export * from './ProductSetNameControl'
@@ -34,7 +34,6 @@ import {
34
34
  } from 'react-hook-form'
35
35
  import { useTranslation } from 'react-i18next'
36
36
  import { useImages } from '@licklist/plugins/dist/hooks/Media/useImages'
37
-
38
37
  import {
39
38
  Image,
40
39
  IMAGE_TYPE_IMAGE,
@@ -1,4 +1,4 @@
1
- import React, { useContext } from 'react'
1
+ import { useContext } from 'react'
2
2
  import { Col, Form } from 'react-bootstrap'
3
3
  import { Controller, Path, useFormContext } from 'react-hook-form'
4
4
  import { HookFormService } from '@licklist/plugins'
@@ -86,6 +86,7 @@ export function ProductBookingManagementControl<T extends FormValues>(
86
86
  <Form.Control
87
87
  ref={ref}
88
88
  type='number'
89
+ onWheel={(event) => event.currentTarget.blur()}
89
90
  min={0}
90
91
  step={1}
91
92
  value={value as string}
@@ -129,6 +130,7 @@ export function ProductBookingManagementControl<T extends FormValues>(
129
130
  <Form.Control
130
131
  ref={ref}
131
132
  type='number'
133
+ onWheel={(event) => event.currentTarget.blur()}
132
134
  min='0'
133
135
  step='1'
134
136
  value={value as string}
@@ -50,6 +50,7 @@ export function ProductDepositControl<T extends FormValues>(
50
50
  <Form.Control
51
51
  ref={ref}
52
52
  type='number'
53
+ onWheel={(event) => event.currentTarget.blur()}
53
54
  min={0}
54
55
  max={Number(totalPrice)}
55
56
  step='0.01'
@@ -91,6 +91,7 @@ export const ProductDurationControl = <T,>({
91
91
  <Form.Control
92
92
  type='number'
93
93
  min={0}
94
+ onWheel={(event) => event.currentTarget.blur()}
94
95
  step={1}
95
96
  value={durationHours}
96
97
  disabled={disabled}
@@ -127,6 +128,7 @@ export const ProductDurationControl = <T,>({
127
128
  type='number'
128
129
  min={0}
129
130
  step={1}
131
+ onWheel={(event) => event.currentTarget.blur()}
130
132
  disabled={disabled}
131
133
  value={durationMinutes}
132
134
  isInvalid={isInvalid}