@eventlook/sdk 1.4.50 → 1.4.51

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 (119) hide show
  1. package/dist/cjs/_virtual/_commonjsHelpers.js +8 -0
  2. package/dist/cjs/_virtual/_commonjsHelpers.js.map +1 -0
  3. package/dist/cjs/_virtual/index.js +6 -0
  4. package/dist/cjs/_virtual/index.js.map +1 -0
  5. package/dist/cjs/_virtual/index2.js +6 -0
  6. package/dist/cjs/_virtual/index2.js.map +1 -0
  7. package/dist/cjs/_virtual/index3.js +6 -0
  8. package/dist/cjs/_virtual/index3.js.map +1 -0
  9. package/dist/cjs/_virtual/react-is.development.js +6 -0
  10. package/dist/cjs/_virtual/react-is.development.js.map +1 -0
  11. package/dist/cjs/_virtual/react-is.development2.js +6 -0
  12. package/dist/cjs/_virtual/react-is.development2.js.map +1 -0
  13. package/dist/cjs/_virtual/react-is.production.js +6 -0
  14. package/dist/cjs/_virtual/react-is.production.js.map +1 -0
  15. package/dist/cjs/_virtual/react-is.production.min.js +6 -0
  16. package/dist/cjs/_virtual/react-is.production.min.js.map +1 -0
  17. package/dist/cjs/form/ReleaseWithMerchandise.js +57 -48
  18. package/dist/cjs/form/ReleaseWithMerchandise.js.map +1 -1
  19. package/dist/cjs/form/TicketForm.js +1 -1
  20. package/dist/cjs/form/TicketForm.js.map +1 -1
  21. package/dist/cjs/form/TicketQuantityControl.js +51 -0
  22. package/dist/cjs/form/TicketQuantityControl.js.map +1 -0
  23. package/dist/cjs/form/TicketSelection.js +5 -6
  24. package/dist/cjs/form/TicketSelection.js.map +1 -1
  25. package/dist/cjs/form/TicketSelectionMobile.js +98 -0
  26. package/dist/cjs/form/TicketSelectionMobile.js.map +1 -0
  27. package/dist/cjs/form/TicketWithMerchandiseSelection.js +3 -5
  28. package/dist/cjs/form/TicketWithMerchandiseSelection.js.map +1 -1
  29. package/dist/cjs/form/merchendise/MerchandiseSelection.js +19 -0
  30. package/dist/cjs/form/merchendise/MerchandiseSelection.js.map +1 -0
  31. package/dist/cjs/form/merchendise/MerchandiseSlider.js +75 -0
  32. package/dist/cjs/form/merchendise/MerchandiseSlider.js.map +1 -0
  33. package/dist/cjs/form/product/ProductCard.js +3 -2
  34. package/dist/cjs/form/product/ProductCard.js.map +1 -1
  35. package/dist/cjs/form/product/ProductVariantsDialog.js +23 -8
  36. package/dist/cjs/form/product/ProductVariantsDialog.js.map +1 -1
  37. package/dist/cjs/form/tickets/ReleaseWithMerchandise.js +30 -7
  38. package/dist/cjs/form/tickets/ReleaseWithMerchandise.js.map +1 -1
  39. package/dist/cjs/form/tickets/TicketSelection.js +37 -14
  40. package/dist/cjs/form/tickets/TicketSelection.js.map +1 -1
  41. package/dist/cjs/form/tickets/TicketSelectionMap.js +7 -1
  42. package/dist/cjs/form/tickets/TicketSelectionMap.js.map +1 -1
  43. package/dist/cjs/form/tickets/TicketSelectionMobile.js +17 -7
  44. package/dist/cjs/form/tickets/TicketSelectionMobile.js.map +1 -1
  45. package/dist/cjs/form/tickets/TicketWithMerchandiseSelection.js +30 -20
  46. package/dist/cjs/form/tickets/TicketWithMerchandiseSelection.js.map +1 -1
  47. package/dist/cjs/hooks/useConsentScrollOnDrawerOpen.js +59 -0
  48. package/dist/cjs/hooks/useConsentScrollOnDrawerOpen.js.map +1 -0
  49. package/dist/cjs/utils/data/ticket.js +6 -0
  50. package/dist/cjs/utils/data/ticket.js.map +1 -0
  51. package/dist/esm/_virtual/_commonjsHelpers.js +6 -0
  52. package/dist/esm/_virtual/_commonjsHelpers.js.map +1 -0
  53. package/dist/esm/_virtual/index.js +4 -0
  54. package/dist/esm/_virtual/index.js.map +1 -0
  55. package/dist/esm/_virtual/index2.js +4 -0
  56. package/dist/esm/_virtual/index2.js.map +1 -0
  57. package/dist/esm/_virtual/index3.js +4 -0
  58. package/dist/esm/_virtual/index3.js.map +1 -0
  59. package/dist/esm/_virtual/react-is.development.js +4 -0
  60. package/dist/esm/_virtual/react-is.development.js.map +1 -0
  61. package/dist/esm/_virtual/react-is.development2.js +4 -0
  62. package/dist/esm/_virtual/react-is.development2.js.map +1 -0
  63. package/dist/esm/_virtual/react-is.production.js +4 -0
  64. package/dist/esm/_virtual/react-is.production.js.map +1 -0
  65. package/dist/esm/_virtual/react-is.production.min.js +4 -0
  66. package/dist/esm/_virtual/react-is.production.min.js.map +1 -0
  67. package/dist/esm/form/ReleaseWithMerchandise.js +58 -49
  68. package/dist/esm/form/ReleaseWithMerchandise.js.map +1 -1
  69. package/dist/esm/form/TicketForm.js +1 -1
  70. package/dist/esm/form/TicketForm.js.map +1 -1
  71. package/dist/esm/form/TicketQuantityControl.js +47 -0
  72. package/dist/esm/form/TicketQuantityControl.js.map +1 -0
  73. package/dist/esm/form/TicketSelection.js +5 -6
  74. package/dist/esm/form/TicketSelection.js.map +1 -1
  75. package/dist/esm/form/TicketSelectionMobile.js +94 -0
  76. package/dist/esm/form/TicketSelectionMobile.js.map +1 -0
  77. package/dist/esm/form/TicketWithMerchandiseSelection.js +4 -6
  78. package/dist/esm/form/TicketWithMerchandiseSelection.js.map +1 -1
  79. package/dist/esm/form/merchendise/MerchandiseSelection.js +15 -0
  80. package/dist/esm/form/merchendise/MerchandiseSelection.js.map +1 -0
  81. package/dist/esm/form/merchendise/MerchandiseSlider.js +71 -0
  82. package/dist/esm/form/merchendise/MerchandiseSlider.js.map +1 -0
  83. package/dist/esm/form/product/ProductCard.js +3 -2
  84. package/dist/esm/form/product/ProductCard.js.map +1 -1
  85. package/dist/esm/form/product/ProductVariantsDialog.js +23 -8
  86. package/dist/esm/form/product/ProductVariantsDialog.js.map +1 -1
  87. package/dist/esm/form/tickets/ReleaseWithMerchandise.js +30 -7
  88. package/dist/esm/form/tickets/ReleaseWithMerchandise.js.map +1 -1
  89. package/dist/esm/form/tickets/TicketSelection.js +38 -15
  90. package/dist/esm/form/tickets/TicketSelection.js.map +1 -1
  91. package/dist/esm/form/tickets/TicketSelectionMap.js +7 -1
  92. package/dist/esm/form/tickets/TicketSelectionMap.js.map +1 -1
  93. package/dist/esm/form/tickets/TicketSelectionMobile.js +17 -7
  94. package/dist/esm/form/tickets/TicketSelectionMobile.js.map +1 -1
  95. package/dist/esm/form/tickets/TicketWithMerchandiseSelection.js +30 -20
  96. package/dist/esm/form/tickets/TicketWithMerchandiseSelection.js.map +1 -1
  97. package/dist/esm/hooks/useConsentScrollOnDrawerOpen.js +55 -0
  98. package/dist/esm/hooks/useConsentScrollOnDrawerOpen.js.map +1 -0
  99. package/dist/esm/utils/data/ticket.js +4 -0
  100. package/dist/esm/utils/data/ticket.js.map +1 -0
  101. package/dist/types/form/PaymentOverviewDrawer.d.ts +8 -0
  102. package/dist/types/form/merchendise/MerchandiseSelection.d.ts +9 -0
  103. package/dist/types/form/merchendise/MerchandiseSlider.d.ts +10 -0
  104. package/dist/types/form/merchendise/MerchendiseSlider.d.ts +0 -0
  105. package/dist/types/locales/cs.d.ts +1 -5
  106. package/package.json +1 -1
  107. package/src/form/TicketForm.tsx +8 -6
  108. package/src/form/product/ProductCard.tsx +5 -2
  109. package/src/form/product/ProductVariantsDialog.tsx +29 -6
  110. package/src/form/tickets/ReleaseWithMerchandise.tsx +39 -8
  111. package/src/form/tickets/TicketSelection.tsx +50 -17
  112. package/src/form/tickets/TicketSelectionMap.tsx +9 -1
  113. package/src/form/tickets/TicketSelectionMobile.tsx +77 -67
  114. package/src/form/tickets/TicketWithMerchandiseSelection.tsx +49 -31
  115. package/src/utils/data/ticket.ts +1 -0
  116. package/dist/cjs/hooks/useFirstRender.js +0 -14
  117. package/dist/cjs/hooks/useFirstRender.js.map +0 -1
  118. package/dist/esm/hooks/useFirstRender.js +0 -12
  119. package/dist/esm/hooks/useFirstRender.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"TicketSelectionMap.js","sources":["../../../../src/form/tickets/TicketSelectionMap.tsx"],"sourcesContent":["import React from 'react';\nimport useGlobal from '@hooks/useGlobal.ts';\nimport { IEvent } from '@utils/types/event.type.ts';\nimport { Button } from '@mui/material';\nimport { iframe, TicketSelection } from '@seat-picker/seat-picker-sdk';\nimport { useFormContext } from 'react-hook-form';\nimport { ITicketForm, ITicketFormTicket, ITicketLocation } from '@utils/types/ticket.type.ts';\nimport Iconify from '@components/iconify/Iconify';\n\ninterface Props {\n event: IEvent;\n}\n\nconst TicketSelectionMap: React.FC<Props> = ({ event }) => {\n const { t, seatingIframeUrl } = useGlobal();\n const { setValue, watch } = useFormContext<ITicketForm>();\n const uuid = watch('uuid');\n\n if (!uuid) return;\n\n const onSelect = (seats: TicketSelection) => {\n const tickets: ITicketFormTicket[] = [];\n const groupedSeatsByZone = seats.reduce(\n (tickets, seat) => {\n const zoneIndex = tickets.findIndex((ticket) => ticket.seat.id === seat.locationId);\n if (zoneIndex !== -1) {\n tickets[zoneIndex].quantity += 1;\n } else {\n tickets.push({\n seat: {\n id: seat.locationId,\n type: seat.locationType,\n locationDescription: seat.locationTypeDescription,\n },\n quantity: 1,\n ticket: seat.ticket,\n });\n }\n\n return tickets;\n },\n // TODO: fix types\n [] as { quantity: number; seat: ITicketLocation; ticket: any }[]\n );\n\n for (const groupedSeat of groupedSeatsByZone) {\n tickets.push({\n releaseId: groupedSeat.ticket.id,\n price: groupedSeat.ticket.price,\n quantity: groupedSeat.quantity,\n itemName: `${groupedSeat.ticket.releaseCategoryName} - ${groupedSeat.ticket.name}`,\n products: [],\n extraFields: [],\n location: {\n id: groupedSeat.seat.id,\n type: groupedSeat.seat.type,\n locationDescription: groupedSeat.seat.locationDescription,\n },\n });\n }\n\n setValue(`tickets.${event.id}`, tickets);\n };\n\n if (!seatingIframeUrl) return null;\n\n return (\n <Button\n variant=\"outlined\"\n onClick={() =>\n iframe.openPicker({\n eventId: String(event.id),\n onSelect,\n baseUrl: seatingIframeUrl,\n clientId: uuid,\n })\n }\n sx={{\n width: { xs: '100%' },\n color: 'text.primary',\n borderColor: (theme) => theme.palette.grey['300'],\n '& .MuiButton-endIcon': { ml: 0, fontSize: '1.5em' },\n }}\n endIcon={<Iconify icon=\"eva:chevron-right-outline\" />}\n >\n {t('form.labels.open_map')}\n </Button>\n );\n};\n\nexport default TicketSelectionMap;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TicketSelectionMap.js","sources":["../../../../src/form/tickets/TicketSelectionMap.tsx"],"sourcesContent":["import React from 'react';\nimport useGlobal from '@hooks/useGlobal.ts';\nimport { IEvent } from '@utils/types/event.type.ts';\nimport { Button } from '@mui/material';\nimport { iframe, TicketSelection } from '@seat-picker/seat-picker-sdk';\nimport { useFormContext } from 'react-hook-form';\nimport { ITicketForm, ITicketFormTicket, ITicketLocation } from '@utils/types/ticket.type.ts';\nimport { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';\nimport Iconify from '@components/iconify/Iconify';\n\ninterface Props {\n event: IEvent;\n}\n\nconst TicketSelectionMap: React.FC<Props> = ({ event }) => {\n const { t, seatingIframeUrl } = useGlobal();\n const { setValue, watch } = useFormContext<ITicketForm>();\n const uuid = watch('uuid');\n\n if (!uuid) return;\n\n const onSelect = (seats: TicketSelection) => {\n const tickets: ITicketFormTicket[] = [];\n const groupedSeatsByZone = seats.reduce(\n (tickets, seat) => {\n const zoneIndex = tickets.findIndex((ticket) => ticket.seat.id === seat.locationId);\n if (zoneIndex !== -1) {\n tickets[zoneIndex].quantity += 1;\n } else {\n tickets.push({\n seat: {\n id: seat.locationId,\n type: seat.locationType,\n locationDescription: seat.locationTypeDescription,\n },\n quantity: 1,\n ticket: seat.ticket,\n });\n }\n\n return tickets;\n },\n // TODO: fix types\n [] as { quantity: number; seat: ITicketLocation; ticket: any }[]\n );\n\n let remainingTicketCapacity = MAX_TICKETS_PER_ORDER;\n\n for (const groupedSeat of groupedSeatsByZone) {\n if (remainingTicketCapacity <= 0) break;\n\n const quantity = Math.min(groupedSeat.quantity, remainingTicketCapacity);\n remainingTicketCapacity -= quantity;\n\n tickets.push({\n releaseId: groupedSeat.ticket.id,\n price: groupedSeat.ticket.price,\n quantity,\n itemName: `${groupedSeat.ticket.releaseCategoryName} - ${groupedSeat.ticket.name}`,\n products: [],\n extraFields: [],\n location: {\n id: groupedSeat.seat.id,\n type: groupedSeat.seat.type,\n locationDescription: groupedSeat.seat.locationDescription,\n },\n });\n }\n\n setValue(`tickets.${event.id}`, tickets);\n };\n\n if (!seatingIframeUrl) return null;\n\n return (\n <Button\n variant=\"outlined\"\n onClick={() =>\n iframe.openPicker({\n eventId: String(event.id),\n onSelect,\n baseUrl: seatingIframeUrl,\n clientId: uuid,\n })\n }\n sx={{\n width: { xs: '100%' },\n color: 'text.primary',\n borderColor: (theme) => theme.palette.grey['300'],\n '& .MuiButton-endIcon': { ml: 0, fontSize: '1.5em' },\n }}\n endIcon={<Iconify icon=\"eva:chevron-right-outline\" />}\n >\n {t('form.labels.open_map')}\n </Button>\n );\n};\n\nexport default TicketSelectionMap;\n"],"names":[],"mappings":"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"}
