@eventlook/sdk 1.4.48 → 1.4.49-beta.2

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 (238) hide show
  1. package/.env.example +1 -0
  2. package/dist/cjs/_virtual/_commonjsHelpers.js +8 -0
  3. package/dist/cjs/_virtual/_commonjsHelpers.js.map +1 -0
  4. package/dist/cjs/_virtual/index.js +6 -0
  5. package/dist/cjs/_virtual/index.js.map +1 -0
  6. package/dist/cjs/_virtual/index2.js +6 -0
  7. package/dist/cjs/_virtual/index2.js.map +1 -0
  8. package/dist/cjs/_virtual/index3.js +6 -0
  9. package/dist/cjs/_virtual/index3.js.map +1 -0
  10. package/dist/cjs/_virtual/react-is.development.js +6 -0
  11. package/dist/cjs/_virtual/react-is.development.js.map +1 -0
  12. package/dist/cjs/_virtual/react-is.development2.js +6 -0
  13. package/dist/cjs/_virtual/react-is.development2.js.map +1 -0
  14. package/dist/cjs/_virtual/react-is.production.js +6 -0
  15. package/dist/cjs/_virtual/react-is.production.js.map +1 -0
  16. package/dist/cjs/_virtual/react-is.production.min.js +6 -0
  17. package/dist/cjs/_virtual/react-is.production.min.js.map +1 -0
  18. package/dist/cjs/components/hook-form/FormProvider.js +2 -2
  19. package/dist/cjs/components/hook-form/FormProvider.js.map +1 -1
  20. package/dist/cjs/form/ChildEventDialog.js +3 -3
  21. package/dist/cjs/form/ChildEventDialog.js.map +1 -1
  22. package/dist/cjs/form/ContactPerson.js +1 -1
  23. package/dist/cjs/form/ContactPerson.js.map +1 -1
  24. package/dist/cjs/form/PaymentOverviewBox.js +47 -61
  25. package/dist/cjs/form/PaymentOverviewBox.js.map +1 -1
  26. package/dist/cjs/form/PaymentOverviewDrawer.js +157 -0
  27. package/dist/cjs/form/PaymentOverviewDrawer.js.map +1 -0
  28. package/dist/cjs/form/PaymentPending.js +15 -3
  29. package/dist/cjs/form/PaymentPending.js.map +1 -1
  30. package/dist/cjs/form/ReleaseWithMerchandise.js +57 -48
  31. package/dist/cjs/form/ReleaseWithMerchandise.js.map +1 -1
  32. package/dist/cjs/form/Shipping.js +21 -18
  33. package/dist/cjs/form/Shipping.js.map +1 -1
  34. package/dist/cjs/form/TicketForm.js +94 -33
  35. package/dist/cjs/form/TicketForm.js.map +1 -1
  36. package/dist/cjs/form/TicketQuantityControl.js +51 -0
  37. package/dist/cjs/form/TicketQuantityControl.js.map +1 -0
  38. package/dist/cjs/form/TicketSelection.js +5 -6
  39. package/dist/cjs/form/TicketSelection.js.map +1 -1
  40. package/dist/cjs/form/TicketSelectionMobile.js +98 -0
  41. package/dist/cjs/form/TicketSelectionMobile.js.map +1 -0
  42. package/dist/cjs/form/TicketWithMerchandiseSelection.js +3 -5
  43. package/dist/cjs/form/TicketWithMerchandiseSelection.js.map +1 -1
  44. package/dist/cjs/form/index.js +1 -1
  45. package/dist/cjs/form/index.js.map +1 -1
  46. package/dist/cjs/form/merchandise/MerchandiseSelection.js +14 -0
  47. package/dist/cjs/form/merchandise/MerchandiseSelection.js.map +1 -0
  48. package/dist/cjs/form/merchandise/MerchandiseSlider.js +40 -0
  49. package/dist/cjs/form/merchandise/MerchandiseSlider.js.map +1 -0
  50. package/dist/cjs/form/merchendise/MerchandiseSelection.js +19 -0
  51. package/dist/cjs/form/merchendise/MerchandiseSelection.js.map +1 -0
  52. package/dist/cjs/form/merchendise/MerchandiseSlider.js +75 -0
  53. package/dist/cjs/form/merchendise/MerchandiseSlider.js.map +1 -0
  54. package/dist/cjs/form/payment/FeeBox.js +4 -16
  55. package/dist/cjs/form/payment/FeeBox.js.map +1 -1
  56. package/dist/cjs/form/payment/PaymentOverviewCheckbox.js +33 -28
  57. package/dist/cjs/form/payment/PaymentOverviewCheckbox.js.map +1 -1
  58. package/dist/cjs/form/product/ProductCard.js +139 -36
  59. package/dist/cjs/form/product/ProductCard.js.map +1 -1
  60. package/dist/cjs/form/product/ProductVariantsDialog.js +157 -96
  61. package/dist/cjs/form/product/ProductVariantsDialog.js.map +1 -1
  62. package/dist/cjs/form/services/index.js +133 -0
  63. package/dist/cjs/form/services/index.js.map +1 -0
  64. package/dist/cjs/form/style.js +7 -3
  65. package/dist/cjs/form/style.js.map +1 -1
  66. package/dist/cjs/form/tickets/ReleaseDescription.js +23 -0
  67. package/dist/cjs/form/tickets/ReleaseDescription.js.map +1 -0
  68. package/dist/cjs/form/tickets/ReleaseWithMerchandise.js +141 -0
  69. package/dist/cjs/form/tickets/ReleaseWithMerchandise.js.map +1 -0
  70. package/dist/cjs/form/tickets/TicketQuantityControl.js +52 -0
  71. package/dist/cjs/form/tickets/TicketQuantityControl.js.map +1 -0
  72. package/dist/cjs/form/tickets/TicketSelection.js +139 -0
  73. package/dist/cjs/form/tickets/TicketSelection.js.map +1 -0
  74. package/dist/cjs/form/tickets/TicketSelectionMap.js +73 -0
  75. package/dist/cjs/form/tickets/TicketSelectionMap.js.map +1 -0
  76. package/dist/cjs/form/tickets/TicketSelectionMobile.js +90 -0
  77. package/dist/cjs/form/tickets/TicketSelectionMobile.js.map +1 -0
  78. package/dist/cjs/form/tickets/TicketWithMerchandiseSelection.js +117 -0
  79. package/dist/cjs/form/tickets/TicketWithMerchandiseSelection.js.map +1 -0
  80. package/dist/cjs/hooks/useConsentScrollOnDrawerOpen.js +59 -0
  81. package/dist/cjs/hooks/useConsentScrollOnDrawerOpen.js.map +1 -0
  82. package/dist/cjs/hooks/useScrollToFirstError.js +64 -0
  83. package/dist/cjs/hooks/useScrollToFirstError.js.map +1 -0
  84. package/dist/cjs/locales/cs.js +18 -3
  85. package/dist/cjs/locales/cs.js.map +1 -1
  86. package/dist/cjs/locales/en.js +17 -2
  87. package/dist/cjs/locales/en.js.map +1 -1
  88. package/dist/cjs/locales/es.js +16 -1
  89. package/dist/cjs/locales/es.js.map +1 -1
  90. package/dist/cjs/locales/pl.js +16 -1
  91. package/dist/cjs/locales/pl.js.map +1 -1
  92. package/dist/cjs/locales/sk.js +17 -2
  93. package/dist/cjs/locales/sk.js.map +1 -1
  94. package/dist/cjs/locales/uk.js +16 -1
  95. package/dist/cjs/locales/uk.js.map +1 -1
  96. package/dist/cjs/utils/data/global.js +2 -0
  97. package/dist/cjs/utils/data/global.js.map +1 -1
  98. package/dist/esm/_virtual/_commonjsHelpers.js +6 -0
  99. package/dist/esm/_virtual/_commonjsHelpers.js.map +1 -0
  100. package/dist/esm/_virtual/index.js +4 -0
  101. package/dist/esm/_virtual/index.js.map +1 -0
  102. package/dist/esm/_virtual/index2.js +4 -0
  103. package/dist/esm/_virtual/index2.js.map +1 -0
  104. package/dist/esm/_virtual/index3.js +4 -0
  105. package/dist/esm/_virtual/index3.js.map +1 -0
  106. package/dist/esm/_virtual/react-is.development.js +4 -0
  107. package/dist/esm/_virtual/react-is.development.js.map +1 -0
  108. package/dist/esm/_virtual/react-is.development2.js +4 -0
  109. package/dist/esm/_virtual/react-is.development2.js.map +1 -0
  110. package/dist/esm/_virtual/react-is.production.js +4 -0
  111. package/dist/esm/_virtual/react-is.production.js.map +1 -0
  112. package/dist/esm/_virtual/react-is.production.min.js +4 -0
  113. package/dist/esm/_virtual/react-is.production.min.js.map +1 -0
  114. package/dist/esm/components/hook-form/FormProvider.js +2 -2
  115. package/dist/esm/components/hook-form/FormProvider.js.map +1 -1
  116. package/dist/esm/form/ChildEventDialog.js +3 -3
  117. package/dist/esm/form/ChildEventDialog.js.map +1 -1
  118. package/dist/esm/form/ContactPerson.js +1 -1
  119. package/dist/esm/form/ContactPerson.js.map +1 -1
  120. package/dist/esm/form/PaymentOverviewBox.js +48 -62
  121. package/dist/esm/form/PaymentOverviewBox.js.map +1 -1
  122. package/dist/esm/form/PaymentOverviewDrawer.js +153 -0
  123. package/dist/esm/form/PaymentOverviewDrawer.js.map +1 -0
  124. package/dist/esm/form/PaymentPending.js +16 -4
  125. package/dist/esm/form/PaymentPending.js.map +1 -1
  126. package/dist/esm/form/ReleaseWithMerchandise.js +58 -49
  127. package/dist/esm/form/ReleaseWithMerchandise.js.map +1 -1
  128. package/dist/esm/form/Shipping.js +21 -18
  129. package/dist/esm/form/Shipping.js.map +1 -1
  130. package/dist/esm/form/TicketForm.js +96 -35
  131. package/dist/esm/form/TicketForm.js.map +1 -1
  132. package/dist/esm/form/TicketQuantityControl.js +47 -0
  133. package/dist/esm/form/TicketQuantityControl.js.map +1 -0
  134. package/dist/esm/form/TicketSelection.js +5 -6
  135. package/dist/esm/form/TicketSelection.js.map +1 -1
  136. package/dist/esm/form/TicketSelectionMobile.js +94 -0
  137. package/dist/esm/form/TicketSelectionMobile.js.map +1 -0
  138. package/dist/esm/form/TicketWithMerchandiseSelection.js +4 -6
  139. package/dist/esm/form/TicketWithMerchandiseSelection.js.map +1 -1
  140. package/dist/esm/form/index.js +1 -1
  141. package/dist/esm/form/index.js.map +1 -1
  142. package/dist/esm/form/merchandise/MerchandiseSelection.js +10 -0
  143. package/dist/esm/form/merchandise/MerchandiseSelection.js.map +1 -0
  144. package/dist/esm/form/merchandise/MerchandiseSlider.js +36 -0
  145. package/dist/esm/form/merchandise/MerchandiseSlider.js.map +1 -0
  146. package/dist/esm/form/merchendise/MerchandiseSelection.js +15 -0
  147. package/dist/esm/form/merchendise/MerchandiseSelection.js.map +1 -0
  148. package/dist/esm/form/merchendise/MerchandiseSlider.js +71 -0
  149. package/dist/esm/form/merchendise/MerchandiseSlider.js.map +1 -0
  150. package/dist/esm/form/payment/FeeBox.js +5 -17
  151. package/dist/esm/form/payment/FeeBox.js.map +1 -1
  152. package/dist/esm/form/payment/PaymentOverviewCheckbox.js +35 -30
  153. package/dist/esm/form/payment/PaymentOverviewCheckbox.js.map +1 -1
  154. package/dist/esm/form/product/ProductCard.js +140 -37
  155. package/dist/esm/form/product/ProductCard.js.map +1 -1
  156. package/dist/esm/form/product/ProductVariantsDialog.js +159 -98
  157. package/dist/esm/form/product/ProductVariantsDialog.js.map +1 -1
  158. package/dist/esm/form/services/index.js +129 -0
  159. package/dist/esm/form/services/index.js.map +1 -0
  160. package/dist/esm/form/style.js +7 -3
  161. package/dist/esm/form/style.js.map +1 -1
  162. package/dist/esm/form/tickets/ReleaseDescription.js +19 -0
  163. package/dist/esm/form/tickets/ReleaseDescription.js.map +1 -0
  164. package/dist/esm/form/tickets/ReleaseWithMerchandise.js +137 -0
  165. package/dist/esm/form/tickets/ReleaseWithMerchandise.js.map +1 -0
  166. package/dist/esm/form/tickets/TicketQuantityControl.js +48 -0
  167. package/dist/esm/form/tickets/TicketQuantityControl.js.map +1 -0
  168. package/dist/esm/form/tickets/TicketSelection.js +135 -0
  169. package/dist/esm/form/tickets/TicketSelection.js.map +1 -0
  170. package/dist/esm/form/tickets/TicketSelectionMap.js +69 -0
  171. package/dist/esm/form/tickets/TicketSelectionMap.js.map +1 -0
  172. package/dist/esm/form/tickets/TicketSelectionMobile.js +86 -0
  173. package/dist/esm/form/tickets/TicketSelectionMobile.js.map +1 -0
  174. package/dist/esm/form/tickets/TicketWithMerchandiseSelection.js +113 -0
  175. package/dist/esm/form/tickets/TicketWithMerchandiseSelection.js.map +1 -0
  176. package/dist/esm/hooks/useConsentScrollOnDrawerOpen.js +55 -0
  177. package/dist/esm/hooks/useConsentScrollOnDrawerOpen.js.map +1 -0
  178. package/dist/esm/hooks/useScrollToFirstError.js +60 -0
  179. package/dist/esm/hooks/useScrollToFirstError.js.map +1 -0
  180. package/dist/esm/locales/cs.js +18 -3
  181. package/dist/esm/locales/cs.js.map +1 -1
  182. package/dist/esm/locales/en.js +17 -2
  183. package/dist/esm/locales/en.js.map +1 -1
  184. package/dist/esm/locales/es.js +16 -1
  185. package/dist/esm/locales/es.js.map +1 -1
  186. package/dist/esm/locales/pl.js +16 -1
  187. package/dist/esm/locales/pl.js.map +1 -1
  188. package/dist/esm/locales/sk.js +17 -2
  189. package/dist/esm/locales/sk.js.map +1 -1
  190. package/dist/esm/locales/uk.js +16 -1
  191. package/dist/esm/locales/uk.js.map +1 -1
  192. package/dist/esm/utils/data/global.js +2 -1
  193. package/dist/esm/utils/data/global.js.map +1 -1
  194. package/dist/types/components/Image.d.ts +4 -4
  195. package/dist/types/form/PaymentOverviewDrawer.d.ts +8 -0
  196. package/dist/types/form/merchendise/MerchandiseSelection.d.ts +9 -0
  197. package/dist/types/form/merchendise/MerchandiseSlider.d.ts +10 -0
  198. package/dist/types/form/merchendise/MerchendiseSlider.d.ts +0 -0
  199. package/dist/types/form/style.d.ts +1 -1
  200. package/package.json +5 -1
  201. package/rollup.config.mjs +2 -0
  202. package/src/components/hook-form/FormProvider.tsx +5 -2
  203. package/src/form/ChildEventDialog.tsx +3 -3
  204. package/src/form/ContactPerson.tsx +1 -1
  205. package/src/form/PaymentOverviewBox.tsx +89 -122
  206. package/src/form/PaymentOverviewDrawer.tsx +238 -0
  207. package/src/form/PaymentPending.tsx +19 -3
  208. package/src/form/Shipping.tsx +29 -17
  209. package/src/form/TicketForm.tsx +140 -39
  210. package/src/form/index.tsx +3 -1
  211. package/src/form/merchandise/MerchandiseSelection.tsx +24 -0
  212. package/src/form/merchandise/MerchandiseSlider.tsx +62 -0
  213. package/src/form/payment/FeeBox.tsx +4 -31
  214. package/src/form/payment/PaymentOverviewCheckbox.tsx +57 -56
  215. package/src/form/product/ProductCard.tsx +250 -59
  216. package/src/form/product/ProductVariantsDialog.tsx +253 -140
  217. package/src/form/services/index.tsx +263 -0
  218. package/src/form/style.ts +9 -3
  219. package/src/form/tickets/ReleaseDescription.tsx +46 -0
  220. package/src/form/tickets/ReleaseWithMerchandise.tsx +239 -0
  221. package/src/form/tickets/TicketQuantityControl.tsx +94 -0
  222. package/src/form/{TicketSelection.tsx → tickets/TicketSelection.tsx} +24 -128
  223. package/src/form/{TicketSelectionMap.tsx → tickets/TicketSelectionMap.tsx} +9 -1
  224. package/src/form/tickets/TicketSelectionMobile.tsx +177 -0
  225. package/src/form/{TicketWithMerchandiseSelection.tsx → tickets/TicketWithMerchandiseSelection.tsx} +3 -7
  226. package/src/hooks/useConsentScrollOnDrawerOpen.ts +73 -0
  227. package/src/hooks/useScrollToFirstError.ts +94 -0
  228. package/src/locales/cs.tsx +18 -3
  229. package/src/locales/en.tsx +17 -2
  230. package/src/locales/es.tsx +16 -1
  231. package/src/locales/pl.tsx +16 -1
  232. package/src/locales/sk.tsx +17 -2
  233. package/src/locales/uk.tsx +16 -1
  234. package/src/utils/data/global.ts +1 -0
  235. package/tsconfig.json +2 -1
  236. package/.claude/settings.local.json +0 -9
  237. package/src/form/MerchandiseSelection.tsx +0 -29
  238. package/src/form/ReleaseWithMerchandise.tsx +0 -230
