@licklist/design 0.71.18-dev.1 → 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 (125) 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 +1 -1
  68. package/dist/report/ReportRunnerModal/ReportRunnerModal.d.ts.map +1 -1
  69. package/dist/sales/coupon/utils/index.d.ts +2 -1
  70. package/dist/sales/coupon/utils/index.d.ts.map +1 -1
  71. package/dist/sales/modals/refund-modal/RefundModal.d.ts +6 -2
  72. package/dist/sales/modals/refund-modal/RefundModal.d.ts.map +1 -1
  73. package/dist/sales/modals/refund-modal/RefundModal.js +8 -4
  74. package/dist/sales/modals/refund-modal/index.d.ts +2 -2
  75. package/dist/sales/modals/refund-modal/index.d.ts.map +1 -1
  76. package/dist/styles/date-time-button/DateTimeButton.scss +8 -1
  77. package/dist/styles/events/EditEventModal.scss +2 -0
  78. package/dist/styles/iframe-page/Page.scss +16 -0
  79. package/dist/styles/iframe-page/PageBody.scss +4 -0
  80. package/dist/styles/modals/Modals.scss +16 -0
  81. package/dist/styles/product-set/EditProductSetElement.scss +1 -0
  82. package/dist/styles/product-set/ProductSetForm.scss +11 -0
  83. package/dist/styles/sales/ManualBooking.scss +6 -0
  84. package/dist/styles/themes/bookedit/index.scss +19 -0
  85. package/package.json +6 -6
  86. package/src/events/event-statistic-modal/utils/index.ts +4 -4
  87. package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetForm.tsx +212 -0
  88. package/src/iframe/ProductWithModifierModal/ModifierSetModal/ProductWithModifierSetModal.tsx +75 -0
  89. package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ModifierSetControll.tsx +393 -0
  90. package/src/iframe/ProductWithModifierModal/ModifierSetModal/controll/ProductControll.tsx +98 -0
  91. package/src/iframe/ProductWithModifierModal/ModifierSetModal/index.ts +1 -0
  92. package/src/iframe/ProductWithModifierModal/index.ts +1 -0
  93. package/src/iframe/ProductWithModifierModal/utils.ts +29 -0
  94. package/src/iframe/activity-card/ActivityCard.stories.tsx +0 -2
  95. package/src/iframe/activity-card/ActivityCard.tsx +0 -4
  96. package/src/iframe/event/ticket-description/TicketDescription.tsx +5 -3
  97. package/src/iframe/order-process/components/BookingSummary/components/ProductSummary/ProductSummary.tsx +21 -1
  98. package/src/iframe/order-process/components/BookingSummary/utils/index.ts +42 -1
  99. package/src/iframe/order-process/components/CategoryProduct/CategoryProduct.tsx +155 -75
  100. package/src/iframe/order-process/components/CategoryProduct/components/ProductQuantityInput/ProductQuantityInput.tsx +58 -1
  101. package/src/iframe/order-process/components/CategoryProduct/components/ProductWithModifier/ProductWithModifier.tsx +86 -0
  102. package/src/iframe/order-process/components/CategoryProduct/constants.ts +1 -0
  103. package/src/iframe/order-process/components/utils/useOnWindowUnmount.ts +25 -0
  104. package/src/iframe/payment/order-items-table/hooks/useTableData.tsx +84 -14
  105. package/src/iframe/payment/order-items-table/utils/index.ts +23 -0
  106. package/src/iframe/payment/order-items-table/utils/paymentSummary.tsx +2 -2
  107. package/src/product-set/form/ProductSetForm.tsx +11 -3
  108. package/src/product-set/form/ProductsControl.tsx +33 -15
  109. package/src/product-set/form/context.tsx +5 -0
  110. package/src/product-set/product/ProductControl.tsx +37 -1
  111. package/src/product-set/utils/index.ts +19 -0
  112. package/src/report/ReportRunnerModal/ReportRunnerModal.tsx +2 -2
  113. package/src/sales/coupon/utils/index.ts +5 -3
  114. package/src/sales/modals/refund-modal/RefundModal.tsx +15 -6
  115. package/src/sales/modals/refund-modal/index.ts +7 -2
  116. package/src/styles/date-time-button/DateTimeButton.scss +8 -1
  117. package/src/styles/events/EditEventModal.scss +2 -0
  118. package/src/styles/iframe-page/Page.scss +16 -0
  119. package/src/styles/iframe-page/PageBody.scss +4 -0
  120. package/src/styles/modals/Modals.scss +16 -0
  121. package/src/styles/product-set/EditProductSetElement.scss +1 -0
  122. package/src/styles/product-set/ProductSetForm.scss +11 -0
  123. package/src/styles/sales/ManualBooking.scss +6 -0
  124. package/src/styles/themes/bookedit/index.scss +19 -0
  125. package/yarn.lock +334 -333