@@ -1,11 +1,12 @@
1
1
  import React, { useState } from 'react';
2
2
  import { useTheme, Stack, Skeleton, Box, Typography } from '@mui/material';
3
3
  import { fCurrency } from '../../utils/formatNumber.js';
4
+ import { MAX_TICKETS_PER_ORDER } from '../../utils/data/ticket.js';
4
5
  import useGlobal from '../../hooks/useGlobal.js';
5
6
  import ReleaseDescription from './ReleaseDescription.js';
6
7
  import TicketQuantityControl from './TicketQuantityControl.js';
7
8
 
8
- const TicketSelectionMobile = ({ event, activeReleases, showLoading, soldOutReleaseCategoryNames, tickets, isQuantityDisabled, setValue, removeTicket, getExtraFields, }) => {
9
+ const TicketSelectionMobile = ({ event, activeReleases, showLoading, tickets, isQuantityDisabled, setValue, removeTicket, getExtraFields, }) => {
9
10
  const { t, lang } = useGlobal();
10
11
  const [expandedReleaseIds, setExpandedReleaseIds] = useState({});
11
12
  const theme = useTheme();
@@ -16,8 +17,9 @@ const TicketSelectionMobile = ({ event, activeReleases, showLoading, soldOutRele
16
17
  const ticket = tickets.find((t) => t.releaseId === releaseId);
17
18
  return Number(ticket?.quantity || 0);
18
19
  };
20
+ const isReleaseVisible = (release) => !release.locked || getReleaseQuantity(release.id) > 0;
19
21
  const updateReleaseQuantity = (release, nextQuantity) => {
20
- const maxAvailable = Math.min(release.availableTickets || 0, 10);
22
+ const maxAvailable = Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER);
21
23
  const clampedQuantity = Math.max(0, Math.min(nextQuantity, maxAvailable));
22
24
  const ticketIndex = getTicketIndexByRelease(release.id);
23
25
  if (clampedQuantity <= 0) {
@@ -51,12 +53,17 @@ const TicketSelectionMobile = ({ event, activeReleases, showLoading, soldOutRele
51
53
  height: (theme) => theme.spacing(12),
52
54
  } })))));
53
55
  }
54
- return (React.createElement(Stack, { spacing: 2 }, activeReleases?.map((release) => {
56
+ return (React.createElement(Stack, { spacing: 2 }, activeReleases
57
+ ?.filter((release) => isReleaseVisible(release))
58
+ .map((release) => {
55
59
  const quantity = getReleaseQuantity(release.id);
56
60
  const ticketIndex = getTicketIndexByRelease(release.id);
57
- const maxAvailable = Math.min(release.availableTickets || 0, 10);
58
- const isLocked = release.locked && !soldOutReleaseCategoryNames.includes(release.releaseCategoryName);
59
- const isDisabled = isLocked && quantity === 0;
61
+ const maxAvailable = Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER);
62
+ const isLocked = release.locked;
63
+ const nextRelease = activeReleases?.find((item) => item.releaseCategoryName === release.releaseCategoryName &&
64
+ item.order === release.order + 1);
65
+ const hasSelectedNextRelease = !!nextRelease && getReleaseQuantity(nextRelease.id) > 0;
66
+ const isDisabled = hasSelectedNextRelease || (isLocked && quantity === 0);
60
67
  const canAddFirst = maxAvailable > 0 && !isQuantityDisabled(1, release.id);
61
68
  const canAddMore = quantity < maxAvailable && !isQuantityDisabled(quantity + 1, release.id);
62
69
  return (React.createElement(Box, { key: release.id, sx: {
@@ -69,7 +76,10 @@ const TicketSelectionMobile = ({ event, activeReleases, showLoading, soldOutRele
69
76
  } },
70
77
  React.createElement(Stack, { spacing: 0 },
71
78
  React.createElement(Box, null,
72
- React.createElement(Typography, { variant: "subtitle2", fontWeight: 700 }, getReleaseTitle(release))),
79
+ React.createElement(Typography, { variant: "subtitle2", fontWeight: 700 },
80
+ getReleaseTitle(release),
81
+ " - ",
82
+ release.name)),
73
83
  React.createElement(Stack, { direction: "row", alignItems: "center", justifyContent: "space-between" },
74
84
  React.createElement(Stack, null,
75
85
  React.createElement(Typography, { variant: "body2" }, release.price === 0
@@ -1 +1 @@
1
- {"version":3,"file":"TicketSelectionMobile.js","sources":["../../../../src/form/tickets/TicketSelectionMobile.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Box, Skeleton, Stack, Typography, useTheme } from '@mui/material';\nimport { fCurrency } from '@utils/formatNumber';\nimport { IEvent } from '@utils/types/event.type';\nimport { IReleaseShort } from '@utils/types/release.type';\nimport { ITicketFormTicket } from '@utils/types/ticket.type';\nimport useGlobal from '@hooks/useGlobal';\nimport ReleaseDescription from './ReleaseDescription';\nimport TicketQuantityControl from './TicketQuantityControl';\n\ninterface Props {\n event: IEvent;\n activeReleases?: IReleaseShort[];\n showLoading: boolean;\n soldOutReleaseCategoryNames: string[];\n tickets: ITicketFormTicket[];\n isQuantityDisabled: (value: number, releaseId: number | '') => boolean;\n setValue: (name: string, value: any) => void;\n removeTicket: (indexToRemove: number) => void;\n getExtraFields: (releaseId: number | '', index: number) => React.ReactNode;\n}\n\nconst TicketSelectionMobile: React.FC<Props> = ({\n event,\n activeReleases,\n showLoading,\n soldOutReleaseCategoryNames,\n tickets,\n isQuantityDisabled,\n setValue,\n removeTicket,\n getExtraFields,\n}) => {\n const { t, lang } = useGlobal();\n const [expandedReleaseIds, setExpandedReleaseIds] = useState<Record<number, boolean>>({});\n const theme = useTheme();\n const isLight = theme.palette.mode === 'light';\n\n const getReleaseTitle = (release: IReleaseShort) =>\n release.releaseCategoryName || release.name || '';\n\n const getTicketIndexByRelease = (releaseId: number) =>\n tickets.findIndex((ticket) => ticket.releaseId === releaseId);\n\n const getReleaseQuantity = (releaseId: number) => {\n const ticket = tickets.find((t) => t.releaseId === releaseId);\n return Number(ticket?.quantity || 0);\n };\n\n const updateReleaseQuantity = (release: IReleaseShort, nextQuantity: number) => {\n const maxAvailable = Math.min(release.availableTickets || 0, 10);\n const clampedQuantity = Math.max(0, Math.min(nextQuantity, maxAvailable));\n const ticketIndex = getTicketIndexByRelease(release.id);\n\n if (clampedQuantity <= 0) {\n if (ticketIndex >= 0) removeTicket(ticketIndex);\n return;\n }\n\n if (ticketIndex >= 0) {\n setValue(`tickets.${event.id}.${ticketIndex}.quantity`, clampedQuantity);\n return;\n }\n\n setValue(`tickets.${event.id}`, [\n ...tickets,\n {\n releaseId: release.id,\n quantity: clampedQuantity,\n itemName: getReleaseTitle(release),\n price: release.price || 0,\n products: [],\n extraFields: [],\n },\n ]);\n };\n\n const toggleReleaseDescription = (releaseId: number) =>\n setExpandedReleaseIds((prev) => ({\n ...prev,\n [releaseId]: !prev[releaseId],\n }));\n\n if (showLoading) {\n return (\n <Stack spacing={2}>\n {[...Array(2)].map((_, index) => (\n <Skeleton\n key={index}\n variant=\"rounded\"\n sx={{\n width: '100%',\n height: (theme) => theme.spacing(12),\n }}\n />\n ))}\n </Stack>\n );\n }\n\n return (\n <Stack spacing={2}>\n {activeReleases?.map((release) => {\n const quantity = getReleaseQuantity(release.id);\n const ticketIndex = getTicketIndexByRelease(release.id);\n const maxAvailable = Math.min(release.availableTickets || 0, 10);\n const isLocked =\n release.locked && !soldOutReleaseCategoryNames.includes(release.releaseCategoryName);\n const isDisabled = isLocked && quantity === 0;\n const canAddFirst = maxAvailable > 0 && !isQuantityDisabled(1, release.id);\n const canAddMore = quantity < maxAvailable && !isQuantityDisabled(quantity + 1, release.id);\n\n return (\n <Box\n key={release.id}\n sx={{\n pt: 1,\n pr: 0.5,\n pb: 0.5,\n pl: 2,\n borderRadius: 1,\n bgcolor: (theme) => (isLight ? theme.palette.grey[100] : theme.palette.grey[800]),\n }}\n >\n <Stack spacing={0}>\n <Box>\n <Typography variant=\"subtitle2\" fontWeight={700}>\n {getReleaseTitle(release)}\n </Typography>\n </Box>\n\n <Stack direction=\"row\" alignItems=\"center\" justifyContent=\"space-between\">\n <Stack>\n <Typography variant=\"body2\">\n {release.price === 0\n ? t('free')\n : fCurrency(release.price, lang, event.currency)}\n </Typography>\n\n <ReleaseDescription\n description={release.description}\n isExpanded={Boolean(expandedReleaseIds[release.id])}\n onToggle={() => toggleReleaseDescription(release.id)}\n moreInfoLabel={t('more_info')}\n />\n </Stack>\n\n <TicketQuantityControl\n quantity={quantity}\n isDisabled={isDisabled}\n canAddFirst={canAddFirst}\n canAddMore={canAddMore}\n addLabel={t('add')}\n onDecrement={() => updateReleaseQuantity(release, quantity - 1)}\n onIncrement={() => updateReleaseQuantity(release, quantity + 1)}\n onAddFirst={() => updateReleaseQuantity(release, 1)}\n />\n </Stack>\n\n <ReleaseDescription\n description={release.description}\n isExpanded={Boolean(expandedReleaseIds[release.id])}\n onToggle={() => toggleReleaseDescription(release.id)}\n moreInfoLabel={t('more_info')}\n showCollapse\n />\n\n {ticketIndex >= 0 && getExtraFields(release.id, ticketIndex)}\n </Stack>\n </Box>\n );\n })}\n </Stack>\n );\n};\n\nexport default TicketSelectionMobile;\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"TicketSelectionMobile.js","sources":["../../../../src/form/tickets/TicketSelectionMobile.tsx"],"sourcesContent":["import React, { useState } from 'react';\nimport { Box, Skeleton, Stack, Typography, useTheme } from '@mui/material';\nimport { fCurrency } from '@utils/formatNumber';\nimport { IEvent } from '@utils/types/event.type';\nimport { IReleaseShort } from '@utils/types/release.type';\nimport { ITicketFormTicket } from '@utils/types/ticket.type';\nimport { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';\nimport useGlobal from '@hooks/useGlobal';\nimport ReleaseDescription from './ReleaseDescription';\nimport TicketQuantityControl from './TicketQuantityControl';\n\ninterface Props {\n event: IEvent;\n activeReleases?: IReleaseShort[];\n showLoading: boolean;\n tickets: ITicketFormTicket[];\n isQuantityDisabled: (value: number, releaseId: number | '') => boolean;\n setValue: (name: string, value: any) => void;\n removeTicket: (indexToRemove: number) => void;\n getExtraFields: (releaseId: number | '', index: number) => React.ReactNode;\n}\n\nconst TicketSelectionMobile: React.FC<Props> = ({\n event,\n activeReleases,\n showLoading,\n tickets,\n isQuantityDisabled,\n setValue,\n removeTicket,\n getExtraFields,\n}) => {\n const { t, lang } = useGlobal();\n const [expandedReleaseIds, setExpandedReleaseIds] = useState<Record<number, boolean>>({});\n const theme = useTheme();\n const isLight = theme.palette.mode === 'light';\n\n const getReleaseTitle = (release: IReleaseShort) =>\n release.releaseCategoryName || release.name || '';\n\n const getTicketIndexByRelease = (releaseId: number) =>\n tickets.findIndex((ticket) => ticket.releaseId === releaseId);\n\n const getReleaseQuantity = (releaseId: number) => {\n const ticket = tickets.find((t) => t.releaseId === releaseId);\n return Number(ticket?.quantity || 0);\n };\n\n const isReleaseVisible = (release: IReleaseShort) =>\n !release.locked || getReleaseQuantity(release.id) > 0;\n\n const updateReleaseQuantity = (release: IReleaseShort, nextQuantity: number) => {\n const maxAvailable = Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER);\n const clampedQuantity = Math.max(0, Math.min(nextQuantity, maxAvailable));\n const ticketIndex = getTicketIndexByRelease(release.id);\n\n if (clampedQuantity <= 0) {\n if (ticketIndex >= 0) removeTicket(ticketIndex);\n return;\n }\n\n if (ticketIndex >= 0) {\n setValue(`tickets.${event.id}.${ticketIndex}.quantity`, clampedQuantity);\n return;\n }\n\n setValue(`tickets.${event.id}`, [\n ...tickets,\n {\n releaseId: release.id,\n quantity: clampedQuantity,\n itemName: getReleaseTitle(release),\n price: release.price || 0,\n products: [],\n extraFields: [],\n },\n ]);\n };\n\n const toggleReleaseDescription = (releaseId: number) =>\n setExpandedReleaseIds((prev) => ({\n ...prev,\n [releaseId]: !prev[releaseId],\n }));\n\n if (showLoading) {\n return (\n <Stack spacing={2}>\n {[...Array(2)].map((_, index) => (\n <Skeleton\n key={index}\n variant=\"rounded\"\n sx={{\n width: '100%',\n height: (theme) => theme.spacing(12),\n }}\n />\n ))}\n </Stack>\n );\n }\n\n return (\n <Stack spacing={2}>\n {activeReleases\n ?.filter((release) => isReleaseVisible(release))\n .map((release) => {\n const quantity = getReleaseQuantity(release.id);\n const ticketIndex = getTicketIndexByRelease(release.id);\n const maxAvailable = Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER);\n const isLocked = release.locked;\n const nextRelease = activeReleases?.find(\n (item) =>\n item.releaseCategoryName === release.releaseCategoryName &&\n item.order === release.order + 1\n );\n const hasSelectedNextRelease = !!nextRelease && getReleaseQuantity(nextRelease.id) > 0;\n const isDisabled = hasSelectedNextRelease || (isLocked && quantity === 0);\n const canAddFirst = maxAvailable > 0 && !isQuantityDisabled(1, release.id);\n const canAddMore =\n quantity < maxAvailable && !isQuantityDisabled(quantity + 1, release.id);\n\n return (\n <Box\n key={release.id}\n sx={{\n pt: 1,\n pr: 0.5,\n pb: 0.5,\n pl: 2,\n borderRadius: 1,\n bgcolor: (theme) => (isLight ? theme.palette.grey[100] : theme.palette.grey[800]),\n }}\n >\n <Stack spacing={0}>\n <Box>\n <Typography variant=\"subtitle2\" fontWeight={700}>\n {getReleaseTitle(release)} - {release.name}\n </Typography>\n </Box>\n\n <Stack direction=\"row\" alignItems=\"center\" justifyContent=\"space-between\">\n <Stack>\n <Typography variant=\"body2\">\n {release.price === 0\n ? t('free')\n : fCurrency(release.price, lang, event.currency)}\n </Typography>\n\n <ReleaseDescription\n description={release.description}\n isExpanded={Boolean(expandedReleaseIds[release.id])}\n onToggle={() => toggleReleaseDescription(release.id)}\n moreInfoLabel={t('more_info')}\n />\n </Stack>\n\n <TicketQuantityControl\n quantity={quantity}\n isDisabled={isDisabled}\n canAddFirst={canAddFirst}\n canAddMore={canAddMore}\n addLabel={t('add')}\n onDecrement={() => updateReleaseQuantity(release, quantity - 1)}\n onIncrement={() => updateReleaseQuantity(release, quantity + 1)}\n onAddFirst={() => updateReleaseQuantity(release, 1)}\n />\n </Stack>\n\n <ReleaseDescription\n description={release.description}\n isExpanded={Boolean(expandedReleaseIds[release.id])}\n onToggle={() => toggleReleaseDescription(release.id)}\n moreInfoLabel={t('more_info')}\n showCollapse\n />\n\n {ticketIndex >= 0 && getExtraFields(release.id, ticketIndex)}\n </Stack>\n </Box>\n );\n })}\n </Stack>\n );\n};\n\nexport default TicketSelectionMobile;\n"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@ import useEventActiveReleases from '../../hooks/data/useEventActiveReleases.js';
5
5
  import { groupBy } from '../../utils/global.js';
6
6
  import ReleaseWithMerchandise from './ReleaseWithMerchandise.js';
7
7
  import { EventType } from '../../utils/data/event.js';
8
+ import { MAX_TICKETS_PER_ORDER } from '../../utils/data/ticket.js';
8
9
  import useGlobal from '../../hooks/useGlobal.js';
9
10
 
10
11
  const TicketWithMerchandiseSelection = ({ event }) => {
@@ -26,7 +27,12 @@ const TicketWithMerchandiseSelection = ({ event }) => {
26
27
  const lockedSelectedReleases = releases?.map((item, index) => {
27
28
  const nextRelease = releases?.find((item2) => item2.releaseCategoryName === item.releaseCategoryName && item2.order === item.order + 1);
28
29
  const selected = tickets.find((ticket) => ticket.releaseId === item.id);
29
- return !!nextRelease && item.locked && !!selected && index + 1 == tickets.length;
30
+ const maxSelectable = Math.min(item.availableTickets || 0, MAX_TICKETS_PER_ORDER);
31
+ return (!!nextRelease &&
32
+ item.locked &&
33
+ !!selected &&
34
+ Number(selected.quantity) >= maxSelectable &&
35
+ index + 1 == tickets.length);
30
36
  });
31
37
  return lockedSelectedReleases && lockedSelectedReleases.includes(true);
32
38
  };
@@ -34,36 +40,38 @@ const TicketWithMerchandiseSelection = ({ event }) => {
34
40
  const isReleaseSelected = (id) => !!tickets.find((ticket) => ticket.releaseId === id);
35
41
  const selectedTickets = async () => {
36
42
  const releases = await mutate();
43
+ const currentReleases = releases || activeReleases || [];
37
44
  const allFilled = tickets.filter((item) => !item.releaseId || !item.quantity);
38
- const soldOutReleaseCategories = activeReleases?.filter((release) => tickets.find((ticket) => release.id === ticket.releaseId &&
39
- ticket.quantity === release.availableTickets &&
40
- release.availableTickets !== 10));
45
+ const soldOutReleaseCategories = currentReleases.filter((release) => tickets.find((ticket) => release.id === ticket.releaseId &&
46
+ Number(ticket.quantity) >= Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER)));
41
47
  // Unlock next releases when current release is sold out
42
- if (soldOutReleaseCategories?.length && activeReleases) {
48
+ if (currentReleases.length) {
43
49
  let hasChanges = false;
44
- const updatedReleases = activeReleases.map((release) => {
45
- // For each sold-out release, find and unlock the next one
46
- const soldOutRelease = soldOutReleaseCategories.find((soldOut) => soldOut.releaseCategoryName === release.releaseCategoryName &&
47
- soldOut.order === release.order - 1 &&
48
- release.locked);
49
- if (soldOutRelease) {
50
- hasChanges = true;
51
- return { ...release, locked: false };
52
- }
53
- return release;
50
+ const updatedReleases = currentReleases.map((release) => {
51
+ const previousRelease = currentReleases.find((item) => item.releaseCategoryName === release.releaseCategoryName &&
52
+ item.order === release.order - 1);
53
+ if (!release.locked || !previousRelease)
54
+ return release;
55
+ const previousTicket = tickets.find((ticket) => ticket.releaseId === previousRelease.id);
56
+ const previousMaxSelectable = Math.min(previousRelease.availableTickets || 0, MAX_TICKETS_PER_ORDER);
57
+ const shouldUnlock = Number(previousTicket?.quantity || 0) >= previousMaxSelectable;
58
+ if (!shouldUnlock)
59
+ return release;
60
+ hasChanges = true;
61
+ return { ...release, locked: false };
54
62
  });
55
63
  if (hasChanges) {
56
64
  await mutate(updatedReleases, false);
57
65
  }
58
66
  }
59
- const hasSelectableRelease = activeReleases?.some((release) => !isReleaseSelected(release.id) && !release.locked);
67
+ const hasSelectableRelease = currentReleases.some((release) => !isReleaseSelected(release.id) && !release.locked);
60
68
  const shouldAddRow = (soldOutReleaseCategories &&
61
69
  selectedReleaseIsSoldOut(releases) &&
62
70
  tickets.length < soldOutReleaseCategories.length + countUnlockedReleases() &&
63
71
  !allFilled.length) ||
64
- (activeReleases &&
65
- soldOutReleaseCategories?.length &&
66
- activeReleases?.length > tickets.length &&
72
+ (currentReleases.length &&
73
+ soldOutReleaseCategories.length &&
74
+ currentReleases.length > tickets.length &&
67
75
  tickets.length < soldOutReleaseCategories.length + countUnlockedReleases() &&
68
76
  !allFilled.length) ||
69
77
  (tickets.length < countReleaseCategories() && !allFilled.length);
@@ -100,7 +108,9 @@ const TicketWithMerchandiseSelection = ({ event }) => {
100
108
  !activeReleases && event.type !== EventType.RECURRING ? (React.createElement(Skeleton, { variant: "rounded", sx: {
101
109
  width: '100%',
102
110
  height: (theme) => theme.spacing(7.5),
103
- } })) : (activeReleases?.map((release, index) => (React.createElement(ReleaseWithMerchandise, { key: release.id, eventId: event.id, release: release, activeReleases: activeReleases, currency: event.currency, index: index })))),
111
+ } })) : (activeReleases
112
+ ?.filter((release) => !release.locked || isReleaseSelected(release.id))
113
+ .map((release, index) => (React.createElement(ReleaseWithMerchandise, { key: release.id, eventId: event.id, release: release, activeReleases: activeReleases, currency: event.currency, index: index })))),
104
114
  !activeReleases && event.type === EventType.RECURRING && (React.createElement(Typography, { variant: "h5" }, t('event.tickets.stepper.1.select_timeslot'))),
105
115
  !!activeReleases && !activeReleases.length && (React.createElement(Typography, { variant: "h5" }, t('event.tickets.stepper.1.no_tickets'))),
106
116
  React.createElement(Box, null,
@@ -1 +1 @@
1
- {"version":3,"file":"TicketWithMerchandiseSelection.js","sources":["../../../../src/form/tickets/TicketWithMerchandiseSelection.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport { useFormContext, useWatch } from 'react-hook-form';\nimport { Box, Skeleton, Stack, Typography } from '@mui/material';\nimport { ITicketForm, ITicketFormTicket } from '@utils/types/ticket.type';\nimport useEventActiveReleases from '@hooks/data/useEventActiveReleases';\nimport { groupBy } from '@utils/global';\nimport { IReleaseShort } from '@utils/types/release.type';\nimport { IEvent } from '@utils/types/event.type';\nimport ReleaseWithMerchandise from '@form/tickets/ReleaseWithMerchandise';\nimport { EventType } from '@utils/data/event';\nimport useGlobal from '@hooks/useGlobal.ts';\n\ninterface Props {\n event: IEvent;\n}\n\nconst TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {\n const { t } = useGlobal();\n const { setValue, watch } = useFormContext<ITicketForm>();\n const tickets: ITicketFormTicket[] = useWatch({ name: `tickets.${event.id}`, defaultValue: [] });\n const eventTimeslotId = watch('eventTimeslotId');\n const isProcessingRef = useRef(false);\n const { data: activeReleases, mutate } = useEventActiveReleases(\n event.id,\n false,\n event.type === EventType.RECURRING ? eventTimeslotId : undefined\n );\n\n useEffect(() => {\n if (!isProcessingRef.current) selectedTickets();\n }, [tickets, activeReleases]);\n\n const countReleaseCategories = (): number => {\n const grouped = groupBy(activeReleases || [], 'releaseCategoryName');\n return Object.keys(grouped).length;\n };\n\n const selectedReleaseIsSoldOut = (releases: IReleaseShort[] | undefined) => {\n const lockedSelectedReleases: boolean[] | undefined = releases?.map((item, index) => {\n const nextRelease = releases?.find(\n (item2) =>\n item2.releaseCategoryName === item.releaseCategoryName && item2.order === item.order + 1\n );\n const selected = tickets.find((ticket) => ticket.releaseId === item.id);\n return !!nextRelease && item.locked && !!selected && index + 1 == tickets.length;\n });\n return lockedSelectedReleases && lockedSelectedReleases.includes(true);\n };\n\n const countUnlockedReleases = () => activeReleases?.filter((item) => !item.locked).length || 0;\n\n const isReleaseSelected = (id: number) => !!tickets.find((ticket) => ticket.releaseId === id);\n\n const selectedTickets = async () => {\n const releases = await mutate();\n const allFilled = tickets.filter((item) => !item.releaseId || !item.quantity);\n\n const soldOutReleaseCategories = activeReleases?.filter((release) =>\n tickets.find(\n (ticket) =>\n release.id === ticket.releaseId &&\n ticket.quantity === release.availableTickets &&\n release.availableTickets !== 10\n )\n );\n\n // Unlock next releases when current release is sold out\n if (soldOutReleaseCategories?.length && activeReleases) {\n let hasChanges = false;\n const updatedReleases = activeReleases.map((release) => {\n // For each sold-out release, find and unlock the next one\n const soldOutRelease = soldOutReleaseCategories.find(\n (soldOut) =>\n soldOut.releaseCategoryName === release.releaseCategoryName &&\n soldOut.order === release.order - 1 &&\n release.locked\n );\n if (soldOutRelease) {\n hasChanges = true;\n return { ...release, locked: false };\n }\n return release;\n });\n\n if (hasChanges) {\n await mutate(updatedReleases, false);\n }\n }\n\n const hasSelectableRelease = activeReleases?.some(\n (release) => !isReleaseSelected(release.id) && !release.locked\n );\n\n const shouldAddRow =\n (soldOutReleaseCategories &&\n selectedReleaseIsSoldOut(releases) &&\n tickets.length < soldOutReleaseCategories.length + countUnlockedReleases() &&\n !allFilled.length) ||\n (activeReleases &&\n soldOutReleaseCategories?.length &&\n activeReleases?.length > tickets.length &&\n tickets.length < soldOutReleaseCategories.length + countUnlockedReleases() &&\n !allFilled.length) ||\n (tickets.length < countReleaseCategories() && !allFilled.length);\n\n const shouldRemoveEmptyRows =\n allFilled.length > 0 &&\n tickets.length > 1 &&\n !hasSelectableRelease &&\n (!soldOutReleaseCategories?.length || !selectedReleaseIsSoldOut(releases));\n\n if (shouldAddRow) {\n isProcessingRef.current = true;\n setValue(`tickets.${event.id}`, [\n ...tickets,\n {\n releaseId: '',\n quantity: '',\n itemName: '',\n price: 0,\n products: [],\n extraFields: [],\n },\n ]);\n setTimeout(() => (isProcessingRef.current = false), 0);\n } else if (shouldRemoveEmptyRows) {\n // Only remove completely empty rows (no releaseId), keep rows where user started selecting\n const nonEmptyTickets = tickets.filter((item) => item.releaseId);\n if (nonEmptyTickets.length < tickets.length) {\n isProcessingRef.current = true;\n setValue(`tickets.${event.id}`, nonEmptyTickets);\n setTimeout(() => (isProcessingRef.current = false), 0);\n }\n }\n };\n\n return (\n <Stack spacing={1} direction=\"column\">\n {!activeReleases && event.type !== EventType.RECURRING ? (\n <Skeleton\n variant=\"rounded\"\n sx={{\n width: '100%',\n height: (theme) => theme.spacing(7.5),\n }}\n />\n ) : (\n activeReleases?.map((release, index) => (\n <ReleaseWithMerchandise\n key={release.id}\n eventId={event.id}\n release={release}\n activeReleases={activeReleases}\n currency={event.currency}\n index={index}\n />\n ))\n )}\n {!activeReleases && event.type === EventType.RECURRING && (\n <Typography variant=\"h5\">{t('event.tickets.stepper.1.select_timeslot')}</Typography>\n )}\n {!!activeReleases && !activeReleases.length && (\n <Typography variant=\"h5\">{t('event.tickets.stepper.1.no_tickets')}</Typography>\n )}\n <Box>\n <Typography variant=\"caption\" component=\"div\" fontStyle=\"italic\" mb={2}>\n *{t('event.tickets.stepper.1.max_ticket_quantity')}\n </Typography>\n </Box>\n </Stack>\n );\n};\n\nexport default TicketWithMerchandiseSelection;\n"],"names":[],"mappings":";;;;;;;;;AAgBA,MAAM,8BAA8B,GAAoB,CAAC,EAAE,KAAK,EAAE,KAAI;AACpE,IAAA,MAAM,EAAE,CAAC,EAAE,GAAG,SAAS,EAAE;IACzB,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,GAAG,cAAc,EAAe;AACzD,IAAA,MAAM,OAAO,GAAwB,QAAQ,CAAC,EAAE,IAAI,EAAE,CAAA,QAAA,EAAW,KAAK,CAAC,EAAE,EAAE,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;AAChG,IAAA,MAAM,eAAe,GAAG,KAAK,CAAC,iBAAiB,CAAC;AAChD,IAAA,MAAM,eAAe,GAAG,MAAM,CAAC,KAAK,CAAC;AACrC,IAAA,MAAM,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,sBAAsB,CAC7D,KAAK,CAAC,EAAE,EACR,KAAK,EACL,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,SAAS,GAAG,eAAe,GAAG,SAAS,CACjE;IAED,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,eAAe,CAAC,OAAO;AAAE,YAAA,eAAe,EAAE;AACjD,KAAC,EAAE,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAE7B,MAAM,sBAAsB,GAAG,MAAa;QAC1C,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,EAAE,qBAAqB,CAAC;QACpE,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM;AACpC,KAAC;AAED,IAAA,MAAM,wBAAwB,GAAG,CAAC,QAAqC,KAAI;QACzE,MAAM,sBAAsB,GAA0B,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;AAClF,YAAA,MAAM,WAAW,GAAG,QAAQ,EAAE,IAAI,CAChC,CAAC,KAAK,KACJ,KAAK,CAAC,mBAAmB,KAAK,IAAI,CAAC,mBAAmB,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,GAAG,CAAC,CAC3F;AACD,YAAA,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,SAAS,KAAK,IAAI,CAAC,EAAE,CAAC;AACvE,YAAA,OAAO,CAAC,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,QAAQ,IAAI,KAAK,GAAG,CAAC,IAAI,OAAO,CAAC,MAAM;AAClF,SAAC,CAAC;QACF,OAAO,sBAAsB,IAAI,sBAAsB,CAAC,QAAQ,CAAC,IAAI,CAAC;AACxE,KAAC;IAED,MAAM,qBAAqB,GAAG,MAAM,cAAc,EAAE,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,IAAI,CAAC;IAE9F,MAAM,iBAAiB,GAAG,CAAC,EAAU,KAAK,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,SAAS,KAAK,EAAE,CAAC;AAE7F,IAAA,MAAM,eAAe,GAAG,YAAW;AACjC,QAAA,MAAM,QAAQ,GAAG,MAAM,MAAM,EAAE;QAC/B,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;QAE7E,MAAM,wBAAwB,GAAG,cAAc,EAAE,MAAM,CAAC,CAAC,OAAO,KAC9D,OAAO,CAAC,IAAI,CACV,CAAC,MAAM,KACL,OAAO,CAAC,EAAE,KAAK,MAAM,CAAC,SAAS;AAC/B,YAAA,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,gBAAgB;AAC5C,YAAA,OAAO,CAAC,gBAAgB,KAAK,EAAE,CAClC,CACF;;AAGD,QAAA,IAAI,wBAAwB,EAAE,MAAM,IAAI,cAAc,EAAE;YACtD,IAAI,UAAU,GAAG,KAAK;YACtB,MAAM,eAAe,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC,OAAO,KAAI;;AAErD,gBAAA,MAAM,cAAc,GAAG,wBAAwB,CAAC,IAAI,CAClD,CAAC,OAAO,KACN,OAAO,CAAC,mBAAmB,KAAK,OAAO,CAAC,mBAAmB;AAC3D,oBAAA,OAAO,CAAC,KAAK,KAAK,OAAO,CAAC,KAAK,GAAG,CAAC;oBACnC,OAAO,CAAC,MAAM,CACjB;gBACD,IAAI,cAAc,EAAE;oBAClB,UAAU,GAAG,IAAI;oBACjB,OAAO,EAAE,GAAG,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE;;AAEtC,gBAAA,OAAO,OAAO;AAChB,aAAC,CAAC;YAEF,IAAI,UAAU,EAAE;AACd,gBAAA,MAAM,MAAM,CAAC,eAAe,EAAE,KAAK,CAAC;;;QAIxC,MAAM,oBAAoB,GAAG,cAAc,EAAE,IAAI,CAC/C,CAAC,OAAO,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAC/D;QAED,MAAM,YAAY,GAChB,CAAC,wBAAwB;YACvB,wBAAwB,CAAC,QAAQ,CAAC;YAClC,OAAO,CAAC,MAAM,GAAG,wBAAwB,CAAC,MAAM,GAAG,qBAAqB,EAAE;YAC1E,CAAC,SAAS,CAAC,MAAM;AACnB,aAAC,cAAc;AACb,gBAAA,wBAAwB,EAAE,MAAM;AAChC,gBAAA,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM;gBACvC,OAAO,CAAC,MAAM,GAAG,wBAAwB,CAAC,MAAM,GAAG,qBAAqB,EAAE;gBAC1E,CAAC,SAAS,CAAC,MAAM,CAAC;AACpB,aAAC,OAAO,CAAC,MAAM,GAAG,sBAAsB,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;AAElE,QAAA,MAAM,qBAAqB,GACzB,SAAS,CAAC,MAAM,GAAG,CAAC;YACpB,OAAO,CAAC,MAAM,GAAG,CAAC;AAClB,YAAA,CAAC,oBAAoB;aACpB,CAAC,wBAAwB,EAAE,MAAM,IAAI,CAAC,wBAAwB,CAAC,QAAQ,CAAC,CAAC;QAE5E,IAAI,YAAY,EAAE;AAChB,YAAA,eAAe,CAAC,OAAO,GAAG,IAAI;AAC9B,YAAA,QAAQ,CAAC,CAAA,QAAA,EAAW,KAAK,CAAC,EAAE,EAAE,EAAE;AAC9B,gBAAA,GAAG,OAAO;AACV,gBAAA;AACE,oBAAA,SAAS,EAAE,EAAE;AACb,oBAAA,QAAQ,EAAE,EAAE;AACZ,oBAAA,QAAQ,EAAE,EAAE;AACZ,oBAAA,KAAK,EAAE,CAAC;AACR,oBAAA,QAAQ,EAAE,EAAE;AACZ,oBAAA,WAAW,EAAE,EAAE;AAChB,iBAAA;AACF,aAAA,CAAC;AACF,YAAA,UAAU,CAAC,OAAO,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;;aACjD,IAAI,qBAAqB,EAAE;;AAEhC,YAAA,MAAM,eAAe,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC;YAChE,IAAI,eAAe,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE;AAC3C,gBAAA,eAAe,CAAC,OAAO,GAAG,IAAI;gBAC9B,QAAQ,CAAC,WAAW,KAAK,CAAC,EAAE,CAAA,CAAE,EAAE,eAAe,CAAC;AAChD,gBAAA,UAAU,CAAC,OAAO,eAAe,CAAC,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC,CAAC;;;AAG5D,KAAC;IAED,QACE,KAAA,CAAA,aAAA,CAAC,KAAK,EAAA,EAAC,OAAO,EAAE,CAAC,EAAE,SAAS,EAAC,QAAQ,EAAA;QAClC,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,SAAS,IACpD,oBAAC,QAAQ,EAAA,EACP,OAAO,EAAC,SAAS,EACjB,EAAE,EAAE;AACF,gBAAA,KAAK,EAAE,MAAM;gBACb,MAAM,EAAE,CAAC,KAAK,KAAK,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC;aACtC,EAAA,CACD,KAEF,cAAc,EAAE,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,MACjC,KAAA,CAAA,aAAA,CAAC,sBAAsB,IACrB,GAAG,EAAE,OAAO,CAAC,EAAE,EACf,OAAO,EAAE,KAAK,CAAC,EAAE,EACjB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,QAAQ,EAAE,KAAK,CAAC,QAAQ,EACxB,KAAK,EAAE,KAAK,EAAA,CACZ,CACH,CAAC,CACH;QACA,CAAC,cAAc,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,CAAC,SAAS,KACpD,oBAAC,UAAU,EAAA,EAAC,OAAO,EAAC,IAAI,EAAA,EAAE,CAAC,CAAC,yCAAyC,CAAC,CAAc,CACrF;QACA,CAAC,CAAC,cAAc,IAAI,CAAC,cAAc,CAAC,MAAM,KACzC,KAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAC,OAAO,EAAC,IAAI,EAAA,EAAE,CAAC,CAAC,oCAAoC,CAAC,CAAc,CAChF;AACD,QAAA,KAAA,CAAA,aAAA,CAAC,GAAG,EAAA,IAAA;AACF,YAAA,KAAA,CAAA,aAAA,CAAC,UAAU,EAAA,EAAC,OAAO,EAAC,SAAS,EAAC,SAAS,EAAC,KAAK,EAAC,SAAS,EAAC,QAAQ,EAAC,EAAE,EAAE,CAAC,EAAA;;AAClE,gBAAA,CAAC,CAAC,6CAA6C,CAAC,CACvC,CACT,CACA;AAEZ;;;;"}
1
+ {"version":3,"file":"TicketWithMerchandiseSelection.js","sources":["../../../../src/form/tickets/TicketWithMerchandiseSelection.tsx"],"sourcesContent":["import React, { useEffect, useRef } from 'react';\nimport { useFormContext, useWatch } from 'react-hook-form';\nimport { Box, Skeleton, Stack, Typography } from '@mui/material';\nimport { ITicketForm, ITicketFormTicket } from '@utils/types/ticket.type';\nimport useEventActiveReleases from '@hooks/data/useEventActiveReleases';\nimport { groupBy } from '@utils/global';\nimport { IReleaseShort } from '@utils/types/release.type';\nimport { IEvent } from '@utils/types/event.type';\nimport ReleaseWithMerchandise from '@form/tickets/ReleaseWithMerchandise';\nimport { EventType } from '@utils/data/event';\nimport { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';\nimport useGlobal from '@hooks/useGlobal.ts';\n\ninterface Props {\n event: IEvent;\n}\n\nconst TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {\n const { t } = useGlobal();\n const { setValue, watch } = useFormContext<ITicketForm>();\n const tickets: ITicketFormTicket[] = useWatch({ name: `tickets.${event.id}`, defaultValue: [] });\n const eventTimeslotId = watch('eventTimeslotId');\n const isProcessingRef = useRef(false);\n const { data: activeReleases, mutate } = useEventActiveReleases(\n event.id,\n false,\n event.type === EventType.RECURRING ? eventTimeslotId : undefined\n );\n\n useEffect(() => {\n if (!isProcessingRef.current) selectedTickets();\n }, [tickets, activeReleases]);\n\n const countReleaseCategories = (): number => {\n const grouped = groupBy(activeReleases || [], 'releaseCategoryName');\n return Object.keys(grouped).length;\n };\n\n const selectedReleaseIsSoldOut = (releases: IReleaseShort[] | undefined) => {\n const lockedSelectedReleases: boolean[] | undefined = releases?.map((item, index) => {\n const nextRelease = releases?.find(\n (item2) =>\n item2.releaseCategoryName === item.releaseCategoryName && item2.order === item.order + 1\n );\n const selected = tickets.find((ticket) => ticket.releaseId === item.id);\n const maxSelectable = Math.min(item.availableTickets || 0, MAX_TICKETS_PER_ORDER);\n\n return (\n !!nextRelease &&\n item.locked &&\n !!selected &&\n Number(selected.quantity) >= maxSelectable &&\n index + 1 == tickets.length\n );\n });\n return lockedSelectedReleases && lockedSelectedReleases.includes(true);\n };\n\n const countUnlockedReleases = () => activeReleases?.filter((item) => !item.locked).length || 0;\n\n const isReleaseSelected = (id: number) => !!tickets.find((ticket) => ticket.releaseId === id);\n\n const selectedTickets = async () => {\n const releases = await mutate();\n const currentReleases = releases || activeReleases || [];\n const allFilled = tickets.filter((item) => !item.releaseId || !item.quantity);\n\n const soldOutReleaseCategories = currentReleases.filter((release) =>\n tickets.find(\n (ticket) =>\n release.id === ticket.releaseId &&\n Number(ticket.quantity) >= Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER)\n )\n );\n\n // Unlock next releases when current release is sold out\n if (currentReleases.length) {\n let hasChanges = false;\n const updatedReleases = currentReleases.map((release) => {\n const previousRelease = currentReleases.find(\n (item) =>\n item.releaseCategoryName === release.releaseCategoryName &&\n item.order === release.order - 1\n );\n\n if (!release.locked || !previousRelease) return release;\n\n const previousTicket = tickets.find((ticket) => ticket.releaseId === previousRelease.id);\n const previousMaxSelectable = Math.min(\n previousRelease.availableTickets || 0,\n MAX_TICKETS_PER_ORDER\n );\n const shouldUnlock = Number(previousTicket?.quantity || 0) >= previousMaxSelectable;\n\n if (!shouldUnlock) return release;\n\n hasChanges = true;\n return { ...release, locked: false };\n });\n\n if (hasChanges) {\n await mutate(updatedReleases, false);\n }\n }\n\n const hasSelectableRelease = currentReleases.some(\n (release) => !isReleaseSelected(release.id) && !release.locked\n );\n\n const shouldAddRow =\n (soldOutReleaseCategories &&\n selectedReleaseIsSoldOut(releases) &&\n tickets.length < soldOutReleaseCategories.length + countUnlockedReleases() &&\n !allFilled.length) ||\n (currentReleases.length &&\n soldOutReleaseCategories.length &&\n currentReleases.length > tickets.length &&\n tickets.length < soldOutReleaseCategories.length + countUnlockedReleases() &&\n !allFilled.length) ||\n (tickets.length < countReleaseCategories() && !allFilled.length);\n\n const shouldRemoveEmptyRows =\n allFilled.length > 0 &&\n tickets.length > 1 &&\n !hasSelectableRelease &&\n (!soldOutReleaseCategories?.length || !selectedReleaseIsSoldOut(releases));\n\n if (shouldAddRow) {\n isProcessingRef.current = true;\n setValue(`tickets.${event.id}`, [\n ...tickets,\n {\n releaseId: '',\n quantity: '',\n itemName: '',\n price: 0,\n products: [],\n extraFields: [],\n },\n ]);\n setTimeout(() => (isProcessingRef.current = false), 0);\n } else if (shouldRemoveEmptyRows) {\n // Only remove completely empty rows (no releaseId), keep rows where user started selecting\n const nonEmptyTickets = tickets.filter((item) => item.releaseId);\n if (nonEmptyTickets.length < tickets.length) {\n isProcessingRef.current = true;\n setValue(`tickets.${event.id}`, nonEmptyTickets);\n setTimeout(() => (isProcessingRef.current = false), 0);\n }\n }\n };\n\n return (\n <Stack spacing={1} direction=\"column\">\n {!activeReleases && event.type !== EventType.RECURRING ? (\n <Skeleton\n variant=\"rounded\"\n sx={{\n width: '100%',\n height: (theme) => theme.spacing(7.5),\n }}\n />\n ) : (\n activeReleases\n ?.filter((release) => !release.locked || isReleaseSelected(release.id))\n .map((release, index) => (\n <ReleaseWithMerchandise\n key={release.id}\n eventId={event.id}\n release={release}\n activeReleases={activeReleases}\n currency={event.currency}\n index={index}\n />\n ))\n )}\n {!activeReleases && event.type === EventType.RECURRING && (\n <Typography variant=\"h5\">{t('event.tickets.stepper.1.select_timeslot')}</Typography>\n )}\n {!!activeReleases && !activeReleases.length && (\n <Typography variant=\"h5\">{t('event.tickets.stepper.1.no_tickets')}</Typography>\n )}\n <Box>\n <Typography variant=\"caption\" component=\"div\" fontStyle=\"italic\" mb={2}>\n *{t('event.tickets.stepper.1.max_ticket_quantity')}\n </Typography>\n </Box>\n </Stack>\n );\n};\n\nexport default TicketWithMerchandiseSelection;\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ function useConsentScrollOnDrawerOpen({ isDrawerOpen, consentRef, }) {
4
+ const [isNearConsentSection, setIsNearConsentSection] = useState(false);
5
+ useEffect(() => {
6
+ const consentElement = consentRef.current;
7
+ if (!consentElement) {
8
+ return;
9
+ }
10
+ if (!('IntersectionObserver' in window)) {
11
+ setIsNearConsentSection(true);
12
+ return;
13
+ }
14
+ const observer = new IntersectionObserver((entries) => {
15
+ const entry = entries[0];
16
+ setIsNearConsentSection(entry.isIntersecting);
17
+ }, {
18
+ root: null,
19
+ threshold: 0,
20
+ rootMargin: '0px 0px 140px 0px',
21
+ });
22
+ observer.observe(consentElement);
23
+ return () => {
24
+ observer.disconnect();
25
+ };
26
+ }, [consentRef]);
27
+ useEffect(() => {
28
+ if (!isDrawerOpen) {
29
+ return;
30
+ }
31
+ if (window.matchMedia('(min-width:900px)').matches) {
32
+ return;
33
+ }
34
+ if (!isNearConsentSection) {
35
+ return;
36
+ }
37
+ let frameId = 0;
38
+ let frameId2 = 0;
39
+ frameId = window.requestAnimationFrame(() => {
40
+ frameId2 = window.requestAnimationFrame(() => {
41
+ consentRef.current?.scrollIntoView({
42
+ behavior: 'smooth',
43
+ block: 'center',
44
+ });
45
+ });
46
+ });
47
+ return () => {
48
+ window.cancelAnimationFrame(frameId);
49
+ window.cancelAnimationFrame(frameId2);
50
+ };
51
+ }, [consentRef, isDrawerOpen, isNearConsentSection]);
52
+ }
53
+
54
+ export { useConsentScrollOnDrawerOpen as default };
55
+ //# sourceMappingURL=useConsentScrollOnDrawerOpen.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useConsentScrollOnDrawerOpen.js","sources":["../../../src/hooks/useConsentScrollOnDrawerOpen.ts"],"sourcesContent":["import { RefObject, useEffect, useState } from 'react';\n\ninterface UseConsentScrollOnDrawerOpenProps {\n isDrawerOpen: boolean;\n consentRef: RefObject<HTMLElement | null>;\n}\n\nexport default function useConsentScrollOnDrawerOpen({\n isDrawerOpen,\n consentRef,\n}: UseConsentScrollOnDrawerOpenProps) {\n const [isNearConsentSection, setIsNearConsentSection] = useState(false);\n\n useEffect(() => {\n const consentElement = consentRef.current;\n if (!consentElement) {\n return;\n }\n\n if (!('IntersectionObserver' in window)) {\n setIsNearConsentSection(true);\n return;\n }\n\n const observer = new IntersectionObserver(\n (entries) => {\n const entry = entries[0];\n setIsNearConsentSection(entry.isIntersecting);\n },\n {\n root: null,\n threshold: 0,\n rootMargin: '0px 0px 140px 0px',\n }\n );\n\n observer.observe(consentElement);\n\n return () => {\n observer.disconnect();\n };\n }, [consentRef]);\n\n useEffect(() => {\n if (!isDrawerOpen) {\n return;\n }\n\n if (window.matchMedia('(min-width:900px)').matches) {\n return;\n }\n\n if (!isNearConsentSection) {\n return;\n }\n\n let frameId = 0;\n let frameId2 = 0;\n frameId = window.requestAnimationFrame(() => {\n frameId2 = window.requestAnimationFrame(() => {\n consentRef.current?.scrollIntoView({\n behavior: 'smooth',\n block: 'center',\n });\n });\n });\n\n return () => {\n window.cancelAnimationFrame(frameId);\n window.cancelAnimationFrame(frameId2);\n };\n }, [consentRef, isDrawerOpen, isNearConsentSection]);\n}\n"],"names":[],"mappings":";;AAOc,SAAU,4BAA4B,CAAC,EACnD,YAAY,EACZ,UAAU,GACwB,EAAA;IAClC,MAAM,CAAC,oBAAoB,EAAE,uBAAuB,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IAEvE,SAAS,CAAC,MAAK;AACb,QAAA,MAAM,cAAc,GAAG,UAAU,CAAC,OAAO;QACzC,IAAI,CAAC,cAAc,EAAE;YACnB;;AAGF,QAAA,IAAI,EAAE,sBAAsB,IAAI,MAAM,CAAC,EAAE;YACvC,uBAAuB,CAAC,IAAI,CAAC;YAC7B;;QAGF,MAAM,QAAQ,GAAG,IAAI,oBAAoB,CACvC,CAAC,OAAO,KAAI;AACV,YAAA,MAAM,KAAK,GAAG,OAAO,CAAC,CAAC,CAAC;AACxB,YAAA,uBAAuB,CAAC,KAAK,CAAC,cAAc,CAAC;AAC/C,SAAC,EACD;AACE,YAAA,IAAI,EAAE,IAAI;AACV,YAAA,SAAS,EAAE,CAAC;AACZ,YAAA,UAAU,EAAE,mBAAmB;AAChC,SAAA,CACF;AAED,QAAA,QAAQ,CAAC,OAAO,CAAC,cAAc,CAAC;AAEhC,QAAA,OAAO,MAAK;YACV,QAAQ,CAAC,UAAU,EAAE;AACvB,SAAC;AACH,KAAC,EAAE,CAAC,UAAU,CAAC,CAAC;IAEhB,SAAS,CAAC,MAAK;QACb,IAAI,CAAC,YAAY,EAAE;YACjB;;QAGF,IAAI,MAAM,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,OAAO,EAAE;YAClD;;QAGF,IAAI,CAAC,oBAAoB,EAAE;YACzB;;QAGF,IAAI,OAAO,GAAG,CAAC;QACf,IAAI,QAAQ,GAAG,CAAC;AAChB,QAAA,OAAO,GAAG,MAAM,CAAC,qBAAqB,CAAC,MAAK;AAC1C,YAAA,QAAQ,GAAG,MAAM,CAAC,qBAAqB,CAAC,MAAK;AAC3C,gBAAA,UAAU,CAAC,OAAO,EAAE,cAAc,CAAC;AACjC,oBAAA,QAAQ,EAAE,QAAQ;AAClB,oBAAA,KAAK,EAAE,QAAQ;AAChB,iBAAA,CAAC;AACJ,aAAC,CAAC;AACJ,SAAC,CAAC;AAEF,QAAA,OAAO,MAAK;AACV,YAAA,MAAM,CAAC,oBAAoB,CAAC,OAAO,CAAC;AACpC,YAAA,MAAM,CAAC,oBAAoB,CAAC,QAAQ,CAAC;AACvC,SAAC;KACF,EAAE,CAAC,UAAU,EAAE,YAAY,EAAE,oBAAoB,CAAC,CAAC;AACtD;;;;"}
@@ -0,0 +1,4 @@
1
+ const MAX_TICKETS_PER_ORDER = 10;
2
+
3
+ export { MAX_TICKETS_PER_ORDER };
4
+ //# sourceMappingURL=ticket.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ticket.js","sources":["../../../../src/utils/data/ticket.ts"],"sourcesContent":["export const MAX_TICKETS_PER_ORDER = 10;\n"],"names":[],"mappings":"AAAO,MAAM,qBAAqB,GAAG;;;;"}
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ import { IEvent } from '@utils/types/event.type';
3
+ interface Props {
4
+ event: IEvent;
5
+ totalPrice: number;
6
+ }
7
+ declare const PaymentOverviewDrawer: React.FC<Props>;
8
+ export default PaymentOverviewDrawer;
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { IEventProduct } from '@utils/types/event-product.type';
3
+ interface Props {
4
+ eventProducts: IEventProduct[];
5
+ eventId: number;
6
+ isLoading?: boolean;
7
+ }
8
+ declare const MerchandiseSelection: React.FC<Props>;
9
+ export default MerchandiseSelection;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { SxProps } from '@mui/material';
3
+ import { IEventProduct } from '@utils/types/event-product.type';
4
+ interface Props {
5
+ sx?: SxProps;
6
+ eventProducts: IEventProduct[];
7
+ eventId: number;
8
+ }
9
+ declare const MerchandiseSlider: React.FC<Props>;
10
+ export default MerchandiseSlider;
@@ -108,11 +108,7 @@ declare const cs: {
108
108
  label: string;
109
109
  per_ticket: string;
110
110
  modal: {
111
- description: string[];
112
- links: {
113
- insurance: string;
114
- info: string;
115
- };
111
+ description: string;
116
112
  coverage: string;
117
113
  price: string;
118
114
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventlook/sdk",
3
- "version": "1.4.50",
3
+ "version": "1.4.51",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -696,12 +696,14 @@ const TicketForm: React.FC<Props> = ({
696
696
  </Grid>
697
697
  </Grid>
698
698
 
699
- <PaymentOverviewDrawer
700
- event={event}
701
- totalPrice={values.total}
702
- termsAndConditionsRef={termsAndConditionsRef}
703
- onOpenChange={setIsPaymentOverviewDrawerOpen}
704
- />
699
+ {!isIframe && (
700
+ <PaymentOverviewDrawer
701
+ event={event}
702
+ totalPrice={values.total}
703
+ termsAndConditionsRef={termsAndConditionsRef}
704
+ onOpenChange={setIsPaymentOverviewDrawerOpen}
705
+ />
706
+ )}
705
707
 
706
708
  <EmailConfirmation
707
709
  open={formStep === 2 && !isIframe}
@@ -22,6 +22,7 @@ import { ITicketForm, ITicketFormTicket } from '@utils/types/ticket.type';
22
22
  import { getSelectedQuantityByVariant } from '@utils/product';
23
23
  import useGlobal from '@hooks/useGlobal.ts';
24
24
  import { fCurrency } from '@utils/formatNumber';
25
+ import { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';
25
26
 
26
27
  interface Props {
27
28
  eventProduct: IEventProduct;
@@ -100,7 +101,7 @@ const ProductCard: React.FC<Props> = ({ eventProduct, eventId, isOnlyMerchandise
100
101
 
101
102
  const onChangeSimpleProductQuantity = (nextQuantity: number) => {
102
103
  if (!simpleVariant) return;
103
- if (nextQuantity < 0 || nextQuantity > 10) return;
104
+ if (nextQuantity < 0 || nextQuantity > MAX_TICKETS_PER_ORDER) return;
104
105
  if (
105
106
  nextQuantity > simpleProductQuantity &&
106
107
  nextQuantity - simpleProductQuantity > simpleProductMaxAvailable
@@ -153,7 +154,9 @@ const ProductCard: React.FC<Props> = ({ eventProduct, eventId, isOnlyMerchandise
153
154
  </Box>
154
155
  <IconButton
155
156
  onClick={() => onChangeSimpleProductQuantity(simpleProductQuantity + 1)}
156
- disabled={simpleProductQuantity >= 10 || simpleProductMaxAvailable <= 0}
157
+ disabled={
158
+ simpleProductQuantity >= MAX_TICKETS_PER_ORDER || simpleProductMaxAvailable <= 0
159
+ }
157
160
  sx={{
158
161
  flex: '1 1 0',
159
162
  height: 36,
@@ -15,6 +15,7 @@ import { useWatch } from 'react-hook-form';
15
15
  import { ITicketFormTicket } from '@utils/types/ticket.type';
16
16
  import { IEventProductForm } from '@utils/types/product.type';
17
17
  import { fCurrency } from '@utils/formatNumber';
18
+ import { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';
18
19
  import useGlobal from '@hooks/useGlobal.ts';
19
20
 
20
21
  interface Props {
@@ -26,6 +27,7 @@ interface Props {
26
27
  selectedQuantityByVariant?: Record<number, number>;
27
28
  isOnlyMerchandise?: boolean;
28
29
  canAddOnlyOneAtATime?: boolean;
30
+ maxSelectableQuantity?: number;
29
31
  }
30
32
 
31
33
  const ProductVariantsDialog: React.FC<Props> = ({
@@ -37,6 +39,7 @@ const ProductVariantsDialog: React.FC<Props> = ({
37
39
  isOnlyMerchandise,
38
40
  eventId,
39
41
  canAddOnlyOneAtATime,
42
+ maxSelectableQuantity,
40
43
  }) => {
41
44
  const { t, lang, options } = useGlobal();
42
45
  const { showSnackbar } = useGlobal();
@@ -53,8 +56,14 @@ const ProductVariantsDialog: React.FC<Props> = ({
53
56
  }, [openDialog]);
54
57
 
55
58
  useEffect(() => {
56
- if (openDialog) {
57
- setDraftQuantities(canAddOnlyOneAtATime ? {} : (selectedQuantityByVariant ?? {}));
59
+ if (openDialog && canAddOnlyOneAtATime) {
60
+ setDraftQuantities({});
61
+ }
62
+ }, [openDialog, canAddOnlyOneAtATime]);
63
+
64
+ useEffect(() => {
65
+ if (openDialog && !canAddOnlyOneAtATime) {
66
+ setDraftQuantities(selectedQuantityByVariant ?? {});
58
67
  }
59
68
  }, [openDialog, selectedQuantityByVariant, canAddOnlyOneAtATime]);
60
69
 
@@ -126,11 +135,18 @@ const ProductVariantsDialog: React.FC<Props> = ({
126
135
  const current = prev[variant.id] ?? 0;
127
136
  const next = current + 1;
128
137
  const maxAvailable = getMaxAvailable(variant);
129
- if (next > 10 || next > maxAvailable) return prev;
138
+
130
139
  if (canAddOnlyOneAtATime) {
131
- // Only allow one variant to be selected
140
+ if (maxAvailable < 1) return prev;
132
141
  return { [variant.id]: 1 };
133
142
  }
143
+
144
+ const maxSelectable =
145
+ maxSelectableQuantity === undefined
146
+ ? MAX_TICKETS_PER_ORDER
147
+ : Math.max(0, Math.min(maxSelectableQuantity, MAX_TICKETS_PER_ORDER));
148
+
149
+ if (next > maxSelectable || next > maxAvailable) return prev;
134
150
  return { ...prev, [variant.id]: next };
135
151
  });
136
152
  };
@@ -248,7 +264,14 @@ const ProductVariantsDialog: React.FC<Props> = ({
248
264
  {eventProduct.eventProductVariants.map((variant) => {
249
265
  const draftQty = draftQuantities[variant.id] ?? 0;
250
266
  const maxAvailable = getMaxAvailable(variant);
251
- const isAddDisabled = isVariantDisabled(variant) || maxAvailable <= 0;
267
+ const maxSelectable =
268
+ maxSelectableQuantity === undefined
269
+ ? MAX_TICKETS_PER_ORDER
270
+ : Math.max(0, Math.min(maxSelectableQuantity, MAX_TICKETS_PER_ORDER));
271
+ const isAddDisabled =
272
+ isVariantDisabled(variant) ||
273
+ maxAvailable <= 0 ||
274
+ (!canAddOnlyOneAtATime && maxSelectable <= 0);
252
275
  const isAnotherSelected =
253
276
  canAddOnlyOneAtATime &&
254
277
  Object.keys(draftQuantities).length > 0 &&
@@ -330,7 +353,7 @@ const ProductVariantsDialog: React.FC<Props> = ({
330
353
  variant="contained"
331
354
  onClick={() => handleAddQuantity(variant)}
332
355
  aria-label={t('components.product_variant_dialog.increase_quantity')}
333
- disabled={draftQty >= 10 || draftQty >= maxAvailable}
356
+ disabled={draftQty >= maxSelectable || draftQty >= maxAvailable}
334
357
  sx={{ minWidth: 0, height: 36, borderRadius: 1, fontWeight: 700 }}
335
358
  >
336
359
  +