@@ -1,36 +1,23 @@
1
1
  import React, { useEffect, useRef, useState } from 'react';
2
2
  import { useFormContext, useWatch } from 'react-hook-form';
3
- import {
4
- Box,
5
- Button,
6
- Divider,
7
- Grid,
8
- IconButton,
9
- MenuItem,
10
- Skeleton,
11
- Stack,
12
- Typography,
13
- } from '@mui/material';
14
- import { RHFSelect } from '@components/hook-form';
3
+ import { Box, Divider, Stack, Typography } from '@mui/material';
15
4
  import { ITicketForm, ITicketFormTicket } from '@utils/types/ticket.type';
16
5
  import useEventActiveReleases from '@hooks/data/useEventActiveReleases';
17
- import { fCurrency } from '@utils/formatNumber';
18
- import { Iconify } from '@components/iconify';
19
6
  import { groupBy } from '@utils/global';
20
7
  import { IReleaseShort } from '@utils/types/release.type';
21
- import FeeBox from '@form/payment/FeeBox';
22
8
  import { IEvent } from '@utils/types/event.type';
23
9
  import useResponsive from '@hooks/useResponsive';
24
10
  import ReleaseExtraFields from '@form/extra-field/ReleaseExtraFields';
25
11
  import { EventType } from '@utils/data/event';