@@ -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
 
@@ -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,
@@ -39,6 +39,8 @@ import {
39
39
  IMAGE_TYPE_IMAGE,
40
40
  } from '@licklist/core/dist/DataMapper/Media/ImageDataMapper'
41
41
  import { FaClipboard } from 'react-icons/fa'
42
+ import { Typeahead } from 'src/typeahead'
43
+ import { convertToTypeaheadOptions } from 'src/sales/coupon/utils'
42
44
  import { checkIfZoneCategory } from '@licklist/plugins'
43
45
  import { FileUpload } from '../../file-upload'
44
46
  import { BooleanSwitch } from '../../static'
@@ -65,6 +67,14 @@ import { ProductZoneControlValues } from '../product-zone'
65
67
  import { AdvancedOptions } from './advanced-options'
66
68
  import { ProductZonesControl } from '../form/ProductZonesControl'
67
69
 
70
+
71
+ export interface ModifiersSet {
72
+ id: number
73
+ value?: string
74
+ name?: string
75
+ label?: string
76
+ }
77
+
68
78
  // TO DO refactor this file
69
79
  // and add correct types
70
80
  export interface ProductControlValues
@@ -88,6 +98,8 @@ export interface ProductControlValues
88
98
  hasSpecialNotes: boolean
89
99
  minSpend?: number | null
90
100
  type?: ProductType
101
+ modifiersSetsId?: Array<ModifiersSet>
102
+ modifiersSet?: Array<ModifiersSet>
91
103
  weight?: number
92
104
  tierId?: number
93
105
  images: Image[] | null
@@ -111,6 +123,7 @@ export interface ProductControlProps<T>
111
123
  hasTicket?: boolean
112
124
  categoryType?: CategoryType
113
125
  isOverrides?: boolean
126
+
114
127
  }
115
128
 
