@licklist/design 0.71.18-dev.1 → 0.71.18-dev.11

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 (135) 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/BookingSummary.d.ts +1 -1
  29. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.d.ts.map +1 -1
  30. package/dist/iframe/order-process/components/BookingSummary/BookingSummary.js +2 -1
  31. package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.d.ts.map +1 -1
  32. package/dist/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.js +15 -2
  33. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts +1 -0
  34. package/dist/iframe/order-process/components/BookingSummary/types/index.d.ts.map +1 -1
  35. package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts +4 -0
  36. package/dist/iframe/order-process/components/BookingSummary/utils/index.d.ts.map +1 -1
  37. package/dist/iframe/order-process/components/BookingSummary/utils/index.js +29 -2
  38. package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.d.ts.map +1 -1
  39. package/dist/iframe/order-process/components/CategoryProduct/CategoryProduct.js +106 -2
  40. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts +3 -1
  41. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.d.ts.map +1 -1
  42. package/dist/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.js +95 -1
  43. package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.d.ts +23 -0
  44. package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.d.ts.map +1 -0
  45. package/dist/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.js +62 -0
  46. package/dist/iframe/order-process/components/CategoryProduct/constants.d.ts +2 -0
  47. package/dist/iframe/order-process/components/CategoryProduct/constants.d.ts.map +1 -0
  48. package/dist/iframe/order-process/components/CategoryProduct/constants.js +4 -0
  49. package/dist/iframe/order-process/components/utils/useOnWindowUnmount.d.ts +6 -0
  50. package/dist/iframe/order-process/components/utils/useOnWindowUnmount.d.ts.map +1 -0
  51. package/dist/iframe/order-process/components/utils/useOnWindowUnmount.js +18 -0
  52. package/dist/iframe/payment/order-items-table/hooks/useTableData.d.ts.map +1 -1
  53. package/dist/iframe/payment/order-items-table/hooks/useTableData.js +83 -10
  54. package/dist/iframe/payment/order-items-table/utils/index.d.ts.map +1 -1
  55. package/dist/iframe/payment/order-items-table/utils/index.js +15 -0
  56. package/dist/iframe/payment/order-items-table/utils/paymentSummary.js +2 -2
  57. package/dist/iframe/payment/payment-page/PaymentPage.d.ts.map +1 -1
  58. package/dist/iframe/payment/payment-page/PaymentPage.js +4 -1
  59. package/dist/index.js +1 -1
  60. package/dist/product-set/form/ProductSetForm.d.ts +3 -1
  61. package/dist/product-set/form/ProductSetForm.d.ts.map +1 -1
  62. package/dist/product-set/form/ProductSetForm.js +6 -4
  63. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  64. package/dist/product-set/form/ProductsControl.js +24 -5
  65. package/dist/product-set/form/context.d.ts +3 -1
  66. package/dist/product-set/form/context.d.ts.map +1 -1
  67. package/dist/product-set/form/context.js +2 -1
  68. package/dist/product-set/product/ProductControl.d.ts +8 -0
  69. package/dist/product-set/product/ProductControl.d.ts.map +1 -1
  70. package/dist/product-set/product/ProductControl.js +25 -1
  71. package/dist/product-set/utils/index.d.ts +88 -0
  72. package/dist/product-set/utils/index.d.ts.map +1 -1
  73. package/dist/product-set/utils/index.js +19 -1
  74. package/dist/report/ReportRunnerModal/ReportRunnerModal.d.ts +1 -1
  75. package/dist/report/ReportRunnerModal/ReportRunnerModal.d.ts.map +1 -1
  76. package/dist/sales/coupon/utils/index.d.ts +2 -1
  77. package/dist/sales/coupon/utils/index.d.ts.map +1 -1
  78. package/dist/sales/modals/refund-modal/RefundModal.d.ts +6 -2
  79. package/dist/sales/modals/refund-modal/RefundModal.d.ts.map +1 -1
  80. package/dist/sales/modals/refund-modal/RefundModal.js +8 -4
  81. package/dist/sales/modals/refund-modal/index.d.ts +2 -2
  82. package/dist/sales/modals/refund-modal/index.d.ts.map +1 -1
  83. package/dist/styles/date-time-button/DateTimeButton.scss +8 -1
  84. package/dist/styles/events/EditEventModal.scss +2 -0
  85. package/dist/styles/iframe-page/Page.scss +16 -0
  86. package/dist/styles/iframe-page/PageBody.scss +4 -0
  87. package/dist/styles/modals/Modals.scss +16 -0
  88. package/dist/styles/product-set/EditProductSetElement.scss +1 -0
  89. package/dist/styles/product-set/ProductSetForm.scss +11 -0
  90. package/dist/styles/sales/ManualBooking.scss +6 -0
  91. package/dist/styles/themes/bookedit/index.scss +19 -0
  92. package/package.json +6 -6
  93. package/src/events/event-statistic-modal/utils/index.ts +4 -4
  94. package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.tsx +212 -0
  95. package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.tsx +75 -0
  96. package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.tsx +393 -0
  97. package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.tsx +98 -0
  98. package/src/iframe/ProductWithModifierModal/ModifierSetModal/index.ts +1 -0
  99. package/src/iframe/ProductWithModifierModal/index.ts +1 -0
  100. package/src/iframe/ProductWithModifierModal/utils.ts +29 -0
  101. package/src/iframe/activity-card/ActivityCard.stories.tsx +0 -2
  102. package/src/iframe/activity-card/ActivityCard.tsx +0 -4
  103. package/src/iframe/event/ticket-description/TicketDescription.tsx +5 -3
  104. package/src/iframe/order-process/components/BookingSummary/BookingSummary.tsx +2 -0
  105. package/src/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.tsx +21 -1
  106. package/src/iframe/order-process/components/BookingSummary/types/index.ts +1 -0
  107. package/src/iframe/order-process/components/BookingSummary/utils/index.ts +42 -1
  108. package/src/iframe/order-process/components/CategoryProduct/CategoryProduct.tsx +155 -75
  109. package/src/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.tsx +58 -1
  110. package/src/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.tsx +86 -0
  111. package/src/iframe/order-process/components/CategoryProduct/constants.ts +1 -0
  112. package/src/iframe/order-process/components/utils/useOnWindowUnmount.ts +25 -0
  113. package/src/iframe/payment/order-items-table/hooks/useTableData.tsx +84 -14
  114. package/src/iframe/payment/order-items-table/utils/index.ts +23 -0
  115. package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +2 -2
  116. package/src/iframe/payment/payment-page/PaymentPage.tsx +8 -10
  117. package/src/product-set/form/ProductSetForm.tsx +11 -3
  118. package/src/product-set/form/ProductsControl.tsx +33 -15
  119. package/src/product-set/form/context.tsx +5 -0
  120. package/src/product-set/product/ProductControl.tsx +37 -1
  121. package/src/product-set/utils/index.ts +19 -0
  122. package/src/report/ReportRunnerModal/ReportRunnerModal.tsx +2 -2
  123. package/src/sales/coupon/utils/index.ts +5 -3
  124. package/src/sales/modals/refund-modal/RefundModal.tsx +15 -6
  125. package/src/sales/modals/refund-modal/index.ts +7 -2
  126. package/src/styles/date-time-button/DateTimeButton.scss +8 -1
  127. package/src/styles/events/EditEventModal.scss +2 -0
  128. package/src/styles/iframe-page/Page.scss +16 -0
  129. package/src/styles/iframe-page/PageBody.scss +4 -0
  130. package/src/styles/modals/Modals.scss +16 -0
  131. package/src/styles/product-set/EditProductSetElement.scss +1 -0
  132. package/src/styles/product-set/ProductSetForm.scss +11 -0
  133. package/src/styles/sales/ManualBooking.scss +6 -0
  134. package/src/styles/themes/bookedit/index.scss +19 -0
  135. package/yarn.lock +334 -333
