@licklist/design 0.71.18-dev.0 → 0.71.18-dev.10

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 (126) hide show
  1. package/dist/events/edit-event-modal/component/SelectEventProductSet/component/EditEventProductSet.js +1 -0
  2. package/dist/events/event-statistic-modal/utils/index.js +3 -3
  3. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.d.ts +18 -0
  4. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.d.ts.map +1 -0
  5. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.js +295 -0
  6. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.d.ts +15 -0
  7. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.d.ts.map +1 -0
  8. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.js +89 -0
  9. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.d.ts +14 -0
  10. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.d.ts.map +1 -0
  11. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.js +404 -0
  12. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.d.ts +10 -0
  13. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.d.ts.map +1 -0
  14. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.js +87 -0
  15. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/index.d.ts +2 -0
  16. package/dist/iframe/ProductWithModifierModal/ModifierSetModal/index.d.ts.map +1 -0
  17. package/dist/iframe/ProductWithModifierModal/index.d.ts +2 -0
  18. package/dist/iframe/ProductWithModifierModal/index.d.ts.map +1 -0
  19. package/dist/iframe/ProductWithModifierModal/utils.d.ts +5 -0
  20. package/dist/iframe/ProductWithModifierModal/utils.d.ts.map +1 -0
  21. package/dist/iframe/ProductWithModifierModal/utils.js +21 -0
  22. package/dist/iframe/activity-card/ActivityCard.d.ts +1 -2
  23. package/dist/iframe/activity-card/ActivityCard.d.ts.map +1 -1
  24. package/dist/iframe/activity-card/ActivityCard.js +1 -7
  25. package/dist/iframe/event/ticket-description/TicketDescription.d.ts +2 -1
  26. package/dist/iframe/event/ticket-description/TicketDescription.d.ts.map +1 -1
  27. package/dist/iframe/event/ticket-description/TicketDescription.js +4 -3
  28. package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.d.ts.map +1 -1
  29. package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.js +15 -2
  30. package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts +4 -0
  31. package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts.map +1 -1
  32. package/dist/iframe/order-process/components/BookingSummary/utils/index.js +29 -2
  33. package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.d.ts.map +1 -1
  34. package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.js +106 -2
  35. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts +3 -1
  36. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts.map +1 -1
  37. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.js +95 -1
  38. package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.d.ts +23 -0
  39. package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.d.ts.map +1 -0
  40. package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.js +62 -0
  41. package/dist/iframe/order-process/components/CategoryProduct/constants.d.ts +2 -0
  42. package/dist/iframe/order-process/components/CategoryProduct/constants.d.ts.map +1 -0
  43. package/dist/iframe/order-process/components/CategoryProduct/constants.js +4 -0
  44. package/dist/iframe/order-process/components/utils/useOnWindowUnmount.d.ts +6 -0
  45. package/dist/iframe/order-process/components/utils/useOnWindowUnmount.d.ts.map +1 -0
  46. package/dist/iframe/order-process/components/utils/useOnWindowUnmount.js +18 -0
  47. package/dist/iframe/payment/order-items-table/hooks/useTableData.d.ts.map +1 -1
  48. package/dist/iframe/payment/order-items-table/hooks/useTableData.js +83 -10
  49. package/dist/iframe/payment/order-items-table/utils/index.d.ts.map +1 -1
  50. package/dist/iframe/payment/order-items-table/utils/index.js +15 -0
  51. package/dist/iframe/payment/order-items-table/utils/paymentSummary.js +2 -2
  52. package/dist/index.js +1 -1
  53. package/dist/product-set/form/ProductSetForm.d.ts +3 -1
  54. package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
  55. package/dist/product-set/form/ProductSetForm.js +6 -4
  56. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  57. package/dist/product-set/form/ProductsControl.js +24 -5
  58. package/dist/product-set/form/context.d.ts +3 -1
  59. package/dist/product-set/form/context.d.ts.map +1 -1
  60. package/dist/product-set/form/context.js +2 -1
  61. package/dist/product-set/product/ProductControl.d.ts +8 -0
  62. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  63. package/dist/product-set/product/ProductControl.js +25 -1
  64. package/dist/product-set/utils/index.d.ts +88 -0
  65. package/dist/product-set/utils/index.d.ts.map +1 -1
  66. package/dist/product-set/utils/index.js +19 -1
  67. package/dist/report/ReportRunnerModal/ReportRunnerModal.d.ts +2 -1
  68. package/dist/report/ReportRunnerModal/ReportRunnerModal.d.ts.map +1 -1
  69. package/dist/report/ReportRunnerModal/ReportRunnerModal.js +3 -2
  70. package/dist/sales/coupon/utils/index.d.ts +2 -1
  71. package/dist/sales/coupon/utils/index.d.ts.map +1 -1
  72. package/dist/sales/modals/refund-modal/RefundModal.d.ts +6 -2
  73. package/dist/sales/modals/refund-modal/RefundModal.d.ts.map +1 -1
  74. package/dist/sales/modals/refund-modal/RefundModal.js +8 -4
  75. package/dist/sales/modals/refund-modal/index.d.ts +2 -2
  76. package/dist/sales/modals/refund-modal/index.d.ts.map +1 -1
  77. package/dist/styles/date-time-button/DateTimeButton.scss +8 -1
  78. package/dist/styles/events/EditEventModal.scss +2 -0
  79. package/dist/styles/iframe-page/Page.scss +16 -0
  80. package/dist/styles/iframe-page/PageBody.scss +4 -0
  81. package/dist/styles/modals/Modals.scss +16 -0
  82. package/dist/styles/product-set/EditProductSetElement.scss +1 -0
  83. package/dist/styles/product-set/ProductSetForm.scss +11 -0
  84. package/dist/styles/sales/ManualBooking.scss +6 -0
  85. package/dist/styles/themes/bookedit/index.scss +19 -0
  86. package/package.json +6 -6
  87. package/src/events/event-statistic-modal/utils/index.ts +4 -4
  88. package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.tsx +212 -0
  89. package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.tsx +75 -0
  90. package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.tsx +393 -0
  91. package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.tsx +98 -0
  92. package/src/iframe/ProductWithModifierModal/ModifierSetModal/index.ts +1 -0
  93. package/src/iframe/ProductWithModifierModal/index.ts +1 -0
  94. package/src/iframe/ProductWithModifierModal/utils.ts +29 -0
  95. package/src/iframe/activity-card/ActivityCard.stories.tsx +0 -2
  96. package/src/iframe/activity-card/ActivityCard.tsx +0 -4
  97. package/src/iframe/event/ticket-description/TicketDescription.tsx +5 -3
  98. package/src/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.tsx +21 -1
  99. package/src/iframe/order-process/components/BookingSummary/utils/index.ts +42 -1
  100. package/src/iframe/order-process/components/CategoryProduct/CategoryProduct.tsx +155 -75
  101. package/src/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.tsx +58 -1
  102. package/src/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.tsx +86 -0
  103. package/src/iframe/order-process/components/CategoryProduct/constants.ts +1 -0
  104. package/src/iframe/order-process/components/utils/useOnWindowUnmount.ts +25 -0
  105. package/src/iframe/payment/order-items-table/hooks/useTableData.tsx +84 -14
  106. package/src/iframe/payment/order-items-table/utils/index.ts +23 -0
  107. package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +2 -2
  108. package/src/product-set/form/ProductSetForm.tsx +11 -3
  109. package/src/product-set/form/ProductsControl.tsx +33 -15
  110. package/src/product-set/form/context.tsx +5 -0
  111. package/src/product-set/product/ProductControl.tsx +37 -1
  112. package/src/product-set/utils/index.ts +19 -0
  113. package/src/report/ReportRunnerModal/ReportRunnerModal.tsx +3 -0
  114. package/src/sales/coupon/utils/index.ts +5 -3
  115. package/src/sales/modals/refund-modal/RefundModal.tsx +15 -6
  116. package/src/sales/modals/refund-modal/index.ts +7 -2
  117. package/src/styles/date-time-button/DateTimeButton.scss +8 -1
  118. package/src/styles/events/EditEventModal.scss +2 -0
  119. package/src/styles/iframe-page/Page.scss +16 -0
  120. package/src/styles/iframe-page/PageBody.scss +4 -0
  121. package/src/styles/modals/Modals.scss +16 -0
  122. package/src/styles/product-set/EditProductSetElement.scss +1 -0
  123. package/src/styles/product-set/ProductSetForm.scss +11 -0
  124. package/src/styles/sales/ManualBooking.scss +6 -0
  125. package/src/styles/themes/bookedit/index.scss +19 -0
  126. package/yarn.lock +345 -336
@@ -1,3 +1,7 @@
1
+ import { OrderModifier } from '@licklist/core/dist/DataMapper/Order/OrderModifierDataMapper'
2
+ import {
3
+ OrderModifierByProduct
4
+ } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
1
5
  import { QuantityCheckProductInfo } from '@licklist/plugins/dist/types/Api/verifyStock'
2
6
  import { OrderItem } from '@licklist/plugins/dist/types/context/Iframe/orderItems'
3
7
 
@@ -13,6 +17,9 @@ export const cartSumByOrderProducts = ({
13
17
  }
14
18
  return orderProducts.reduce((prevSumValue: number, product) => {
15
19
  if (!product) return 0
20
+ const modifiersPrice = calculateTotalModifiersPrice(
21
+ product?.orderModifiersSets,
22
+ )
16
23
 
17
24
  const price = isTotalSum
18
25
  ? product?.price
@@ -20,10 +27,44 @@ export const cartSumByOrderProducts = ({
20
27
  ? product?.deposit
21
28
  : product?.price
22
29
 
23
- return prevSumValue + price * product.quantity
30
+ return prevSumValue + price * product.quantity + modifiersPrice
24
31
  }, 0)
25
32
  }
26
33
 
34
+ export const getModifierName = (
35
+ modifier: OrderModifierByProduct,
36
+ ) => {
37
+ const modifierName = (orderModifier: OrderModifier) => orderModifier?.modifier?.name ?? orderModifier?.name
38
+ return `${modifier.modifiers.map((item) => (
39
+ item?.quantity > 1 ? `${item?.quantity}x - ${modifierName(item)}` : modifierName(item))).join(', ')}`
40
+ }
41
+
42
+ export const calculateTotalModifiersPrice = (
43
+ orderModifiersSets: OrderModifierByProduct[],
44
+ ) =>
45
+ orderModifiersSets
46
+ ?.map((set) =>
47
+ set.modifiers.reduce(
48
+ (sum, modifier) =>
49
+ sum + modifier.price * modifier.quantity * set.productQuantity,
50
+ 0,
51
+ ),
52
+ )
53
+ .reduce((total, setTotal) => total + setTotal, 0)
54
+
55
+ export const getOrderProductModifiersPrice = (
56
+ modifierFromProduct: OrderModifierByProduct,
57
+ ) => {
58
+ const { modifiers, productQuantity } = modifierFromProduct
59
+ const modifiersPrices = modifiers.reduce(
60
+ (prevSumModifier: number, modifier: OrderModifier) =>
61
+ prevSumModifier + modifier.price * modifier.quantity,
62
+ 0,
63
+ )
64
+
65
+ return modifiersPrices * productQuantity
66
+ }
67
+
27
68
  export const getProductError = (
28
69
  productsWithErrors: QuantityCheckProductInfo[],
29
70
  productId: OrderItem['id'],
@@ -1,4 +1,4 @@
1
- import { useEffect, useMemo } from 'react'
1
+ import { useEffect, useMemo, useState } from 'react'
2
2
  import { useFormContext, Controller } from 'react-hook-form'
3
3
  import clsx from 'clsx'
4
4
  import { useTranslation } from 'react-i18next'
@@ -10,8 +10,14 @@ import {
10
10
  Product,
11
11
  ProductCategory,
12
12
  } from '@licklist/plugins/dist/types/context/sale/menuSteps'
13
+ import { Button } from 'react-bootstrap'
14
+ import { FaTrashAlt } from 'react-icons/fa'
15
+ import { ProductWithModifierSetModal } from 'src/iframe/ProductWithModifierModal'
16
+ import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
13
17
  import { TicketDescription } from '../../../event/ticket-description'
14
18
  import { ProductQuantityInput } from './components/ProductQuantityInput'
19
+ import { FormOrderItem } from './components/ProductQuantityInput/ProductQuantityInput'
20
+ import { ProductWithModifier } from './components/ProductWithModifier/ProductWithModifier'
15
21
 
16
22
  interface CategoryProductProps {
17
23
  product: Product
@@ -31,7 +37,9 @@ export const CategoryProduct = ({
31
37
  const { formatNumber } = useIntl()
32
38
  const { t } = useTranslation(['Design', 'Validation'])
33
39
  const { control, clearErrors, setError } = useFormContext()
34
-
40
+ const [editOrderModifierIndex, setEditOrderModifierIndex] =
41
+ useState<OrderModifierByProduct>(undefined)
42
+ const [modifierIndex, setModifierIndex] = useState<number>(undefined)
35
43
  const hasDeposits = category.allowDeposits && product?.deposit < product.price
36
44
 
37
45
  const productQuantityError = useMemo(() => {
@@ -118,83 +126,155 @@ export const CategoryProduct = ({
118
126
  render={({
119
127
  field: { onChange, value: productInfo = {}, ref },
120
128
  fieldState: { invalid, error },
121
- }) => (
122
- <div id={String(product.id)} className='iframe-event__category-product'>
123
- <div className={clsx('iframe-event__product', invalid && 'error')}>
124
- <TicketDescription
125
- title={product.name}
126
- description={product.description}
127
- className={clsx('iframe-event__product-description')}
128
- images={product.images}
129
- isRequired={product.isRequired}
130
- canExpand={canExpandDescription}
131
- />
132
- </div>
133
- <div className='iframe-event__product-price-wrapper'>
134
- <span className='product-price'>
135
- {formatNumber(product.price, {
136
- style: 'currency',
137
- currency: Config.Currency.GBP,
138
- })}
139
- </span>
140
- <ProductQuantityInput
141
- onChange={onChange}
142
- productInfo={productInfo}
143
- refCallback={ref}
144
- clearErrors={clearErrors}
145
- product={{
146
- ...product,
147
- isSoldOut: product?.isSoldOut || checkIfSoldOutProduct(),
148
- }}
149
- category={category}
150
- invalid={invalid}
151
- />
152
- </div>
153
- {hasDeposits && !category?.remainderExpireAfter && (
154
- <div className='mt-4'>
155
- {t('Design:payNowAndUponArrival', {
156
- deposit: formatNumber(product?.deposit, {
157
- style: 'currency',
158
- currency: Config.Currency.GBP,
159
- }),
160
- remainder: formatNumber(product.price - product?.deposit, {
161
- style: 'currency',
162
- currency: Config.Currency.GBP,
163
- }),
164
- })}
165
- </div>
166
- )}
129
+ }) => {
130
+ const deleteOrderModifier = (orderModifierIndex: number) => {
131
+ const removedOrderModifierIndex = (
132
+ productInfo as FormOrderItem
133
+ ).orderModifiersSets?.filter(
134
+ (_, index) => index !== orderModifierIndex,
135
+ )
136
+ const productInfoWithRemove = {
137
+ ...productInfo,
138
+ orderModifiersSets: removedOrderModifierIndex,
139
+ quantity: removedOrderModifierIndex.reduce(
140
+ (acc, product) => product.productQuantity + acc,
141
+ 0,
142
+ ),
143
+ }
144
+ onChange(productInfoWithRemove)
145
+ }
167
146
 
168
- {hasDeposits && category?.remainderExpireAfter > 0 && (
169
- <div className='mt-4'>
170
- {t('Design:payNowAndReminderDays', {
171
- deposit: formatNumber(product?.deposit, {
172
- style: 'currency',
173
- currency: Config.Currency.GBP,
174
- }),
175
- remainder: formatNumber(product.price - product?.deposit, {
147
+ const editOrderModifierSet = (orderModifierIndex: number) => {
148
+ const editOrderModifierIndex = (
149
+ productInfo as FormOrderItem
150
+ ).orderModifiersSets.find((_, index) => {
151
+ setModifierIndex(index)
152
+ return index === orderModifierIndex
153
+ })
154
+ setEditOrderModifierIndex(editOrderModifierIndex)
155
+ }
156
+
157
+ const onChangeWithModifierSets = (value: FormOrderItem) => {
158
+ const editedOrderModifiersSets = (
159
+ productInfo as FormOrderItem
160
+ ).orderModifiersSets
161
+ ?.filter((_, index) => index !== modifierIndex)
162
+ .concat(value.orderModifiersSets)
163
+
164
+ onChange({
165
+ ...value,
166
+ orderModifiersSets: editedOrderModifiersSets,
167
+ quantity: editedOrderModifiersSets.reduce(
168
+ (acc, product) => product.productQuantity + acc,
169
+ 0,
170
+ ),
171
+ })
172
+ setEditOrderModifierIndex(undefined)
173
+ }
174
+
175
+ return (
176
+ <div
177
+ id={String(product.id)}
178
+ className='iframe-event__category-product'
179
+ >
180
+ <div className={clsx('iframe-event__product', invalid && 'error')}>
181
+ <TicketDescription
182
+ title={product.name}
183
+ description={product.description}
184
+ className={clsx('iframe-event__product-description')}
185
+ images={product.images}
186
+ isRequired={product.isRequired}
187
+ canExpand={canExpandDescription}
188
+ />
189
+ </div>
190
+ <div className='iframe-event__product-price-wrapper'>
191
+ <span className='product-price'>
192
+ {formatNumber(product.price, {
176
193
  style: 'currency',
177
194
  currency: Config.Currency.GBP,
178
- }),
179
- days: category?.remainderExpireAfter,
180
- })}
195
+ })}
196
+ </span>
197
+ <ProductQuantityInput
198
+ onChange={onChange}
199
+ productInfo={productInfo}
200
+ refCallback={ref}
201
+ clearErrors={clearErrors}
202
+ product={{
203
+ ...product,
204
+ isSoldOut: product?.isSoldOut || checkIfSoldOutProduct(),
205
+ }}
206
+ category={category}
207
+ invalid={invalid}
208
+ />
181
209
  </div>
182
- )}
183
- {invalid && (
184
- <div className='d-flex mt-3 w-100'>
185
- <p className='iframe-event__message-error'>
186
- {HookFormService.hasError(error, 'required') &&
187
- t('Design:pleaseSelectAtLeastFrom', {
188
- min: 1,
189
- type: 'item',
190
- from: 'this category',
191
- })}
192
- {HookFormService.hasError(error, 'validate') && error.message}
193
- </p>
194
- </div>
195
- )}
196
- </div>
197
- )}
210
+ {hasDeposits && !category?.remainderExpireAfter && (
211
+ <div className='mt-4'>
212
+ {t('Design:payNowAndUponArrival', {
213
+ deposit: formatNumber(product?.deposit, {
214
+ style: 'currency',
215
+ currency: Config.Currency.GBP,
216
+ }),
217
+ remainder: formatNumber(product.price - product?.deposit, {
218
+ style: 'currency',
219
+ currency: Config.Currency.GBP,
220
+ }),
221
+ })}
222
+ </div>
223
+ )}
224
+ {(productInfo as FormOrderItem).orderModifiersSets?.length > 0 && (
225
+ <>
226
+ {(productInfo as FormOrderItem).orderModifiersSets.map(
227
+ (modifier, index) => (
228
+ <ProductWithModifier
229
+ key={modifier.productQuantity.toString()}
230
+ modifier={modifier}
231
+ modifierKey={index}
232
+ editOrderModifierSet={editOrderModifierSet}
233
+ deleteOrderModifier={deleteOrderModifier}
234
+ />
235
+ ),
236
+ )}
237
+ </>
238
+ )}
239
+ {hasDeposits && category?.remainderExpireAfter > 0 && (
240
+ <div className='mt-4'>
241
+ {t('Design:payNowAndReminderDays', {
242
+ deposit: formatNumber(product?.deposit, {
243
+ style: 'currency',
244
+ currency: Config.Currency.GBP,
245
+ }),
246
+ remainder: formatNumber(product.price - product?.deposit, {
247
+ style: 'currency',
248
+ currency: Config.Currency.GBP,
249
+ }),
250
+ days: category?.remainderExpireAfter,
251
+ })}
252
+ </div>
253
+ )}
254
+ {invalid && (
255
+ <div className='d-flex mt-3 w-100'>
256
+ <p className='iframe-event__message-error'>
257
+ {HookFormService.hasError(error, 'required') &&
258
+ t('Design:pleaseSelectAtLeastFrom', {
259
+ min: 1,
260
+ type: 'item',
261
+ from: 'this category',
262
+ })}
263
+ {HookFormService.hasError(error, 'validate') && error.message}
264
+ </p>
265
+ </div>
266
+ )}
267
+ <ProductWithModifierSetModal
268
+ show={!!editOrderModifierIndex}
269
+ onHide={() => setEditOrderModifierIndex(undefined)}
270
+ editOrderModifier={editOrderModifierIndex}
271
+ onChange={onChangeWithModifierSets}
272
+ product={product}
273
+ category={category}
274
+ />
275
+ </div>
276
+ )
277
+ }}
198
278
  />
199
279
  )
200
280
  }
@@ -1,14 +1,19 @@
1
+ import { useState } from 'react'
1
2
  import clsx from 'clsx'
2
3
  import { Button } from 'react-bootstrap'
4
+ import { isEmpty } from 'lodash'
3
5
  import { useTranslation } from 'react-i18next'
4
6
  import { FieldValues, RefCallBack, UseFormClearErrors } from 'react-hook-form'
5
7
  import {
6
8
  Product,
7
9
  ProductCategory,
8
10
  } from '@licklist/plugins/dist/types/context/sale/menuSteps'
11
+ import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
9
12
  import { NumberInput } from '../NumberInput'
13
+ // eslint-disable-next-line
14
+ import { ProductWithModifierSetModal } from '../../../../../ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal'
10
15
 
11
- interface FormOrderItem {
16
+ export interface FormOrderItem {
12
17
  id: number
13
18
  name: string
14
19
  price: number
@@ -17,6 +22,7 @@ interface FormOrderItem {
17
22
  deposit?: number | null
18
23
  quantity: number
19
24
  capacity?: number | null
25
+ orderModifiersSets?: OrderModifierByProduct[] | null
20
26
  }
21
27
 
22
28
  interface ProductQuantityInputProps {
@@ -40,6 +46,7 @@ export const ProductQuantityInput = ({
40
46
  invalid,
41
47
  }: ProductQuantityInputProps) => {
42
48
  const { t } = useTranslation('Design')
49
+ const [open, handleOpenModal] = useState(false)
43
50
 
44
51
  const onChange = (quantity: number | null) => {
45
52
  _onChange({
@@ -48,12 +55,35 @@ export const ProductQuantityInput = ({
48
55
  deposit: product?.deposit,
49
56
  hasDeposit: category.allowDeposits && product?.deposit < product.price,
50
57
  price: product.price,
58
+ orderModifiersSets: [],
51
59
  productCategoryId: category.id,
52
60
  quantity,
53
61
  capacity: product?.capacity,
54
62
  })
55
63
  }
56
64
 
65
+ const onChangeWithModifierSets = (productOrder: FormOrderItem) => {
66
+ if (isEmpty(productInfo)) {
67
+ _onChange(productOrder)
68
+ return handleOpenModal(false)
69
+ }
70
+
71
+ _onChange({
72
+ id: productInfo.id,
73
+ name: productInfo.name,
74
+ deposit: productInfo?.deposit,
75
+ hasDeposit: productInfo.hasDeposit,
76
+ price: productInfo.price,
77
+ orderModifiersSets: productInfo.orderModifiersSets?.concat(
78
+ productOrder.orderModifiersSets,
79
+ ),
80
+ productCategoryId: category.id,
81
+ quantity: productInfo.quantity + productOrder.quantity,
82
+ capacity: productInfo?.capacity,
83
+ })
84
+ return handleOpenModal(false)
85
+ }
86
+
57
87
  if (product.isSoldOut) {
58
88
  return (
59
89
  <div className='iframe-event__sold-out-wrapper'>
@@ -62,6 +92,33 @@ export const ProductQuantityInput = ({
62
92
  )
63
93
  }
64
94
 
95
+ if ((product as Product).modifiersSet.length) {
96
+ return (
97
+ <>
98
+ <Button
99
+ ref={refCallback}
100
+ disabled={product.isSoldOut}
101
+ className={clsx(
102
+ `iframe-event__${
103
+ productInfo?.quantity ? 'unselect-product' : 'select-product'
104
+ }`,
105
+ invalid && 'error',
106
+ )}
107
+ onClick={() => handleOpenModal(true)}
108
+ >
109
+ +
110
+ </Button>
111
+ <ProductWithModifierSetModal
112
+ show={open}
113
+ onHide={() => handleOpenModal(false)}
114
+ onChange={onChangeWithModifierSets}
115
+ product={product}
116
+ category={category}
117
+ />
118
+ </>
119
+ )
120
+ }
121
+
65
122
  if (product?.maxAmount === 1) {
66
123
  return (
67
124
  <Button
@@ -0,0 +1,86 @@
1
+ import { Button } from 'react-bootstrap'
2
+ import { useTranslation } from 'react-i18next'
3
+ import { FaTrashAlt } from 'react-icons/fa'
4
+ import { Config } from '@licklist/core'
5
+ import { useIntl } from 'react-intl'
6
+ import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
7
+ import {
8
+ getOrderProductModifiersPrice,
9
+ getModifierName,
10
+ } from '../../../BookingSummary/utils'
11
+
12
+ export interface FormOrderItem {
13
+ id: number
14
+ name: string
15
+ price: number
16
+ productCategoryId: number
17
+ hasDeposit?: boolean
18
+ deposit?: number | null
19
+ quantity: number
20
+ capacity?: number | null
21
+ orderModifiersSets?: OrderModifierByProduct[] | null
22
+ }
23
+
24
+ interface ProductQuantityInputProps {
25
+ modifier: OrderModifierByProduct
26
+ modifierKey: number
27
+ isManualBooking?: boolean
28
+ isSummary? :boolean
29
+ deleteOrderModifier?: (order: number) => void
30
+ editOrderModifierSet?: (order: number) => void
31
+ }
32
+
33
+ export const ProductWithModifier = ({
34
+ modifier,
35
+ modifierKey,
36
+ isManualBooking = false,
37
+ isSummary = false,
38
+ deleteOrderModifier,
39
+ editOrderModifierSet,
40
+ }: ProductQuantityInputProps) => {
41
+ const { t } = useTranslation('Design')
42
+ const { formatNumber } = useIntl()
43
+
44
+ const modifierName = getModifierName(modifier)
45
+
46
+ const orderModifierDescription = `${modifier.productQuantity}`
47
+
48
+ const modifierPrice = getOrderProductModifiersPrice(modifier)
49
+
50
+ const fullModifiersPrice = formatNumber(modifierPrice, {
51
+ style: 'currency',
52
+ currency: Config.Currency.GBP,
53
+ })
54
+ return (
55
+ <div
56
+ key={modifierKey}
57
+ className='d-flex p-2 justify-content-between align-items-center'
58
+ >
59
+ <div className='d-flex'>
60
+ <p className='font-weight-bold w-25 pr-4'>{`${orderModifierDescription} x`}</p>
61
+ <p>{modifierName ? ` ${modifierName}` : t('withoutModifier')}</p>
62
+ </div>
63
+ {isManualBooking || isSummary ? (
64
+ <p className='price'>{fullModifiersPrice}</p>
65
+ ) : (
66
+ <div>
67
+ <Button
68
+ className='ml-2'
69
+ variant='link'
70
+ onClick={() => editOrderModifierSet(modifierKey)}
71
+ >
72
+ {t('customise')}
73
+ </Button>
74
+
75
+ <Button
76
+ className='ml-2'
77
+ variant='link'
78
+ onClick={() => deleteOrderModifier(modifierKey)}
79
+ >
80
+ <FaTrashAlt />
81
+ </Button>
82
+ </div>
83
+ )}
84
+ </div>
85
+ )
86
+ }
@@ -0,0 +1 @@
1
+ export const MAX_PRODUCT_NUMBER = 100000 // max number
@@ -0,0 +1,25 @@
1
+ import { useEffect } from 'react'
2
+
3
+ export type UseOnWindowUnmountProps = {
4
+ onBeforeUnload: (event: Event) => void
5
+ onPopState: (event: Event) => void
6
+ }
7
+
8
+ export const useOnWindowUnmount = ({
9
+ onBeforeUnload,
10
+ onPopState,
11
+ }: UseOnWindowUnmountProps) => {
12
+ useEffect(() => {
13
+ window.history.pushState(null, '', window.location.pathname)
14
+ window.addEventListener('beforeunload', onBeforeUnload)
15
+ window.addEventListener('popstate', onPopState)
16
+
17
+ return () => {
18
+ window.removeEventListener('beforeunload', onBeforeUnload)
19
+ window.removeEventListener('popstate', onPopState)
20
+ }
21
+ // eslint-disable-next-line react-hooks/exhaustive-deps
22
+ }, [])
23
+
24
+ return null
25
+ }