116
129
  export function ProductControl<T extends FormValues>({
@@ -126,6 +139,7 @@ export function ProductControl<T extends FormValues>({
126
139
  categoryType,
127
140
  isOverrides = false,
128
141
  }: ProductControlProps<T>) {
142
+
129
143
  const {
130
144
  register,
131
145
  control,
@@ -135,14 +149,16 @@ export function ProductControl<T extends FormValues>({
135
149
  watch,
136
150
  } = useFormContext<T>()
137
151
 
138
- const { setLoading } = useContext(ProductSetLoadingContext)
152
+ const { setLoading, modifiersSetList } = useContext(ProductSetLoadingContext)
139
153
  const { t } = useTranslation(['Design', 'Validation', 'ProductSet'])
140
154
  const [expanded, setExpanded] = useState(false)
155
+
141
156
  const [initialImages, setInitialImages] = useState<Image[] | null>(null)
142
157
  // @TODO: After checking "isUnlimited" checkbox need to reset field totalQuantity
143
158
  const isUnlimited = Boolean(
144
159
  watch(`${fieldNamePrefix}.isUnlimited` as Path<T>),
145
160
  )
161
+
146
162
  const advancedId = useId()
147
163
  const nameId = useId()
148
164
 
@@ -200,6 +216,7 @@ export function ProductControl<T extends FormValues>({
200
216
  setInitialImages(formImages as Image[])
201
217
  }, [getValues, setInitialImages, fieldNamePrefix])
202
218
 
219
+
203
220
  useEffect(() => {
204
221
  if (Array.isArray(images)) {
205
222
  setValue(
@@ -212,6 +229,9 @@ export function ProductControl<T extends FormValues>({
212
229
 
213
230
  const quantitySelector = quantityValue ?? '1'
214
231
  const quantity = QUANTITY_TYPE_LIST_DTO[quantitySelector as string]
232
+
233
+ const modifierList = convertToTypeaheadOptions(modifiersSetList)
234
+
215
235
  return (
216
236
  <>
217
237
  <Row>
@@ -354,6 +374,22 @@ export function ProductControl<T extends FormValues>({
354
374
  </Form.Group>
355
375
  </Col>
356
376
  </Row>
377
+ <Row>
378
+ <Col>
379
+ <Form.Group className='mb-3'>
380
+ <Form.Label>{t('Design:addModifierSet')}</Form.Label>
381
+ <Typeahead
382
+ name='modifierList'
383
+ options={modifierList}
384
+ {...register(`${fieldNamePrefix}.modifiersSet` as Path<T>)}
385
+ isMultipleChoise
386
+ isCouponForm
387
+ placeholder={t('Design:choose')}
388
+ noOptionsMessage={t('Design:noSelectedModifier')}
389
+ />
390
+ </Form.Group>
391
+ </Col>
392
+ </Row>
357
393
 
358
394
  <Row className='my-4 mx-0 d-flex flex-column'>
359
395
  {isZoneCategory && (
@@ -1,5 +1,7 @@
1
1
  import { EmailTemplate } from '@licklist/core/dist/DataMapper/Notification/EmailTemplateDataMapper'
2
2
  import { SmsTemplate } from '@licklist/core/dist/DataMapper/Notification/SmsTemplateDataMapper'
3
+ import { ModifierSet } from '@licklist/core/dist/DataMapper/Product/ModifierSetDataMapper'
4
+ import { convertToTypeaheadOptions } from 'src/sales/coupon/utils'
3
5
  import { TFunction } from 'react-i18next'
4
6
  import { UseFormSetError } from 'react-hook-form'
5
7
  import { checkIfZoneCategory } from '@licklist/plugins'
@@ -7,6 +9,7 @@ import { ProductSet } from '@licklist/core/dist/DataMapper/Product/ProductSetDat
7
9
  import { TemplateItem } from '../control/ProductSetControl'
8
10
  import { ProductSetFormValues } from '../form/ProductSetForm'
9
11
 
12
+
10
13
  interface CheckAvailableTimesErrors {
11
14
  values: ProductSetFormValues
12
15
  setError: UseFormSetError<ProductSetFormValues>
@@ -58,6 +61,22 @@ export const getFilteredTemplates = (
58
61
  }))
59
62
  }
60
63
 
64
+ export const updateModifiersSetAtProductSetForm = (data: ProductSetFormValues) => ({
65
+ ...data,
66
+ steps: data.steps.map(step => ({
67
+ ...step,
68
+ productCategories: step.productCategories.map(category => ({
69
+ ...category,
70
+ products: category.products.map(product => ({
71
+ ...product,
72
+ modifiersSet: product?.modifiersSet
73
+ ? convertToTypeaheadOptions(product.modifiersSet as ModifierSet[])
74
+ : [],
75
+ })),
76
+ })),
77
+ })),
78
+ });
79
+
61
80
  export const checkAvailableTimesErrors = ({
62
81
  values,
63
82
  setError,
@@ -52,13 +52,13 @@ export const ReportRunnerModal = ({
52
52
  generate,
53
53
  download,
54
54
  onEdit,
55
- providerId
55
+ providerId,
56
56
  }: ReportRunnerModalProps) => {
57
57
  const { t } = useTranslation(['App', 'Design'])
58
58
  const report = reports?.find((report) => report.id === reportId)
59
59
 
60
60
  const { data: reportFields = [], isLoading: isLoadingReportFields } =
61
- useShowReportFields(report?.type, )
61
+ useShowReportFields(report?.type)
62
62
 
63
63
  const {
64
64
  handleSubmit,
@@ -1,13 +1,15 @@
1
+
2
+ import { ModifierSet } from '@licklist/core/dist/DataMapper/Product/ModifierSetDataMapper'
1
3
  import { ProductGroup } from '@licklist/core/dist/DataMapper/Product/ProductGroupDataMapper'
2
4
 
3
- export const convertToTypeaheadOptions = (productGroups?: ProductGroup[]) => {
5
+ export const convertToTypeaheadOptions = (productGroups?: ProductGroup[] | ModifierSet[]) => {
4
6
  if (!productGroups || !productGroups.length) {
5
7
  return []
6
8
  }
7
9
 
8
- return productGroups.map(({ id, name }: ProductGroup) => ({
10
+ return productGroups.map(({ id, name }: ProductGroup | ModifierSet ) => ({
9
11
  id: Number(id),
10
12
  value: name,
11
- label: name,
13
+ label: name ,
12
14
  }))
13
15
  }
@@ -9,9 +9,18 @@ import { FaTimes } from 'react-icons/fa'
9
9
  import { EXTENDED_PAYMENT_TYPE_TRANSLATION_KEYS } from '../../constants'
10
10
  import { CurrencyNumberInput } from '../../../static/CurrencyNumberInput'
11
11
 
12
+ export const FULL_REFUND_TYPE = 'fullRefund'
13
+ export const PARTIAL_REFUND_TYPE = 'partialRefund'
14
+ export const NET_REFUND_TYPE = 'netRefund'
15
+
16
+ export type RefundType =
17
+ | typeof FULL_REFUND_TYPE
18
+ | typeof PARTIAL_REFUND_TYPE
19
+ | typeof NET_REFUND_TYPE
20
+
12
21
  export interface RefundModalProps {
13
22
  isVisible: boolean
14
- isFullRefund?: boolean
23
+ refundType?: RefundType
15
24
  onHide: () => void
16
25
  onSubmit: (amount?: number) => void
17
26
  isLoading?: boolean
@@ -29,12 +38,14 @@ export const RefundModal = ({
29
38
  onHide,
30
39
  onSubmit,
31
40
  isLoading = false,
32
- isFullRefund = false,
41
+ refundType = PARTIAL_REFUND_TYPE,
33
42
  paymentType,
34
43
  defaultValue = 0,
35
44
  maxValue,
36
45
  }: RefundModalProps) => {
37
46
  const { t } = useTranslation(['Design', 'Validation'])
47
+ const isInputDisabled =
48
+ isLoading || refundType === 'fullRefund' || refundType === 'netRefund'
38
49
 
39
50
  const {
40
51
  handleSubmit,
@@ -64,9 +75,7 @@ export const RefundModal = ({
64
75
  >
65
76
  <Form onSubmit={handleSubmit(onModalSubmit)}>
66
77
  <ModalHeader className='align-items-center border-0'>
67
- <ModalTitle as='h5'>
68
- {t(isFullRefund ? 'Design:fullRefund' : 'Design:partialRefund')}
69
- </ModalTitle>
78
+ <ModalTitle as='h5'>{t(`Design:${refundType}`)}</ModalTitle>
70
79
 
71
80
  <Button variant='danger' className='btn-sm rounded' onClick={onHide}>
72
81
  <FaTimes size={20} />
@@ -111,7 +120,7 @@ export const RefundModal = ({
111
120
  },
112
121
  })}
113
122
  step={0.01}
114
- disabled={isLoading || isFullRefund}
123
+ disabled={isInputDisabled}
115
124
  isInvalid={!!errors.amount}
116
125
  min={0}
117
126
  />
@@ -1,2 +1,7 @@
1
- export { RefundModal } from './RefundModal'
2
- export type { RefundModalProps } from './RefundModal'
1
+ export {
2
+ RefundModal,
3
+ FULL_REFUND_TYPE,
4
+ NET_REFUND_TYPE,
5
+ PARTIAL_REFUND_TYPE,
6
+ } from './RefundModal'
7
+ export type { RefundModalProps, RefundType } from './RefundModal'
@@ -33,7 +33,7 @@
33
33
 
34
34
  &.disabled {
35
35
  border: 2px solid $snippet-calendar-disabled-button-border-color;
36
- background-color:transparent;
36
+ background-color: transparent;
37
37
  border: none;
38
38
  color: $snippet-calendar-disabled-button-font-color;
39
39
  cursor: not-allowed;
@@ -105,3 +105,10 @@
105
105
  font-weight: 300;
106
106
  color: $snippet-calendar-button-font-color;
107
107
  }
108
+
109
+ .modifier-price {
110
+ font-size: 1rem;
111
+ line-height: 1.03rem;
112
+ font-weight: 500;
113
+ color: $snippet-calendar-button-font-color;
114
+ }
@@ -37,6 +37,8 @@
37
37
  .edit-step-dialog {
38
38
  .custom-checkbox {
39
39
  align-items: unset;
40
+ position: relative;
41
+ z-index: 0;
40
42
  .form-check-label {
41
43
  margin-top: 1rem;
42
44
  }