@@ -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
+ }
@@ -1,8 +1,9 @@
1
1
  import { useMemo } from 'react'
2
- import { uniqueId } from 'lodash'
2
+ import { uniqueId, flatMap, flatten, map } from 'lodash'
3
3
  import { useIntl } from 'react-intl'
4
4
  import { useTranslation } from 'react-i18next'
5
5
  import { Product } from '@licklist/core/dist/DataMapper/Product/ProductDataMapper'
6
+ import { OrderModifier } from '@licklist/core/dist/DataMapper/Order/OrderModifierDataMapper'
6
7
  import {
7
8
  PAYMENT_TYPE_VAT,
8
9
  PAYMENT_TYPE_FEE,
@@ -12,6 +13,10 @@ import { StaticTableData } from '../../../../table'
12
13
  import { getProductQuantityAndPrice, getTotalSumByCategory } from '../utils'
13
14
  import { OrderItemsTableProps, SummaryItem } from '../types'
14
15
  import { getOrderSummaryItems } from '../utils/paymentSummary'
16
+ import { Order } from '@licklist/core/dist/DataMapper'
17
+ import { OrderPayment } from '@licklist/core/dist/DataMapper/Order/OrderPaymentDataMapper'
18
+ import { OrderProduct } from '@licklist/core/dist/DataMapper/Order/OrderProductDataMapper'
19
+ import { OrderModifierByProduct } from '@licklist/core/dist/DataMapper/Order/OrderModifiierByProduct'
15
20
 
16
21
  const CURRENCY_DEFAULT = 'GBP'
17
22
  export const PAYMENT_TYPE_TRANSLATE_KEYS = {
@@ -50,19 +55,67 @@ export const useTableData = ({
50
55
  ),
51
56
  })
52
57
 
53
- const renderProductItem = (product: Product) => {
54
- const { quantity, price } = getProductQuantityAndPrice(
55
- order.orderProducts,
56
- product,
57
- )
58
+ const reworkProductStructure = (order: OrderProduct) =>
59
+ order
60
+ ? flatMap(order, (item) => {
61
+ if (!item || !Array.isArray(item)) return []
62
+ return item.map((modGroup, idx) => ({
63
+ deletedAt: order.deletedAt ?? null,
64
+ id: `${order.id}-${idx + 1}`, // Ensuring uniqueness with string concatenation
65
+ orderId: order.orderId ?? null,
66
+ price: order.price ?? 0,
67
+ productId: order.productId ?? '',
68
+ quantity: modGroup.productQuantity ?? 1,
69
+ deposit: order.deposit ?? 0,
70
+ orderProductModifiers: modGroup.modifiers.map((mod) => ({
71
+ modifierId: mod.modifierId ?? '',
72
+ price: mod.price ?? 0,
73
+ productId: mod.productId ?? '',
74
+ quantity: mod.quantity ?? 1,
75
+ modifierSetId: mod.modifierSetId ?? '',
76
+ modifier: mod.modifier ?? null,
77
+ })),
78
+ }))
79
+ })
80
+ : []
81
+
82
+ const renderProductItem = ({
83
+ product,
84
+ productsForCategory,
85
+ }: {
86
+ product: OrderProduct
87
+ productsForCategory: Product[]
88
+ }) => {
89
+ if (product.quantity === 0) {
90
+ return null
91
+ }
92
+
93
+ const name =
94
+ productsForCategory.find((item) => item.id === product.productId)?.name || ''
58
95
 
96
+ return {
97
+ key: product.id,
98
+ name,
99
+ quantity: (
100
+ <div className='quantity'>
101
+ <div className='multiplier'>x</div>
102
+ {product.quantity}
103
+ </div>
104
+ ),
105
+ price: formatPrice(product.price),
106
+ modifier: product?.orderProductModifiers?.map(renderModifierItem) || [],
107
+ }
108
+ }
109
+
110
+ const renderModifierItem = (orderModifier: OrderModifier) => {
111
+ const { quantity, modifier, modifierId, price } = orderModifier
59
112
  if (quantity === 0) {
60
113
  return null
61
114
  }
62
115
 
63
116
  return {
64
- key: product.id,
65
- name: product.name,
117
+ key: modifierId,
118
+ name: ` - ${modifier?.name || ''}`,
66
119
  quantity: (
67
120
  <div className='quantity'>
68
121
  <div className='multiplier'>x</div>
@@ -80,15 +133,33 @@ export const useTableData = ({
80
133
 
81
134
  return productCategories.reduce(
82
135
  (previousValues: StaticTableData[], categoryId) => {
83
- const products = order.products.filter(
136
+ const productsForCategory = order?.products.filter(
84
137
  (product) => product.productCategoryId === categoryId,
85
138
  )
86
139
 
140
+ const products = order.orderProducts.filter((el) =>
141
+ productsForCategory
142
+ .map((product) => product.id)
143
+ .includes(el.productId),
144
+ )
145
+
87
146
  if (!products.length) {
88
147
  return previousValues
89
148
  }
90
-
91
- const filteredProducts = products.map(renderProductItem).filter(Boolean)
149
+ const productsWithReworkedModifier = products.map((product) => {
150
+ if (!product.orderProductModifiers.length) return product
151
+ return reworkProductStructure(product)
152
+ })
153
+
154
+ const filteredProducts = flatten(productsWithReworkedModifier).map(
155
+ (product) =>
156
+ renderProductItem({ product , productsForCategory }),
157
+ )
158
+
159
+ const productWithModifier = flatMap(filteredProducts, (item) => [
160
+ item,
161
+ ...item.modifier,
162
+ ])
92
163
 
93
164
  if (!filteredProducts.length) {
94
165
  return previousValues
@@ -96,8 +167,8 @@ export const useTableData = ({
96
167
 
97
168
  return [
98
169
  ...previousValues,
99
- renderCategoryItem(products),
100
- ...filteredProducts,
170
+ renderCategoryItem(productsForCategory),
171
+ ...productWithModifier,
101
172
  ]
102
173
  },
103
174
  [],
@@ -133,6 +204,5 @@ export const useTableData = ({
133
204
  // eslint-disable-next-line react-hooks/exhaustive-deps
134
205
  [order, externalDiscount, isPaymentProcessed],
135
206
  )
136
-
137
207
  return data
138
208
  }
@@ -6,6 +6,7 @@ import { Product } from '@licklist/core/dist/DataMapper/Product/ProductDataMappe
6
6
  import { PAYMENT_TYPE_DISCOUNT } from '@licklist/core/dist/DataMapper/Order/PaymentDataMapper'
7
7
  import { PaymentDetail } from '@licklist/core/dist/DataMapper/Order/PaymentDetailDataMapper'
8
8
  import { PAYMENT_TYPE_TRANSLATE_KEYS } from '../hooks/useTableData'
9
+ import { OrderModifier } from '@licklist/core/dist/DataMapper/Order/OrderModifierDataMapper'
9
10
 
10
11
  const TRANSLATE_KEYS = {
11
12
  totalAmount: 'totalPaid',
@@ -28,6 +29,7 @@ export const calculateTotalPrice = (
28
29
  order: Order,
29
30
  externalPaymentDetails?: ExternalPaymnetDetail[],
30
31
  ) => {
32
+
31
33
  const totalPrice =
32
34
  order?.orderProducts?.reduce(
33
35
  (total: number, product) =>
@@ -125,5 +127,26 @@ export const getTotalSumByCategory = (
125
127
  product,
126
128
  )
127
129
 
130
+ const modifierFromProduct = orderProducts.find(
131
+ (orderProduct) => orderProduct.productId === product.id,
132
+ )?.orderProductModifiers
133
+ if (modifierFromProduct) {
134
+ const modifierPrice = modifierFromProduct.reduce(
135
+ (prevSum: number, { modifiers }) => {
136
+ const modifiersPrices = modifiers.reduce(
137
+ (prevSumModifier: number, modifier: OrderModifier) =>
138
+ prevSumModifier + modifier.price * modifier.quantity,
139
+ 0,
140
+ )
141
+
142
+ return prevSum + modifiersPrices
143
+ },
144
+ 0,
145
+ )
146
+ const priceWithModifier = price + modifierPrice
147
+
148
+ return prevSum + priceWithModifier * quantity
149
+ }
150
+
128
151
  return prevSum + price * quantity
129
152
  }, 0)
@@ -23,7 +23,7 @@ const paymentNotProcessedSummary = ({
23
23
  ? getExternalPaymentDetail(paymentDetail)
24
24
  : undefined
25
25
 
26
- const total = calculateTotalPrice(order, externalPaymentDetail)
26
+ const total = order?.fullAmount || calculateTotalPrice(order, externalPaymentDetail)
27
27
 
28
28
  const summaryItems: SummaryItem[] = [
29
29
  {
@@ -58,7 +58,7 @@ const processedPaymentSummary = ({
58
58
  price: getPaymentValueByType(order.payments, key),
59
59
  }))
60
60
 
61
- const total = calculateTotalPrice(order, externalPaymentDetail)
61
+ const total = order.fullAmount || calculateTotalPrice(order, externalPaymentDetail)
62
62
 
63
63
  const totalDiscount = calculateTotalDiscount(order.payments)
64
64
 
@@ -131,6 +131,12 @@ export const PaymentPage = ({
131
131
  const totalPaidWithRemainingToPay =
132
132
  data?.amount_to_pay && !!Number(data?.amount_to_pay)
133
133
 
134
+ const totalBooked = paymentMetadata
135
+ ? paymentMetadata.paid
136
+ ? paymentMetadata.total - paymentMetadata.paid
137
+ : paymentMetadata.total
138
+ : orderTotalAmountByFormValues + (bookingSummaryProps?.transactionFee ?? 0)
139
+
134
140
  return (
135
141
  <Page className='payment_link'>
136
142
  {/* TODO wait for Brad's design for close and go back buttons */}
@@ -156,16 +162,8 @@ export const PaymentPage = ({
156
162
  <BookingSummary
157
163
  {...bookingSummaryProps}
158
164
  isPaymentPage
159
- headerComponent={
160
- <SummaryTotalBlock
161
- amount={
162
- paymentMetadata
163
- ? paymentMetadata.total
164
- : orderTotalAmountByFormValues +
165
- (bookingSummaryProps?.transactionFee || 0)
166
- }
167
- />
168
- }
165
+ headerTitle={t('totalBooking')}
166
+ headerComponent={<SummaryTotalBlock amount={totalBooked} />}
169
167
  footer={
170
168
  <div className='d-flex flex-column justify-content-between'>
171
169
  {paymentMetadata ? (
@@ -6,6 +6,7 @@ import { TFunction, useTranslation } from 'react-i18next'
6
6
  import { VenueMapSet } from '@licklist/core/dist/DataMapper/Product/VenueMapSetDataMapper'
7
7
  import { ServerError } from '@licklist/plugins/dist/hooks/Api/useHttpQuery'
8
8
  import FormErrorService from '@licklist/plugins/dist/services/Form/FormErrorService'
9
+ import { ModifierSet } from '@licklist/core/dist/DataMapper/Product/ModifierSetDataMapper'
9
10
 
10
11
  import { isEqual } from 'lodash'
11
12
  // eslint-disable-next-line max-len
@@ -22,7 +23,11 @@ import {
22
23
  import { Step } from '../types'
23
24
  import { ProductSetContextProvider, ProductSetLoadingContext } from './context'
24
25
  import { SelectItem } from '../../types/generic/SelectItem'
25
- import { checkAvailableTimesErrors, getFilteredTemplates } from '../utils'
26
+ import {
27
+ checkAvailableTimesErrors,
28
+ updateModifiersSetAtProductSetForm,
29
+ getFilteredTemplates,
30
+ } from '../utils'
26
31
  import { ErrorModal } from '../../iframe/order-process/components/ErrorModal'
27
32
 
28
33
  export interface WithIsLoading {
@@ -62,6 +67,7 @@ export interface ProductSetFormProps
62
67
  saleDeadline?: number
63
68
  isCreateNewOverrides?: boolean
64
69
  timeZone: string
70
+ modifiersSetList?: ModifierSet[]
65
71
  }
66
72
 
67
73
  export function ProductSetForm({
@@ -71,6 +77,7 @@ export function ProductSetForm({
71
77
  onSubmitAndRedirect,
72
78
  onSubmitNoRedirect,
73
79
  productGroupList,
80
+ modifiersSetList,
74
81
  serverErrors,
75
82
  providerHasMap = false,
76
83
  venueMapSets = [],
@@ -95,7 +102,7 @@ export function ProductSetForm({
95
102
  const [errorMessage, setErrorMessage] = useState('')
96
103
 
97
104
  const form = useForm<ProductSetFormValues>({
98
- defaultValues,
105
+ defaultValues: updateModifiersSetAtProductSetForm(defaultValues),
99
106
  mode: 'onChange',
100
107
  })
101
108
 
@@ -122,7 +129,7 @@ export function ProductSetForm({
122
129
  if (!defaultValues || isEqual(defaultValues, formValues)) {
123
130
  return
124
131
  }
125
- reset(defaultValues)
132
+ reset(updateModifiersSetAtProductSetForm(defaultValues))
126
133
  // eslint-disable-next-line react-hooks/exhaustive-deps
127
134
  }, [defaultValues])
128
135
 
@@ -162,6 +169,7 @@ export function ProductSetForm({
162
169
  <ProductSetContextProvider
163
170
  productGroupList={productGroupList}
164
171
  providerHasMap={providerHasMap}
172
+ modifiersSetList={modifiersSetList}
165
173
  venueMapSets={venueMapSets}
166
174
  providerHasBookingManagement={providerHasBookingManagement}
167
175
  zones={zones}
@@ -49,6 +49,8 @@ const getDefaultProductValue = (sort: number): Product => ({
49
49
  maxQuantity: null,
50
50
  totalQuantity: 0,
51
51
  isAvailable: true,
52
+ modifiersSet: [],
53
+ modifiersSetsId: [],
52
54
  isSoldOut: false,
53
55
  isRequired: false,
54
56
  isUnlimited: false,
@@ -139,6 +141,16 @@ export function ProductsControl({
139
141
  ],
140
142
  })
141
143
 
144
+ const modifierSets = useWatch({
145
+ control,
146
+ name: [
147
+ ...fields.map(
148
+ (_, index) =>
149
+ `${productControlFieldName}.${index}.modifiersSet` as const,
150
+ ),
151
+ ],
152
+ })
153
+
142
154
  const categoryProductErrors =
143
155
  errors?.steps?.[stepIndex]?.productCategories?.[productCategoryIndex]
144
156
  ?.products
@@ -199,6 +211,7 @@ export function ProductsControl({
199
211
  : isOverrides && !!product.originalProductId
200
212
 
201
213
  const isNewProductOverrides = isCreateNewOverrides && !!product.id
214
+ const modifiersSets = modifierSets[index]?.length || 0
202
215
 
203
216
  return (
204
217
  <Controller
@@ -226,21 +239,26 @@ export function ProductsControl({
226
239
  edit={() => edit(index)}
227
240
  secondaryBadge={getBadgeConfig(categoryType, t(categoryType))}
228
241
  subTitle={
229
- <div className='product-set-badges-container'>
230
- <div className='product-set-subtitle-dot product-set-subtitle-product-dot' />
231
- <span>
232
- {`£${prices[index]} ${t('each')} - ${t('qty')}:${
233
- !isUnlimitedQuantities[index]
234
- ? ` ${quantities[index]}`
235
- : t(' unlimited')
236
- } ${
237
- !isUnlimitedQuantities[index]
238
- ? ` - ${t('possibleRevenue')} £${
239
- prices[index] * quantities[index]
240
- }`
241
- : ''
242
- } `}
243
- </span>
242
+ <div className='d-flex justify-content-between'>
243
+ <div className='product-set-badges-container'>
244
+ <div className='product-set-subtitle-dot product-set-subtitle-product-dot' />
245
+ <span>
246
+ {`£${prices[index]} ${t('each')} - ${t('qty')}:${
247
+ !isUnlimitedQuantities[index]
248
+ ? ` ${quantities[index]}`
249
+ : t(' unlimited')
250
+ } ${
251
+ !isUnlimitedQuantities[index]
252
+ ? ` - ${t('possibleRevenue')} £${
253
+ prices[index] * quantities[index]
254
+ }`
255
+ : ''
256
+ } `}
257
+ </span>
258
+ </div>
259
+ {!!modifiersSets && (
260
+ <Badge className='modifier-badge'>{`${modifiersSets} ${t('modifiersSets')}`}</Badge>
261
+ )}
244
262
  </div>
245
263
  }
246
264
  modalLabel={t('addNewProduct')}
@@ -7,15 +7,18 @@ import {
7
7
  Dispatch,
8
8
  } from 'react'
9
9
  import { VenueMapSet } from '@licklist/core/dist/DataMapper/Product/VenueMapSetDataMapper'
10
+ import { ModifierSet } from '@licklist/core/dist/DataMapper/Product/ModifierSetDataMapper'
10
11
  // eslint-disable-next-line max-len
11
12
  import { ProviderBookingManagementSetting } from '@licklist/core/dist/DataMapper/Provider/ProviderBookingManagementSettingDataMapper'
12
13
  import { Zone } from '@licklist/core/dist/DataMapper/Provider/ZoneDataMapper'
13
14
  import { SelectItem } from '../../types/generic/SelectItem'
14
15
 
16
+
15
17
  interface LoadingContext {
16
18
  isLoading: boolean
17
19
  setLoading: (loading: boolean) => void
18
20
  productGroupList?: SelectItem[]
21
+ modifiersSetList?: ModifierSet[] | null
19
22
  providerHasMap?: boolean | null
20
23
  venueMapSets?: VenueMapSet[]
21
24
  providerHasBookingManagement?: ProviderBookingManagementSetting['hasBookingManagement']
@@ -43,6 +46,7 @@ type ProductSetContextProviderProps = PropsWithChildren<
43
46
  export function ProductSetContextProvider({
44
47
  children,
45
48
  productGroupList = [],
49
+ modifiersSetList =[],
46
50
  providerHasMap = false,
47
51
  venueMapSets = [],
48
52
  providerHasBookingManagement,
@@ -62,6 +66,7 @@ export function ProductSetContextProvider({
62
66
  isLoading: loading,
63
67
  setLoading,
64
68
  productGroupList,
69
+ modifiersSetList,
65
70
  providerHasMap,
66
71
  venueMapSets,
67
72
  providerHasBookingManagement,