@eventlook/sdk 1.7.2-beta.0 → 1.7.3

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.
@@ -1 +1,2 @@
1
1
  export declare const MAX_TICKETS_PER_ORDER = 10;
2
+ export declare const getMaxTicketsPerOrder: (eventId?: number) => number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eventlook/sdk",
3
- "version": "1.7.2-beta.0",
3
+ "version": "1.7.3",
4
4
  "main": "dist/cjs/index.js",
5
5
  "module": "dist/esm/index.js",
6
6
  "types": "dist/types/index.d.ts",
@@ -22,7 +22,7 @@
22
22
  "watch:push": "chokidar 'dist/**/*' -c 'yalc push --changed --force'",
23
23
  "dev": "concurrently --kill-others-on-fail --kill-others \"yarn watch:rollup\" \"yarn watch:types\" \"yarn watch:push\"",
24
24
  "dev:simple": "concurrently --kill-others-on-fail \"yarn watch:rollup\" \"yarn watch:types\"",
25
- "publish": "npm publish",
25
+ "release": "npm publish",
26
26
  "lint": "eslint .",
27
27
  "lint:fix": "eslint --fix .",
28
28
  "prettier": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'",
@@ -40,31 +40,34 @@ const ChildEventCard: React.FC<Props> = ({ event }) => {
40
40
  return (
41
41
  <>
42
42
  <Card sx={{ p: 2 }}>
43
- <Grid container spacing={6} alignItems="stretch">
44
- {/* LEFT SIDE: Image + Button */}
45
- <Grid size={{ xs: 12, md: 6 }} sx={{ display: 'flex', flexDirection: 'column' }}>
46
- <Image src={event.image.url} alt={event.name} ratio="16/9" borderRadius={2} />
47
- <Button
48
- variant="contained"
49
- onClick={() => setOpenVariantDialog(true)}
50
- fullWidth
51
- startIcon={
52
- eventNotEmpty ? <Iconify icon="eva:edit-fill" /> : <Iconify icon="eva:plus-fill" />
53
- }
54
- sx={{ mt: 2 }}
55
- >
56
- {eventNotEmpty ? t('change') : t('add')}
57
- </Button>
58
- </Grid>
59
-
60
- {/* RIGHT SIDE: Info block with bottom aligned date + organizer */}
61
- <Grid
62
- size={{ xs: 12, md: 6 }}
63
- sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}
64
- >
65
- <Stack spacing={2}>
66
- <Typography variant="h6">{event.name}</Typography>
43
+ <Stack spacing={2}>
44
+ <Typography variant="h6">{event.name}</Typography>
45
+ <Grid container spacing={6} alignItems="stretch">
46
+ {/* LEFT SIDE: Image + Button */}
47
+ <Grid size={{ xs: 12, md: 6 }} sx={{ display: 'flex', flexDirection: 'column' }}>
48
+ <Image src={event.image.url} alt={event.name} ratio="16/9" borderRadius={2} />
49
+ <Button
50
+ variant="contained"
51
+ onClick={() => setOpenVariantDialog(true)}
52
+ fullWidth
53
+ startIcon={
54
+ eventNotEmpty ? (
55
+ <Iconify icon="eva:edit-fill" />
56
+ ) : (
57
+ <Iconify icon="eva:plus-fill" />
58
+ )
59
+ }
60
+ sx={{ mt: 2 }}
61
+ >
62
+ {eventNotEmpty ? t('change') : t('add')}
63
+ </Button>
64
+ </Grid>
67
65
 
66
+ {/* RIGHT SIDE: Info block with bottom aligned date + organizer */}
67
+ <Grid
68
+ size={{ xs: 12, md: 6 }}
69
+ sx={{ display: 'flex', flexDirection: 'column', justifyContent: 'space-between' }}
70
+ >
68
71
  <TextIconLabel
69
72
  icon={
70
73
  <Iconify
@@ -75,48 +78,51 @@ const ChildEventCard: React.FC<Props> = ({ event }) => {
75
78
  value={<Box>{getPlaceAsString(event.place)}</Box>}
76
79
  sx={{ typography: 'body3', color: 'text.secondary', alignItems: 'flex-start' }}
77
80
  />
78
- </Stack>
79
81
 
80
- {/* Bottom: Date & Organizer */}
81
- <Stack
82
- direction={{ xs: 'column', sm: 'row', md: 'column', lg: 'row' }}
83
- spacing={2}
84
- p={2}
85
- divider={
86
- <Divider
87
- orientation={xs || md ? 'horizontal' : 'vertical'}
88
- flexItem
89
- sx={{ borderStyle: 'dashed' }}
90
- />
91
- }
92
- sx={{
93
- backgroundColor: (theme) => theme.palette.grey.A100,
94
- borderRadius: 1,
95
- }}
96
- >
97
- <Box width={{ sm: '50%', md: '100%', lg: '50%' }}>
98
- <TextIconLabel
99
- icon={<Iconify icon={calendarIcon} sx={{ minWidth: 20, height: 20, mr: 1 }} />}
100
- value={t('form.labels.start_date')}
101
- sx={{ color: 'text.secondary' }}
102
- />
103
- <Typography variant="body2" fontWeight={700}>
104
- {dayjs(event.startDate).format('DD.MM.YYYY HH:mm')}
105
- </Typography>
106
- </Box>
107
- <Box width={{ sm: '50%', md: '100%', lg: '50%' }}>
108
- <TextIconLabel
109
- icon={<Iconify icon={userIcon} sx={{ minWidth: 20, height: 20, mr: 1 }} />}
110
- value={t('form.labels.organizer')}
111
- sx={{ color: 'text.secondary' }}
112
- />
113
- <Typography variant="body2" fontWeight={700}>
114
- {event.company.displayName}
115
- </Typography>
116
- </Box>
117
- </Stack>
82
+ {/* Bottom: Date & Organizer */}
83
+ <Stack
84
+ direction={{ xs: 'column', sm: 'row', md: 'column', lg: 'row' }}
85
+ spacing={2}
86
+ p={2}
87
+ divider={
88
+ <Divider
89
+ orientation={xs || md ? 'horizontal' : 'vertical'}
90
+ flexItem
91
+ sx={{ borderStyle: 'dashed' }}
92
+ />
93
+ }
94
+ sx={{
95
+ backgroundColor: (theme) =>
96
+ theme.palette.mode === 'light'
97
+ ? theme.palette.grey[100]
98
+ : theme.palette.grey[900],
99
+ borderRadius: 1,
100
+ }}
101
+ >
102
+ <Box width={{ sm: '50%', md: '100%', lg: '50%' }}>
103
+ <TextIconLabel
104
+ icon={<Iconify icon={calendarIcon} sx={{ minWidth: 20, height: 20, mr: 1 }} />}
105
+ value={t('form.labels.start_date')}
106
+ sx={{ color: 'text.secondary' }}
107
+ />
108
+ <Typography variant="body2" fontWeight={700}>
109
+ {dayjs(event.startDate).format('DD.MM.YYYY HH:mm')}
110
+ </Typography>
111
+ </Box>
112
+ <Box width={{ sm: '50%', md: '100%', lg: '50%' }}>
113
+ <TextIconLabel
114
+ icon={<Iconify icon={userIcon} sx={{ minWidth: 20, height: 20, mr: 1 }} />}
115
+ value={t('form.labels.organizer')}
116
+ sx={{ color: 'text.secondary' }}
117
+ />
118
+ <Typography variant="body2" fontWeight={700}>
119
+ {event.company.displayName}
120
+ </Typography>
121
+ </Box>
122
+ </Stack>
123
+ </Grid>
118
124
  </Grid>
119
- </Grid>
125
+ </Stack>
120
126
  </Card>
121
127
 
122
128
  <ChildEventDialog
@@ -9,7 +9,7 @@ import { useFormContext, useWatch } from 'react-hook-form';
9
9
  import { IEventProductForm } from '@utils/types/product.type';
10
10
  import { fCurrency } from '@utils/formatNumber';
11
11
  import { Currencies } from '@utils/data/currency';
12
- import { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';
12
+ import { getMaxTicketsPerOrder } from '@utils/data/ticket';
13
13
  import { getSelectedQuantityByVariant } from '@utils/product';
14
14
  import ReleaseExtraFields from '@form/extra-field/ReleaseExtraFields';
15
15
  import ReleaseDescription from '@form/tickets/ReleaseDescription';
@@ -32,6 +32,7 @@ const ReleaseWithMerchandise: React.FC<Props> = ({
32
32
  index,
33
33
  }) => {
34
34
  const { t, lang } = useGlobal();
35
+ const maxTicketsPerOrder = getMaxTicketsPerOrder(eventId);
35
36
  const [openVariantDialog, setOpenVariantDialog] = useState<'add' | 'increase' | null>(null);
36
37
  const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false);
37
38
  const [primaryDialogMode, setPrimaryDialogMode] = useState<'add' | 'increase' | null>(null);
@@ -60,7 +61,7 @@ const ReleaseWithMerchandise: React.FC<Props> = ({
60
61
  const getAvailableTicketsForRelease = (release: ITicketFormTicket): number => {
61
62
  const selectedRelease = activeReleases?.find((item) => item.id === release.releaseId);
62
63
  const availableQuantity = selectedRelease ? selectedRelease.availableTickets : 0;
63
- return availableQuantity > MAX_TICKETS_PER_ORDER ? MAX_TICKETS_PER_ORDER : availableQuantity;
64
+ return availableQuantity > maxTicketsPerOrder ? maxTicketsPerOrder : availableQuantity;
64
65
  };
65
66
 
66
67
  const isMaxQuantity = (releaseId: number) => {
@@ -79,8 +80,8 @@ const ReleaseWithMerchandise: React.FC<Props> = ({
79
80
  ? [productsToAdd]
80
81
  : [];
81
82
  const requestedQuantity = normalizedProducts.length ? normalizedProducts.length : 1;
82
- const releaseMaxQuantity = Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER);
83
- const remainingOrderCapacity = Math.max(0, MAX_TICKETS_PER_ORDER - countSelectedTickets());
83
+ const releaseMaxQuantity = Math.min(release.availableTickets || 0, maxTicketsPerOrder);
84
+ const remainingOrderCapacity = Math.max(0, maxTicketsPerOrder - countSelectedTickets());
84
85
  const quantity = Math.min(requestedQuantity, releaseMaxQuantity, remainingOrderCapacity);
85
86
 
86
87
  if (quantity <= 0) {
@@ -123,7 +124,7 @@ const ReleaseWithMerchandise: React.FC<Props> = ({
123
124
  if (addedRelease) {
124
125
  const increment = normalizedProducts.length ? normalizedProducts.length : 1;
125
126
  const maxQuantity = getAvailableTicketsForRelease(addedRelease);
126
- const remainingOrderCapacity = Math.max(0, MAX_TICKETS_PER_ORDER - countSelectedTickets());
127
+ const remainingOrderCapacity = Math.max(0, maxTicketsPerOrder - countSelectedTickets());
127
128
  const availableIncrement = Math.max(
128
129
  0,
129
130
  Math.min(increment, maxQuantity - Number(addedRelease.quantity), remainingOrderCapacity)
@@ -194,7 +195,7 @@ const ReleaseWithMerchandise: React.FC<Props> = ({
194
195
  }, [tickets, release.id, setValue]);
195
196
 
196
197
  const ticketIndex = tickets.findIndex((t) => t.releaseId === release.id);
197
- const remainingOrderCapacity = Math.max(0, MAX_TICKETS_PER_ORDER - countSelectedTickets());
198
+ const remainingOrderCapacity = Math.max(0, maxTicketsPerOrder - countSelectedTickets());
198
199
  const nextRelease = activeReleases?.find(
199
200
  (item) =>
200
201
  item.releaseCategoryName === release.releaseCategoryName && item.order === release.order + 1
@@ -9,7 +9,7 @@ import { IEvent } from '@utils/types/event.type';
9
9
  import useResponsive from '@hooks/useResponsive';
10
10
  import ReleaseExtraFields from '@form/extra-field/ReleaseExtraFields';
11
11
  import { EventType } from '@utils/data/event';
12
- import { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';
12
+ import { getMaxTicketsPerOrder } from '@utils/data/ticket';
13
13
  import useGlobal from '@hooks/useGlobal';
14
14
  import TicketSelectionMobile from './TicketSelectionMobile';
15
15
 
@@ -19,6 +19,7 @@ interface Props {
19
19
 
20
20
  const TicketSelection: React.FC<Props> = ({ event }) => {
21
21
  const { t } = useGlobal();
22
+ const maxTicketsPerOrder = getMaxTicketsPerOrder(event.id);
22
23
  const isMobile = useResponsive('down', 'md');
23
24
  const { setValue, watch } = useFormContext<ITicketForm>();
24
25
  const tickets = useWatch({
@@ -83,7 +84,7 @@ const TicketSelection: React.FC<Props> = ({ event }) => {
83
84
  item2.releaseCategoryName === item.releaseCategoryName && item2.order === item.order + 1
84
85
  );
85
86
  const selected = tickets.find((ticket) => ticket.releaseId === item.id);
86
- const maxSelectable = Math.min(item.availableTickets || 0, MAX_TICKETS_PER_ORDER);
87
+ const maxSelectable = Math.min(item.availableTickets || 0, maxTicketsPerOrder);
87
88
 
88
89
  return (
89
90
  !!nextRelease &&
@@ -110,8 +111,8 @@ const TicketSelection: React.FC<Props> = ({ event }) => {
110
111
  const isQuantityDisabled = (value: number, releaseId: number | '') => {
111
112
  const releaseSelected = tickets.find((item) => item.releaseId === releaseId);
112
113
  return releaseSelected && releaseSelected.quantity
113
- ? countSelectedTickets() + value - releaseSelected.quantity > MAX_TICKETS_PER_ORDER
114
- : countSelectedTickets() + value > MAX_TICKETS_PER_ORDER;
114
+ ? countSelectedTickets() + value - releaseSelected.quantity > maxTicketsPerOrder
115
+ : countSelectedTickets() + value > maxTicketsPerOrder;
115
116
  };
116
117
 
117
118
  const removeTicket = (indexToRemove: number) => {
@@ -128,7 +129,7 @@ const TicketSelection: React.FC<Props> = ({ event }) => {
128
129
  tickets.find(
129
130
  (ticket) =>
130
131
  release.id === ticket.releaseId &&
131
- Number(ticket.quantity) >= Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER)
132
+ Number(ticket.quantity) >= Math.min(release.availableTickets || 0, maxTicketsPerOrder)
132
133
  )
133
134
  );
134
135
 
@@ -146,7 +147,7 @@ const TicketSelection: React.FC<Props> = ({ event }) => {
146
147
  const previousTicket = tickets.find((ticket) => ticket.releaseId === previousRelease.id);
147
148
  const previousMaxSelectable = Math.min(
148
149
  previousRelease.availableTickets || 0,
149
- MAX_TICKETS_PER_ORDER
150
+ maxTicketsPerOrder
150
151
  );
151
152
  const shouldUnlock = Number(previousTicket?.quantity || 0) >= previousMaxSelectable;
152
153
 
@@ -5,7 +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';
8
- import { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';
8
+ import { getMaxTicketsPerOrder } from '@utils/data/ticket';
9
9
  import Iconify from '@components/iconify/Iconify';
10
10
 
11
11
  interface Props {
@@ -44,7 +44,7 @@ const TicketSelectionMap: React.FC<Props> = ({ event }) => {
44
44
  [] as { quantity: number; seat: ITicketLocation; ticket: any }[]
45
45
  );
46
46
 
47
- let remainingTicketCapacity = MAX_TICKETS_PER_ORDER;
47
+ let remainingTicketCapacity = getMaxTicketsPerOrder(event.id);
48
48
 
49
49
  for (const groupedSeat of groupedSeatsByZone) {
50
50
  if (remainingTicketCapacity <= 0) break;
@@ -4,7 +4,7 @@ import { fCurrency } from '@utils/formatNumber';
4
4
  import { IEvent } from '@utils/types/event.type';
5
5
  import { IReleaseShort } from '@utils/types/release.type';
6
6
  import { ITicketFormTicket } from '@utils/types/ticket.type';
7
- import { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';
7
+ import { getMaxTicketsPerOrder } from '@utils/data/ticket';
8
8
  import useGlobal from '@hooks/useGlobal';
9
9
  import { validatePrimaryTicketNumber } from '@modules/ticket';
10
10
  import ReleaseDescription from './ReleaseDescription';
@@ -33,6 +33,7 @@ const TicketSelectionMobile: React.FC<Props> = ({
33
33
  getExtraFields,
34
34
  }) => {
35
35
  const { t, lang } = useGlobal();
36
+ const maxTicketsPerOrder = getMaxTicketsPerOrder(event.id);
36
37
  const [expandedReleaseIds, setExpandedReleaseIds] = useState<Record<number, boolean>>({});
37
38
  const [pendingPrimaryRelease, setPendingPrimaryRelease] = useState<IReleaseShort | null>(null);
38
39
  const theme = useTheme();
@@ -53,7 +54,7 @@ const TicketSelectionMobile: React.FC<Props> = ({
53
54
  !release.locked || getReleaseQuantity(release.id) > 0;
54
55
 
55
56
  const incrementRelease = (release: IReleaseShort, primaryTicketNumber?: string) => {
56
- const maxAvailable = Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER);
57
+ const maxAvailable = Math.min(release.availableTickets || 0, maxTicketsPerOrder);
57
58
  const ticketIndex = getTicketIndexByRelease(release.id);
58
59
  const currentQuantity = ticketIndex >= 0 ? Number(tickets[ticketIndex]?.quantity || 0) : 0;
59
60
  const nextQuantity = Math.min(currentQuantity + 1, maxAvailable);
@@ -155,7 +156,7 @@ const TicketSelectionMobile: React.FC<Props> = ({
155
156
  .map((release) => {
156
157
  const quantity = getReleaseQuantity(release.id);
157
158
  const ticketIndex = getTicketIndexByRelease(release.id);
158
- const maxAvailable = Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER);
159
+ const maxAvailable = Math.min(release.availableTickets || 0, maxTicketsPerOrder);
159
160
  const isLocked = release.locked;
160
161
  const nextRelease = activeReleases?.find(
161
162
  (item) =>
@@ -8,7 +8,7 @@ import { IReleaseShort } from '@utils/types/release.type';
8
8
  import { IEvent } from '@utils/types/event.type';
9
9
  import ReleaseWithMerchandise from '@form/tickets/ReleaseWithMerchandise';
10
10
  import { EventType } from '@utils/data/event';
11
- import { MAX_TICKETS_PER_ORDER } from '@utils/data/ticket';
11
+ import { getMaxTicketsPerOrder } from '@utils/data/ticket';
12
12
  import useGlobal from '@hooks/useGlobal';
13
13
 
14
14
  interface Props {
@@ -17,6 +17,7 @@ interface Props {
17
17
 
18
18
  const TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {
19
19
  const { t } = useGlobal();
20
+ const maxTicketsPerOrder = getMaxTicketsPerOrder(event.id);
20
21
  const { setValue, watch } = useFormContext<ITicketForm>();
21
22
  const tickets: ITicketFormTicket[] = useWatch({ name: `tickets.${event.id}`, defaultValue: [] });
22
23
  const eventTimeslotId = watch('eventTimeslotId');
@@ -43,7 +44,7 @@ const TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {
43
44
  item2.releaseCategoryName === item.releaseCategoryName && item2.order === item.order + 1
44
45
  );
45
46
  const selected = tickets.find((ticket) => ticket.releaseId === item.id);
46
- const maxSelectable = Math.min(item.availableTickets || 0, MAX_TICKETS_PER_ORDER);
47
+ const maxSelectable = Math.min(item.availableTickets || 0, maxTicketsPerOrder);
47
48
 
48
49
  return (
49
50
  !!nextRelease &&
@@ -69,7 +70,7 @@ const TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {
69
70
  tickets.find(
70
71
  (ticket) =>
71
72
  release.id === ticket.releaseId &&
72
- Number(ticket.quantity) >= Math.min(release.availableTickets || 0, MAX_TICKETS_PER_ORDER)
73
+ Number(ticket.quantity) >= Math.min(release.availableTickets || 0, maxTicketsPerOrder)
73
74
  )
74
75
  );
75
76
 
@@ -88,7 +89,7 @@ const TicketWithMerchandiseSelection: React.FC<Props> = ({ event }) => {
88
89
  const previousTicket = tickets.find((ticket) => ticket.releaseId === previousRelease.id);
89
90
  const previousMaxSelectable = Math.min(
90
91
  previousRelease.availableTickets || 0,
91
- MAX_TICKETS_PER_ORDER
92
+ maxTicketsPerOrder
92
93
  );
93
94
  const shouldUnlock = Number(previousTicket?.quantity || 0) >= previousMaxSelectable;
94
95
 
@@ -1 +1,11 @@
1
1
  export const MAX_TICKETS_PER_ORDER = 10;
2
+
3
+ // TODO(EVE-NN): temporary per-event overrides until the backend exposes a
4
+ // configurable maxTicketsPerOrder. Mirrors the same map in the backend's
5
+ // OrderService — keep the two in sync and remove BOTH once that column ships.
6
+ const PER_EVENT_TICKET_LIMITS: Record<number, number> = {
7
+ 1837: 2,
8
+ };
9
+
10
+ export const getMaxTicketsPerOrder = (eventId?: number): number =>
11
+ (eventId != null && PER_EVENT_TICKET_LIMITS[eventId]) || MAX_TICKETS_PER_ORDER;