26
12
  import useGlobal from '@hooks/useGlobal.ts';
13
+ import TicketSelectionMobile from './TicketSelectionMobile';
27
14
 
28
15
  interface Props {
29
16
  event: IEvent;
30
17
  }
31
18
 
32
19
  const TicketSelection: React.FC<Props> = ({ event }) => {
33
- const { t, lang } = useGlobal();
20
+ const { t } = useGlobal();
34
21
  const isMobile = useResponsive('down', 'md');
35
22
  const { setValue, watch } = useFormContext<ITicketForm>();
36
23
  const tickets = useWatch({
@@ -78,11 +65,11 @@ const TicketSelection: React.FC<Props> = ({ event }) => {
78
65
  );
79
66
  };
80
67
 
81
- const getAvailableTicketsForRelease = (release: ITicketFormTicket): number => {
82
- const selectedRelease = activeReleases?.find((item) => item.id === release.releaseId);
83
- const availableQuantity = selectedRelease ? selectedRelease.availableTickets : 0;
84
- return availableQuantity > 10 ? 10 : availableQuantity;
85
- };
68
+ // const getAvailableTicketsForRelease = (release: ITicketFormTicket): number => {
69
+ // const selectedRelease = activeReleases?.find((item) => item.id === release.releaseId);
70
+ // const availableQuantity = selectedRelease ? selectedRelease.availableTickets : 0;
71
+ // return availableQuantity > 10 ? 10 : availableQuantity;
72
+ // };
86
73
 
87
74
  const countReleaseCategories = (): number => {
88
75
  const grouped = groupBy(activeReleases || [], 'releaseCategoryName');
@@ -188,117 +175,26 @@ const TicketSelection: React.FC<Props> = ({ event }) => {
188
175
  };
189
176
 
190
177
  return (
191
- <Stack spacing={3} direction="column" divider={<Divider sx={{ borderStyle: 'dashed' }} />}>
192
- {tickets.map((item, index) => (
193
- <Box key={index}>
194
- <Grid container spacing={3}>
195
- <Grid item xs={12} md={6}>
196
- {showLoading ? (
197
- <Skeleton
198
- variant="rounded"
199
- sx={{
200
- width: '100%',
201
- height: (theme) => theme.spacing(7.5),
202
- }}
203
- />
204
- ) : (
205
- <RHFSelect
206
- name={`tickets.${event.id}.${index}.releaseId`}
207
- value={item.releaseId}
208
- label={
209
- index > 0
210
- ? t('form.labels.add_another_release')
211
- : t('form.labels.release_category_price')
212
- }
213
- maxHeight="calc(100vh - 2rem)"
214
- onChange={(e) => {
215
- setValue(`tickets.${event.id}.${index}.releaseId`, Number(e.target.value));
216
- setValue(`tickets.${event.id}.${index}.extraFields`, []);
217
- }}
218
- >
219
- <MenuItem key={0} value="">
220
- {t('choose')}
221
- </MenuItem>
222
- {activeReleases?.map((activeRelease) => (
223
- <MenuItem
224
- key={activeRelease.id}
225
- value={activeRelease.id}
226
- disabled={
227
- isReleaseSelected(activeRelease.id) ||
228
- (activeRelease.locked &&
229
- !soldOutReleaseCategoryNames.includes(activeRelease.releaseCategoryName))
230
- }
231
- >
232
- {activeRelease.releaseCategoryName} - {activeRelease.name}:{' '}
233
- {activeRelease.price === 0
234
- ? t('free')
235
- : fCurrency(activeRelease.price, lang, event.currency)}
236
- </MenuItem>
237
- ))}
238
- </RHFSelect>
239
- )}
240
- </Grid>
241
- <Grid key={index} item xs={12} md={6}>
242
- {showLoading ? (
243
- <Skeleton
244
- variant="rounded"
245
- sx={{
246
- width: '100%',
247
- height: (theme) => theme.spacing(7.5),
248
- }}
249
- />
250
- ) : (
251
- <Stack direction="row" alignItems="center" spacing={1}>
252
- <RHFSelect
253
- name={`tickets.${event.id}.${index}.quantity`}
254
- value={item.quantity}
255
- label={t('form.labels.quantity')}
256
- >
257
- {[...Array(getAvailableTicketsForRelease(item))].map((_, index2) => (
258
- <MenuItem
259
- key={index2}
260
- value={index2 + 1}
261
- disabled={isQuantityDisabled(index2 + 1, item.releaseId)}
262
- >
263
- {index2 + 1}
264
- </MenuItem>
265
- ))}
266
- {!item.releaseId && (
267
- <MenuItem disabled sx={{ textTransform: 'unset!important' }}>
268
- {t('event.tickets.stepper.1.quantity_select')}
269
- </MenuItem>
270
- )}
271
- </RHFSelect>
272
- {item.releaseId && item.quantity && (
273
- <Box>
274
- <IconButton color="primary" onClick={() => removeTicket(index)}>
275
- <Iconify icon="carbon:trash-can" />
276
- </IconButton>
277
- </Box>
278
- )}
279
- </Stack>
280
- )}
281
- </Grid>
282
- </Grid>
283
- {activeReleases && item.releaseId && (
284
- <Typography
285
- variant="caption"
286
- content="div"
287
- mt={2}
288
- mb={getRelease(item.releaseId)?.extraFields?.length ? 2 : 0}
289
- display="block"
290
- >
291
- {getRelease(item.releaseId)?.description ?? ''}
292
- </Typography>
293
- )}
294
- {getExtraFields(item.releaseId, index)}
295
- </Box>
296
- ))}
178
+ <Stack
179
+ spacing={3}
180
+ direction="column"
181
+ divider={!isMobile ? <Divider sx={{ borderStyle: 'dashed' }} /> : undefined}
182
+ >
183
+ <TicketSelectionMobile
184
+ event={event}
185
+ activeReleases={activeReleases}
186
+ showLoading={showLoading}
187
+ soldOutReleaseCategoryNames={soldOutReleaseCategoryNames}
188
+ tickets={tickets}
189
+ isQuantityDisabled={isQuantityDisabled}
190
+ setValue={setValue as (name: string, value: any) => void}
191
+ removeTicket={removeTicket}
192
+ getExtraFields={getExtraFields}
193
+ />
297
194
  <Box>
298
195
  <Typography variant="caption" component="div" fontStyle="italic" mb={2}>
299
196
  *{t('event.tickets.stepper.1.max_ticket_quantity')}
300
197
  </Typography>
301
- {isMobile && <FeeBox event={event} align="right" />}
302
198
  </Box>
303
199
  </Stack>
304
200
  );
@@ -5,6 +5,7 @@ import { Button } from '@mui/material';
5
5
  import { iframe, TicketSelection } from '@seat-picker/seat-picker-sdk';
6
6
  import { useFormContext } from 'react-hook-form';
7
7
  import { ITicketForm, ITicketFormTicket, ITicketLocation } from '@utils/types/ticket.type.ts';
8
+ import Iconify from '@components/iconify/Iconify';
8
9
 
9
10
  interface Props {
10
11
  event: IEvent;
@@ -65,7 +66,7 @@ const TicketSelectionMap: React.FC<Props> = ({ event }) => {
65
66
 
66
67
  return (
67
68
  <Button
68
- variant="contained"
69
+ variant="outlined"
69
70
  onClick={() =>
70
71
  iframe.openPicker({
71
72
  eventId: String(event.id),
@@ -74,6 +75,13 @@ const TicketSelectionMap: React.FC<Props> = ({ event }) => {
74
75
  clientId: uuid,
75
76
  })
76
77
  }
78
+ sx={{
79
+ width: { xs: '100%' },
80
+ color: 'text.primary',
81
+ borderColor: (theme) => theme.palette.grey['300'],
82
+ '& .MuiButton-endIcon': { ml: 0, fontSize: '1.5em' },
83
+ }}
84
+ endIcon={<Iconify icon="eva:chevron-right-outline" />}
77
85
  >
78
86
  {t('form.labels.open_map')}
79
87
  </Button>
@@ -0,0 +1,177 @@
1
+ import React, { useState } from 'react';
2
+ import { Box, Skeleton, Stack, Typography, useTheme } from '@mui/material';
3
+ import { fCurrency } from '@utils/formatNumber';
4
+ import { IEvent } from '@utils/types/event.type';
5
+ import { IReleaseShort } from '@utils/types/release.type';
6
+ import { ITicketFormTicket } from '@utils/types/ticket.type';
7
+ import useGlobal from '@hooks/useGlobal';
8
+ import ReleaseDescription from './ReleaseDescription';
9
+ import TicketQuantityControl from './TicketQuantityControl';
10
+
11
+ interface Props {
12
+ event: IEvent;
13
+ activeReleases?: IReleaseShort[];
14
+ showLoading: boolean;
15
+ soldOutReleaseCategoryNames: string[];
16
+ tickets: ITicketFormTicket[];
17
+ isQuantityDisabled: (value: number, releaseId: number | '') => boolean;
18
+ setValue: (name: string, value: any) => void;
19
+ removeTicket: (indexToRemove: number) => void;
20
+ getExtraFields: (releaseId: number | '', index: number) => React.ReactNode;
21
+ }
22
+
23
+ const TicketSelectionMobile: React.FC<Props> = ({
24
+ event,
25
+ activeReleases,
26
+ showLoading,
27
+ soldOutReleaseCategoryNames,
28
+ tickets,
29
+ isQuantityDisabled,
30
+ setValue,
31
+ removeTicket,
32
+ getExtraFields,
33
+ }) => {
34
+ const { t, lang } = useGlobal();
35
+ const [expandedReleaseIds, setExpandedReleaseIds] = useState<Record<number, boolean>>({});
36
+ const theme = useTheme();
37
+ const isLight = theme.palette.mode === 'light';
38
+
39
+ const getReleaseTitle = (release: IReleaseShort) =>
40
+ release.releaseCategoryName || release.name || '';
41
+
42
+ const getTicketIndexByRelease = (releaseId: number) =>
43
+ tickets.findIndex((ticket) => ticket.releaseId === releaseId);
44
+
45
+ const getReleaseQuantity = (releaseId: number) => {
46
+ const ticket = tickets.find((t) => t.releaseId === releaseId);
47
+ return Number(ticket?.quantity || 0);
48
+ };
49
+
50
+ const updateReleaseQuantity = (release: IReleaseShort, nextQuantity: number) => {
51
+ const maxAvailable = Math.min(release.availableTickets || 0, 10);
52
+ const clampedQuantity = Math.max(0, Math.min(nextQuantity, maxAvailable));
53
+ const ticketIndex = getTicketIndexByRelease(release.id);
54
+
55
+ if (clampedQuantity <= 0) {
56
+ if (ticketIndex >= 0) removeTicket(ticketIndex);
57
+ return;
58
+ }
59
+
60
+ if (ticketIndex >= 0) {
61
+ setValue(`tickets.${event.id}.${ticketIndex}.quantity`, clampedQuantity);
62
+ return;
63
+ }
64
+
65
+ setValue(`tickets.${event.id}`, [
66
+ ...tickets,
67
+ {
68
+ releaseId: release.id,
69
+ quantity: clampedQuantity,
70
+ itemName: getReleaseTitle(release),
71
+ price: release.price || 0,
72
+ products: [],
73
+ extraFields: [],
74
+ },
75
+ ]);
76
+ };
77
+
78
+ const toggleReleaseDescription = (releaseId: number) =>
79
+ setExpandedReleaseIds((prev) => ({
80
+ ...prev,
81
+ [releaseId]: !prev[releaseId],
82
+ }));
83
+
84
+ if (showLoading) {
85
+ return (
86
+ <Stack spacing={2}>
87
+ {[...Array(2)].map((_, index) => (
88
+ <Skeleton
89
+ key={index}
90
+ variant="rounded"
91
+ sx={{
92
+ width: '100%',
93
+ height: (theme) => theme.spacing(12),
94
+ }}
95
+ />
96
+ ))}
97
+ </Stack>
98
+ );
99
+ }
100
+
101
+ return (
102
+ <Stack spacing={2}>
103
+ {activeReleases?.map((release) => {
104
+ const quantity = getReleaseQuantity(release.id);
105
+ const ticketIndex = getTicketIndexByRelease(release.id);
106
+ const maxAvailable = Math.min(release.availableTickets || 0, 10);
107
+ const isLocked =
108
+ release.locked && !soldOutReleaseCategoryNames.includes(release.releaseCategoryName);
109
+ const isDisabled = isLocked && quantity === 0;
110
+ const canAddFirst = maxAvailable > 0 && !isQuantityDisabled(1, release.id);
111
+ const canAddMore = quantity < maxAvailable && !isQuantityDisabled(quantity + 1, release.id);
112
+
113
+ return (
114
+ <Box
115
+ key={release.id}
116
+ sx={{
117
+ pt: 1,
118
+ pr: 0.5,
119
+ pb: 0.5,
120
+ pl: 2,
121
+ borderRadius: 1,
122
+ bgcolor: (theme) => (isLight ? theme.palette.grey[100] : theme.palette.grey[800]),
123
+ }}
124
+ >
125
+ <Stack spacing={0}>
126
+ <Box>
127
+ <Typography variant="subtitle2" fontWeight={700}>
128
+ {getReleaseTitle(release)}
129
+ </Typography>
130
+ </Box>
131
+
132
+ <Stack direction="row" alignItems="center" justifyContent="space-between">
133
+ <Stack>
134
+ <Typography variant="body2">
135
+ {release.price === 0
136
+ ? t('free')
137
+ : fCurrency(release.price, lang, event.currency)}
138
+ </Typography>
139
+
140
+ <ReleaseDescription
141
+ description={release.description}
142
+ isExpanded={Boolean(expandedReleaseIds[release.id])}
143
+ onToggle={() => toggleReleaseDescription(release.id)}
144
+ moreInfoLabel={t('more_info')}
145
+ />
146
+ </Stack>
147
+
148
+ <TicketQuantityControl
149
+ quantity={quantity}
150
+ isDisabled={isDisabled}
151
+ canAddFirst={canAddFirst}
152
+ canAddMore={canAddMore}
153
+ addLabel={t('add')}
154
+ onDecrement={() => updateReleaseQuantity(release, quantity - 1)}
155
+ onIncrement={() => updateReleaseQuantity(release, quantity + 1)}
156
+ onAddFirst={() => updateReleaseQuantity(release, 1)}
157
+ />
158
+ </Stack>
159
+
160
+ <ReleaseDescription
161
+ description={release.description}
162
+ isExpanded={Boolean(expandedReleaseIds[release.id])}
163
+ onToggle={() => toggleReleaseDescription(release.id)}
164
+ moreInfoLabel={t('more_info')}
165
+ showCollapse
166
+ />
167
+
168
+ {ticketIndex >= 0 && getExtraFields(release.id, ticketIndex)}
169
+ </Stack>
170
+ </Box>
171
+ );
172
+ })}
173
+ </Stack>
174
+ );
175
+ };
176
+
177
+ export default TicketSelectionMobile;
@@ -1,14 +1,12 @@
1
1
  import React, { useEffect, useRef } from 'react';
2
2
  import { useFormContext, useWatch } from 'react-hook-form';
3
- import { Box, Divider, Skeleton, Stack, Typography } from '@mui/material';
3
+ import { Box, Skeleton, Stack, Typography } from '@mui/material';
4
4
  import { ITicketForm, ITicketFormTicket } from '@utils/types/ticket.type';
5
5
  import useEventActiveReleases from '@hooks/data/useEventActiveReleases';
6
6
  import { groupBy } from '@utils/global';
7
7
  import { IReleaseShort } from '@utils/types/release.type';
8
- import FeeBox from '@form/payment/FeeBox';
9
8
  import { IEvent } from '@utils/types/event.type';
10
- import useResponsive from '@hooks/useResponsive';
11
- import ReleaseWithMerchandise from '@form/ReleaseWithMerchandise';
9
+ import ReleaseWithMerchandise from '@form/tickets/ReleaseWithMerchandise';
12
10
  import { EventType } from '@utils/data/event';
13
11
  import useGlobal from '@hooks/useGlobal.ts';
14
12
 
@@ -18,7 +16,6 @@ interface Props {
18
16
 
19
17
  const TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {
20
18
  const { t } = useGlobal();
21
- const isMobile = useResponsive('down', 'md');
22
19
  const { setValue, watch } = useFormContext<ITicketForm>();
23
20
  const tickets: ITicketFormTicket[] = useWatch({ name: `tickets.${event.id}`, defaultValue: [] });
24
21
  const eventTimeslotId = watch('eventTimeslotId');
@@ -138,7 +135,7 @@ const TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {
138
135
  };
139
136
 
140
137
  return (
141
- <Stack spacing={3} direction="column" divider={<Divider sx={{ borderStyle: 'dashed' }} />}>
138
+ <Stack spacing={1} direction="column">
142
139
  {!activeReleases && event.type !== EventType.RECURRING ? (
143
140
  <Skeleton
144
141
  variant="rounded"
@@ -169,7 +166,6 @@ const TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {
169
166
  <Typography variant="caption" component="div" fontStyle="italic" mb={2}>
170
167
  *{t('event.tickets.stepper.1.max_ticket_quantity')}
171
168
  </Typography>
172
- {isMobile && <FeeBox event={event} align="right" />}
173
169
  </Box>
174
170
  </Stack>
175
171
  );
@@ -0,0 +1,73 @@
1
+ import { RefObject, useEffect, useState } from 'react';
2
+
3
+ interface UseConsentScrollOnDrawerOpenProps {
4
+ isDrawerOpen: boolean;
5
+ consentRef: RefObject<HTMLElement | null>;
6
+ }
7
+
8
+ export default function useConsentScrollOnDrawerOpen({
9
+ isDrawerOpen,
10
+ consentRef,
11
+ }: UseConsentScrollOnDrawerOpenProps) {
12
+ const [isNearConsentSection, setIsNearConsentSection] = useState(false);
13
+
14
+ useEffect(() => {
15
+ const consentElement = consentRef.current;
16
+ if (!consentElement) {
17
+ return;
18
+ }
19
+
20
+ if (!('IntersectionObserver' in window)) {
21
+ setIsNearConsentSection(true);
22
+ return;
23
+ }
24
+
25
+ const observer = new IntersectionObserver(
26
+ (entries) => {
27
+ const entry = entries[0];
28
+ setIsNearConsentSection(entry.isIntersecting);
29
+ },
30
+ {
31
+ root: null,
32
+ threshold: 0,
33
+ rootMargin: '0px 0px 140px 0px',
34
+ }
35
+ );
36
+
37
+ observer.observe(consentElement);
38
+
39
+ return () => {
40
+ observer.disconnect();
41
+ };
42
+ }, [consentRef]);
43
+
44
+ useEffect(() => {
45
+ if (!isDrawerOpen) {
46
+ return;
47
+ }
48
+
49
+ if (window.matchMedia('(min-width:900px)').matches) {
50
+ return;
51
+ }
52
+
53
+ if (!isNearConsentSection) {
54
+ return;
55
+ }
56
+
57
+ let frameId = 0;
58
+ let frameId2 = 0;
59
+ frameId = window.requestAnimationFrame(() => {
60
+ frameId2 = window.requestAnimationFrame(() => {
61
+ consentRef.current?.scrollIntoView({
62
+ behavior: 'smooth',
63
+ block: 'center',
64
+ });
65
+ });
66
+ });
67
+
68
+ return () => {
69
+ window.cancelAnimationFrame(frameId);
70
+ window.cancelAnimationFrame(frameId2);
71
+ };
72
+ }, [consentRef, isDrawerOpen, isNearConsentSection]);
73
+ }
@@ -0,0 +1,94 @@
1
+ import { useCallback } from 'react';
2
+ import { FieldError, FieldErrors, FieldValues, Path, UseFormReturn } from 'react-hook-form';
3
+
4
+ type FirstError<T extends FieldValues> = {
5
+ name: Path<T>;
6
+ ref?: HTMLElement | null;
7
+ };
8
+
9
+ const isFieldError = (value: unknown): value is FieldError =>
10
+ !!value && typeof value === 'object' && ('type' in value || 'message' in value);
11
+
12
+ const getFirstError = <T extends FieldValues>(
13
+ errors: FieldErrors<T>,
14
+ parentPath = ''
15
+ ): FirstError<T> | null => {
16
+ for (const [key, value] of Object.entries(errors)) {
17
+ if (!value) {
18
+ continue;
19
+ }
20
+
21
+ const fieldPath = parentPath ? `${parentPath}.${key}` : key;
22
+
23
+ if (isFieldError(value)) {
24
+ return {
25
+ name: fieldPath as Path<T>,
26
+ ref: value.ref instanceof HTMLElement ? value.ref : null,
27
+ };
28
+ }
29
+
30
+ if (Array.isArray(value)) {
31
+ for (let index = 0; index < value.length; index++) {
32
+ const nestedError = value[index] as FieldErrors<T> | undefined;
33
+ if (!nestedError) {
34
+ continue;
35
+ }
36
+
37
+ const firstNestedError = getFirstError(
38
+ nestedError,
39
+ parentPath ? `${parentPath}.${key}.${index}` : `${key}.${index}`
40
+ );
41
+ if (firstNestedError) {
42
+ return firstNestedError;
43
+ }
44
+ }
45
+ } else if (typeof value === 'object') {
46
+ const firstNestedError = getFirstError(value as FieldErrors<T>, fieldPath);
47
+ if (firstNestedError) {
48
+ return firstNestedError;
49
+ }
50
+ }
51
+ }
52
+
53
+ return null;
54
+ };
55
+
56
+ const escapeSelectorValue = (value: string) => {
57
+ if (typeof CSS !== 'undefined' && typeof CSS.escape === 'function') {
58
+ return CSS.escape(value);
59
+ }
60
+
61
+ return value.replace(/"/g, '\\"');
62
+ };
63
+
64
+ type ScrollToFirstErrorMethods<T extends FieldValues> = Pick<
65
+ UseFormReturn<T, any, any>,
66
+ 'setFocus'
67
+ >;
68
+
69
+ export default function useScrollToFirstError<T extends FieldValues>(
70
+ methods: ScrollToFirstErrorMethods<T>
71
+ ) {
72
+ return useCallback(
73
+ (errors: FieldErrors<T>) => {
74
+ const firstError = getFirstError(errors);
75
+ if (!firstError) {
76
+ return;
77
+ }
78
+
79
+ methods.setFocus(firstError.name);
80
+
81
+ const scrollTarget =
82
+ firstError.ref ||
83
+ document.querySelector<HTMLElement>(
84
+ `[name="${escapeSelectorValue(String(firstError.name))}"]`
85
+ );
86
+
87
+ scrollTarget?.scrollIntoView({
88
+ behavior: 'smooth',
89
+ block: 'center',
90
+ });
91
+ },
92
+ [methods]
93
+ );
94
+ }
@@ -7,6 +7,8 @@ const cs = {
7
7
  add: 'Přidat',
8
8
  confirm: 'Potvrdit',
9
9
  cancel: 'Zrušit',
10
+ close: 'Zavřít',
11
+ remove: 'Odstranit',
10
12
  pay: 'Zaplatit',
11
13
  change: 'Změnit',
12
14
  free: 'Zdarma',
@@ -39,7 +41,7 @@ const cs = {
39
41
  promo_code: 'Slevový kód',
40
42
  start_date: 'Datum konání',
41
43
  organizer: 'Pořadatel',
42
- total: 'Celkem ',
44
+ total: 'Celkem',
43
45
  with_fee: 'vč. servisního poplatku',
44
46
  service_fee: 'Servisní poplatek',
45
47
  shipping_fee: 'Doprava',
@@ -53,6 +55,8 @@ const cs = {
53
55
  category: 'Kategorie',
54
56
  sms_notification: 'SMS notifikace',
55
57
  open_map: 'Otevřít mapu',
58
+ payment_overview_open: 'Otevřít přehled platby',
59
+ payment_overview_close: 'Zavřít přehled platby',
56
60
  },
57
61
  validation: {
58
62
  required: 'Toto pole je povinné.',
@@ -105,9 +109,13 @@ const cs = {
105
109
  7: {
106
110
  title: 'Přidružené eventy',
107
111
  },
112
+ 8: {
113
+ title: 'EventLook služby',
114
+ additional_info: 'Více informací ke službám',
115
+ },
108
116
  },
109
117
  terms_and_conditions:
110
- 'Odesláním objednávky souhlasím s <0>Obchodními podmínkami</0> {{termsAndConditionsCompanies}} a beru na vědomí <1>Zásady soukromí</1>.',
118
+ 'Souhlasím s <0>Obchodními podmínkami</0> {{termsAndConditionsCompanies}} a <1>Zásady soukromí</1>.',
111
119
  insurance: {
112
120
  label: 'Pojištění vstupenek',
113
121
  per_ticket: 'ks',
@@ -120,13 +128,20 @@ const cs = {
120
128
  },
121
129
  },
122
130
  sms_notification: {
123
- label: 'SMS připomenutí termínu akce',
131
+ label: 'SMS připomenutí termínu',
124
132
  modal: {
125
133
  description:
126
134
  'Připomínka akce den předem: SMS vás upozorní na blížící se událost, abyste na ni nezapomněli a stihli se včas připravit.',
127
135
  price: 'Cena SMS připomenutí termínu akce',
128
136
  },
129
137
  },
138
+ merchandise: {
139
+ show_sizes: 'Zobrazit velikosti',
140
+ show_added: 'Zobrazit přidané',
141
+ },
142
+ services: {
143
+ add_tickets_first: 'Nejdříve prosím přidejte vstupenky',
144
+ },
130
145
  order_success: {
131
146
  title: 'Vstupenky byly úspěšně zarezervovány. Teď už zbývá jenom zaplatit.',
132
147
  description: