@eventlook/sdk 1.7.2 → 1.7.3-beta.0

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 (84) hide show
  1. package/.prettierignore +3 -0
  2. package/CLAUDE.md +33 -0
  3. package/dist/cjs/{index-D1KZ-2U1.js → index-CXsZ9BsP.js} +26476 -25947
  4. package/dist/cjs/index-CXsZ9BsP.js.map +1 -0
  5. package/dist/cjs/index-DgOx9uHQ.js +41917 -0
  6. package/dist/cjs/index-DgOx9uHQ.js.map +1 -0
  7. package/dist/cjs/index.js +3 -1
  8. package/dist/cjs/index.js.map +1 -1
  9. package/dist/cjs/{index.umd-C2KzR75H.js → index.umd-DR37hmpO.js} +2 -2
  10. package/dist/cjs/{index.umd-C2KzR75H.js.map → index.umd-DR37hmpO.js.map} +1 -1
  11. package/dist/cjs/index.umd-TbjzhsUx.js +13397 -0
  12. package/dist/cjs/index.umd-TbjzhsUx.js.map +1 -0
  13. package/dist/cjs/{mui-tel-input.es-Bjml407E.js → mui-tel-input.es-Dk9M_v4X.js} +6 -6
  14. package/dist/{esm/mui-tel-input.es-Bt2rE3An.js.map → cjs/mui-tel-input.es-Dk9M_v4X.js.map} +1 -1
  15. package/dist/esm/index-Ds-63DcA.js +41896 -0
  16. package/dist/esm/index-Ds-63DcA.js.map +1 -0
  17. package/dist/esm/{index-DRYwiFvp.js → index-z31XSEKz.js} +26751 -26240
  18. package/dist/esm/index-z31XSEKz.js.map +1 -0
  19. package/dist/esm/index.js +3 -1
  20. package/dist/esm/index.js.map +1 -1
  21. package/dist/esm/{index.umd-BXOC8cuK.js → index.umd-5znOX_Ww.js} +4 -4
  22. package/dist/esm/{index.umd-BXOC8cuK.js.map → index.umd-5znOX_Ww.js.map} +1 -1
  23. package/dist/esm/index.umd-ddggyAGa.js +13395 -0
  24. package/dist/esm/index.umd-ddggyAGa.js.map +1 -0
  25. package/dist/esm/{mui-tel-input.es-Bt2rE3An.js → mui-tel-input.es-Cb4Lpqx7.js} +21 -21
  26. package/dist/{cjs/mui-tel-input.es-Bjml407E.js.map → esm/mui-tel-input.es-Cb4Lpqx7.js.map} +1 -1
  27. package/dist/types/form/Payment.d.ts +1 -0
  28. package/dist/types/form/paydroid/PaydroidCashlessSection.d.ts +7 -0
  29. package/dist/types/form/paydroid/PaydroidError.d.ts +3 -0
  30. package/dist/types/form/paydroid/PaydroidErrorAccount.d.ts +3 -0
  31. package/dist/types/form/paydroid/PaydroidErrorTicket.d.ts +3 -0
  32. package/dist/types/form/paydroid/PaydroidPage.d.ts +6 -0
  33. package/dist/types/form/paydroid/PaydroidStatusCard.d.ts +10 -0
  34. package/dist/types/form/paydroid/PaydroidSuccess.d.ts +3 -0
  35. package/dist/types/form/paydroid/PaydroidSuccessTopup.d.ts +3 -0
  36. package/dist/types/form/payment/StripeCheckoutProvider.d.ts +36 -0
  37. package/dist/types/hooks/data/useStripeConfig.d.ts +3 -0
  38. package/dist/types/locales/cs.d.ts +34 -0
  39. package/dist/types/locales/en.d.ts +34 -0
  40. package/dist/types/locales/es.d.ts +34 -0
  41. package/dist/types/locales/pl.d.ts +34 -0
  42. package/dist/types/locales/sk.d.ts +34 -0
  43. package/dist/types/locales/uk.d.ts +34 -0
  44. package/dist/types/modules/order.d.ts +3 -0
  45. package/dist/types/modules/paydroid.d.ts +4 -0
  46. package/dist/types/utils/data/page.d.ts +7 -0
  47. package/dist/types/utils/page.d.ts +1 -0
  48. package/dist/types/utils/paydroid.d.ts +6 -0
  49. package/dist/types/utils/types/global.type.d.ts +1 -0
  50. package/dist/types/utils/types/order.type.d.ts +4 -0
  51. package/dist/types/utils/types/paydroid.d.ts +23 -0
  52. package/dist/types/utils/types/payment-method.type.d.ts +1 -0
  53. package/package.json +6 -2
  54. package/src/form/Payment.tsx +42 -3
  55. package/src/form/PaymentOverviewBox.tsx +20 -7
  56. package/src/form/PaymentSuccess.tsx +6 -2
  57. package/src/form/TicketForm.tsx +269 -168
  58. package/src/form/paydroid/PaydroidCashlessSection.tsx +311 -0
  59. package/src/form/paydroid/PaydroidError.tsx +26 -0
  60. package/src/form/paydroid/PaydroidErrorAccount.tsx +26 -0
  61. package/src/form/paydroid/PaydroidErrorTicket.tsx +26 -0
  62. package/src/form/paydroid/PaydroidPage.tsx +22 -0
  63. package/src/form/paydroid/PaydroidStatusCard.tsx +91 -0
  64. package/src/form/paydroid/PaydroidSuccess.tsx +26 -0
  65. package/src/form/paydroid/PaydroidSuccessTopup.tsx +26 -0
  66. package/src/form/payment/StripeCheckoutProvider.tsx +154 -0
  67. package/src/hooks/data/useStripeConfig.ts +14 -0
  68. package/src/locales/cs.tsx +40 -0
  69. package/src/locales/en.tsx +38 -0
  70. package/src/locales/es.tsx +39 -0
  71. package/src/locales/pl.tsx +38 -0
  72. package/src/locales/sk.tsx +40 -0
  73. package/src/locales/uk.tsx +38 -0
  74. package/src/modules/order.ts +3 -0
  75. package/src/modules/paydroid.ts +33 -0
  76. package/src/utils/data/page.ts +7 -0
  77. package/src/utils/page.ts +4 -0
  78. package/src/utils/paydroid.ts +35 -0
  79. package/src/utils/types/global.type.ts +1 -0
  80. package/src/utils/types/order.type.ts +7 -0
  81. package/src/utils/types/paydroid.ts +26 -0
  82. package/src/utils/types/payment-method.type.ts +1 -0
  83. package/dist/cjs/index-D1KZ-2U1.js.map +0 -1
  84. package/dist/esm/index-DRYwiFvp.js.map +0 -1
@@ -42,6 +42,7 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
42
42
  const insuranceAvailable = isInsuranceAvailable(event.currency);
43
43
  const { data: eventProducts } = useActiveEventProducts(event.id, true);
44
44
  const [shippingFee, setShippingFee] = useState(0);
45
+ const [paymentMethodFee, setPaymentMethodFee] = useState(0);
45
46
  const { setValue, watch } = useFormContext<ITicketForm>();
46
47
  const values = watch();
47
48
  const {
@@ -135,6 +136,10 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
135
136
  }, [event, flatProducts]);
136
137
 
137
138
  const getFee = useMemo(() => fCurrency(totalFee ?? 0, lang, event.currency), [totalFee]);
139
+ const getPaymentMethodFee = useMemo(
140
+ () => fCurrency(paymentMethodFee ?? 0, lang, event.currency),
141
+ [paymentMethodFee]
142
+ );
138
143
 
139
144
  const shoppingCartBody = useMemo<ICalculateShoppingCartDto>(
140
145
  () => ({
@@ -253,8 +258,10 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
253
258
  setValue('originalPrice', data.originalPrice);
254
259
  setValue('total', data.totalPrice || 0);
255
260
 
256
- const feeTotal = (data.serviceFee ?? 0) + (data.paymentMethodFee ?? 0);
257
- setValue('totalFee', feeTotal);
261
+ // The Stripe processing surcharge is shown as its own line, so keep the
262
+ // service fee and the payment-method fee separate.
263
+ setValue('totalFee', data.serviceFee ?? 0);
264
+ setPaymentMethodFee(data.paymentMethodFee ?? 0);
258
265
 
259
266
  setShippingFee(data.shippingFee);
260
267
  setValue('ticketInsurance', data.ticketInsurance.enabled);
@@ -482,13 +489,13 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
482
489
  className="overview-card__order-info"
483
490
  sx={{ p: { xs: withoutPadding ? 0 : 2, md: 2 } }}
484
491
  pt={{ xs: 0, sm: 2 }}
485
- spacing={0.75}
492
+ spacing={1.25}
486
493
  useFlexGap
487
494
  >
488
- {!!selectedTickets.length && !isMobile && <Divider sx={{ borderStyle: 'dashed' }} />}
495
+ {!!selectedTickets.length && !isMobile && <Divider sx={{ borderStyle: 'dashed', my: 1 }} />}
489
496
 
490
497
  {!!selectedTickets.length && (
491
- <Stack spacing={0.5}>
498
+ <Stack spacing={1}>
492
499
  {insuranceAvailable && (
493
500
  <PaymentOverviewCheckbox
494
501
  checkboxName="ticketInsurance"
@@ -515,7 +522,7 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
515
522
  </>
516
523
  }
517
524
  />
518
- <Divider sx={{ borderStyle: 'dashed' }} />
525
+ <Divider sx={{ borderStyle: 'dashed', mt: 0.5 }} />
519
526
  </Stack>
520
527
  )}
521
528
  {selectedTickets.map((ticket, index) => (
@@ -600,8 +607,14 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
600
607
  <Typography variant="body2">{getFee}</Typography>
601
608
  </Stack>
602
609
  )}
610
+ {!!total && !!paymentMethodFee && (
611
+ <Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
612
+ <Typography variant="body2">{t('form.labels.payment_processing_fee')}</Typography>
613
+ <Typography variant="body2">{getPaymentMethodFee}</Typography>
614
+ </Stack>
615
+ )}
603
616
  {((!!selectedTickets.length && isMobile) || !isMobile) && (
604
- <Divider sx={{ borderStyle: 'dashed' }} />
617
+ <Divider sx={{ borderStyle: 'dashed', my: 1 }} />
605
618
  )}
606
619
  {!hideBuyButton && (
607
620
  <>
@@ -1,5 +1,6 @@
1
1
  import { Iconify, Image, MotionContainer, varBounce } from '@components';
2
2
  import { Box, Button, Card, Grid, LinearProgress, Link, Typography } from '@mui/material';
3
+ import PaydroidCashlessSection from '@form/paydroid/PaydroidCashlessSection';
3
4
  import React, { Dispatch, SetStateAction, useEffect, useState } from 'react';
4
5
  import { getSearchParamsInObject } from '@utils/url';
5
6
  import { postOrderPaid } from '@modules/order';
@@ -17,6 +18,7 @@ import useGlobal from '@hooks/useGlobal';
17
18
  import { Trans } from '@components/Trans';
18
19
  import { getGtmPurchasePaid, gtmPurchasePaid, mapUserToUserData } from '@utils/gtm';
19
20
  import { IPixels } from '@utils/types/gtm.type';
21
+ import { IOrderPaid } from '@utils/types/order.type';
20
22
 
21
23
  interface Props {
22
24
  setIsPaying: Dispatch<SetStateAction<boolean>>;
@@ -31,6 +33,7 @@ const PaymentSuccess: React.FC<Props> = ({ setIsPaying, isIframe, pixels }) => {
31
33
  const errorState = 'ERROR';
32
34
  const [tickets, setTickets] = useState<IPaidTicket[]>([]);
33
35
  const [products, setProducts] = useState<IPaidProduct[]>([]);
36
+ const [data, setData] = useState<IOrderPaid | null>(null);
34
37
  const [state, setState] = useState<string>(defaultState);
35
38
  const [title, setTitle] = useState<string>(t('event.tickets.payment_success.loading'));
36
39
  const [description, setDescription] = useState<string | null>(null);
@@ -50,12 +53,12 @@ const PaymentSuccess: React.FC<Props> = ({ setIsPaying, isIframe, pixels }) => {
50
53
  const { data } = await postOrderPaid({
51
54
  gopayId: Number(paymentId),
52
55
  });
53
- const { tickets } = data;
56
+ const { tickets, products } = data;
54
57
  setTickets(tickets);
55
- const { products } = data;
56
58
  setProducts(products);
57
59
  setState(data.state);
58
60
  setGwUrl(data.gwUrl);
61
+ setData(data);
59
62
 
60
63
  const items = [
61
64
  ...data.tickets.map((ticket) => ({
@@ -329,6 +332,7 @@ const PaymentSuccess: React.FC<Props> = ({ setIsPaying, isIframe, pixels }) => {
329
332
  </Grid>
330
333
  </>
331
334
  )}
335
+ {data?.paydroidEventId && <PaydroidCashlessSection data={data} />}
332
336
  {!isIframe && (
333
337
  <Box textAlign="center">
334
338
  <CustomButton
@@ -61,6 +61,23 @@ import TicketSelectionMap from '@form/tickets/TicketSelectionMap';
61
61
  import PaymentOverviewDrawer from './PaymentOverviewDrawer';
62
62
  import { getPlaceAsString } from '@utils/place';
63
63
  import Services from '@form/services';
64
+ import PaydroidPage from './paydroid/PaydroidPage';
65
+ import { isPaydroidPage } from '@utils/page';
66
+ import StripeCheckoutProvider, { StripeCheckoutApi } from '@form/payment/StripeCheckoutProvider';
67
+ import useAllowedPaymentMethods from '@hooks/data/useAllowedPaymentMethods';
68
+ import useStripeConfig from '@hooks/data/useStripeConfig';
69
+
70
+ // Append the order number so the post-payment confirmation poll (PaymentSuccess)
71
+ // can resolve the order — same ?id contract the hosted-gateway return used.
72
+ const withOrderId = (url: string, orderNumber: number) => {
73
+ try {
74
+ const u = new URL(url);
75
+ u.searchParams.set('id', String(orderNumber));
76
+ return u.toString();
77
+ } catch {
78
+ return url;
79
+ }
80
+ };
64
81
 
65
82
  interface Props {
66
83
  event: IEvent;
@@ -96,12 +113,32 @@ const TicketForm: React.FC<Props> = ({
96
113
  isInline,
97
114
  headerSlot,
98
115
  }) => {
99
- const { t, setGlobal, callbacks, links, user, options, showSnackbar, content, seatingIframeUrl } =
100
- useGlobal();
116
+ const {
117
+ t,
118
+ lang,
119
+ setGlobal,
120
+ callbacks,
121
+ links,
122
+ user,
123
+ options,
124
+ showSnackbar,
125
+ content,
126
+ seatingIframeUrl,
127
+ } = useGlobal();
101
128
  const { transformErrors } = useErrors(t('event.tickets.error.order'));
102
129
  const { data: eventProducts, isLoading } = useActiveEventProducts(event.id);
103
130
  const [paymentRedirect, setPaymentRedirect] = useState<string | null>(null);
104
131
  const [hasGopayId, setHasGopayId] = useState<boolean>(hasGopayIdSsr);
132
+
133
+ // Inline Stripe (Payment Element, expand-on-select). The Elements provider is
134
+ // mounted up front when a Stripe method is on offer and the publishable key is
135
+ // loaded; the form's submit handler drives confirmation via this ref.
136
+ const { data: allowedPaymentMethods } = useAllowedPaymentMethods(event.currency, event.id);
137
+ const stripeMethod = allowedPaymentMethods?.find((m) => m.provider === 'STRIPE');
138
+ const { publishableKey } = useStripeConfig(!!stripeMethod);
139
+ const stripeOffered = !!stripeMethod && !!publishableKey;
140
+ const stripeCheckoutRef = useRef<StripeCheckoutApi | null>(null);
141
+ const [page, setPage] = useState<string | null>(null);
105
142
  const [isPaying, setIsPaying] = useState<boolean>(false);
106
143
  const [formStep, setFormStep] = useState<number>(1);
107
144
  const [isPaymentOverviewDrawerOpen, setIsPaymentOverviewDrawerOpen] = useState<boolean>(false);
@@ -387,6 +424,14 @@ const TicketForm: React.FC<Props> = ({
387
424
  const cartItemCount = getCartUniqueItemCount(values);
388
425
  const onInvalid = useScrollToFirstError(methods);
389
426
 
427
+ // Stripe deferred Elements rejects amounts below the per-currency minimum, so
428
+ // only mount it once there's a real, positive cart total (in minor units).
429
+ // Free orders with items verify the card instead (SetupIntent, no charge).
430
+ const stripeAmountMinor = Math.round((Number(values.total) || 0) * 100);
431
+ const isStripeVerification = stripeAmountMinor === 0 && cartItemCount > 0;
432
+ const stripeMode: 'payment' | 'setup' = isStripeVerification ? 'setup' : 'payment';
433
+ const stripeReady = stripeOffered && (stripeAmountMinor > 0 || isStripeVerification);
434
+
390
435
  const onSubmit = async (values: ITicketForm) => {
391
436
  if (cartItemCount <= 0) {
392
437
  showSnackbar(t('form.validation.count_tickets_or_products'), {
@@ -424,6 +469,21 @@ const TicketForm: React.FC<Props> = ({
424
469
  },
425
470
  {} as Record<number, ITicketFormTicket[]>
426
471
  );
472
+ // Inline Stripe (expand-on-select): validate + collect the card fields
473
+ // before creating the order, so a card error never leaves a dangling
474
+ // order/reservation behind.
475
+ const selectedMethod = allowedPaymentMethods?.find(
476
+ (m) => m.id === Number(values.paymentMethodId)
477
+ );
478
+ const isStripeSelected = selectedMethod?.provider === 'STRIPE';
479
+ if (isStripeSelected) {
480
+ const cardError = await stripeCheckoutRef.current?.submit();
481
+ if (cardError) {
482
+ showSnackbar(cardError, { variant: 'error' });
483
+ return;
484
+ }
485
+ }
486
+
427
487
  const { data: orderData } = await postOrder(data);
428
488
  localStorage.removeItem('cartToken');
429
489
  const items = [
@@ -479,6 +539,32 @@ const TicketForm: React.FC<Props> = ({
479
539
  gtmPurchase(null);
480
540
  gtmPurchase(item, pixels, userData);
481
541
  }
542
+ // Inline Stripe: confirm the PaymentIntent in-page (no redirect). On
543
+ // success land on the order page with ?id=<orderNumber> so the existing
544
+ // PaymentSuccess poll + webhook finalize the order.
545
+ if (orderData.clientSecret) {
546
+ const returnUrl = withOrderId(
547
+ data.callback || window.location.href,
548
+ orderData.orderEntity.number
549
+ );
550
+ const result = await stripeCheckoutRef.current?.confirm(
551
+ orderData.clientSecret,
552
+ returnUrl
553
+ );
554
+ if (!result?.ok) {
555
+ showSnackbar(result?.error || t('form.labels.card_payment_error'), {
556
+ variant: 'error',
557
+ });
558
+ return;
559
+ }
560
+ if (!isInline && isIframe) {
561
+ parent.postMessage({ type: 'eventlookFrameGopayRedirect', gwUrl: returnUrl }, '*');
562
+ } else {
563
+ window.location.replace(returnUrl);
564
+ }
565
+ return;
566
+ }
567
+
482
568
  setPaymentRedirect(orderData.gwUrl);
483
569
  methods.reset();
484
570
  } catch (err: any) {
@@ -513,6 +599,7 @@ const TicketForm: React.FC<Props> = ({
513
599
  const paymentId = searchParams.id;
514
600
  const iframeCampaignId = Number(searchParams.iframeCampaignId);
515
601
  setHasGopayId(!!paymentId);
602
+ setPage(searchParams.page || null);
516
603
  if (!isNaN(iframeCampaignId)) {
517
604
  methods.setValue('iframeCampaignId', iframeCampaignId);
518
605
  }
@@ -559,7 +646,9 @@ const TicketForm: React.FC<Props> = ({
559
646
 
560
647
  return (
561
648
  <Box id={EVENTLOOK_ORDER_FORM_CONTAINER_ID}>
562
- {hasGopayId ? (
649
+ {isPaydroidPage(page) ? (
650
+ <PaydroidPage page={page} />
651
+ ) : hasGopayId ? (
563
652
  <PaymentSuccess setIsPaying={setIsPaying} isIframe={isIframe} pixels={pixels} />
564
653
  ) : isPaying ? (
565
654
  <PaymentPending />
@@ -571,204 +660,216 @@ const TicketForm: React.FC<Props> = ({
571
660
  isInline={isInline}
572
661
  />
573
662
  ) : (
574
- <FormProvider
575
- methods={methods}
576
- // @ts-ignore -- handleSubmit type mismatch with FormProvider onSubmit prop
577
- onSubmit={methods.handleSubmit(onSubmit, onInvalid)}
578
- formId={EVENTLOOK_ORDER_FORM_ID}
663
+ <StripeCheckoutProvider
664
+ active={stripeReady}
665
+ publishableKey={publishableKey}
666
+ mode={stripeMode}
667
+ amount={stripeAmountMinor}
668
+ currency={event.currency}
669
+ locale={lang}
670
+ apiRef={stripeCheckoutRef}
579
671
  >
580
- <Stack
581
- className="overview-card__event-info"
582
- display={{ md: 'none' }}
583
- sx={{
584
- mb: 2,
585
- }}
672
+ <FormProvider
673
+ methods={methods}
674
+ // @ts-ignore -- handleSubmit type mismatch with FormProvider onSubmit prop
675
+ onSubmit={methods.handleSubmit(onSubmit, onInvalid)}
676
+ formId={EVENTLOOK_ORDER_FORM_ID}
586
677
  >
587
- <Typography variant="h3" component="h1">
588
- {event.name}
589
- </Typography>
590
- <Typography variant="h5" component="h2">
591
- {dayjs(event.startDate).format('DD.MM.YYYY HH:mm')}
592
- </Typography>
593
- <Typography variant="body2" mt={1}>
594
- {getPlaceAsString(event.place)}
595
- </Typography>
596
- {headerSlot ? <>{headerSlot}</> : null}
597
- </Stack>
598
- <Grid
599
- container
600
- spacing={2}
601
- sx={{
602
- pb: {
603
- xs: isPaymentOverviewDrawerOpen ? cartItemCount * 4 + 18 : 0,
604
- md: 0,
605
- },
606
- }}
607
- >
608
- <Grid size={{ xs: 12, md: 8 }}>
609
- <Stepper
610
- orientation="vertical"
611
- sx={(theme) => ({
612
- [theme.breakpoints.down('sm')]: {
613
- '& .MuiStepContent-root': {
614
- borderLeftWidth: 0,
615
- paddingLeft: 0,
616
- marginLeft: 0,
678
+ <Stack
679
+ className="overview-card__event-info"
680
+ display={{ md: 'none' }}
681
+ sx={{
682
+ mb: 2,
683
+ }}
684
+ >
685
+ <Typography variant="h3" component="h1">
686
+ {event.name}
687
+ </Typography>
688
+ <Typography variant="h5" component="h2">
689
+ {dayjs(event.startDate).format('DD.MM.YYYY HH:mm')}
690
+ </Typography>
691
+ <Typography variant="body2" mt={1}>
692
+ {getPlaceAsString(event.place)}
693
+ </Typography>
694
+ {headerSlot ? <>{headerSlot}</> : null}
695
+ </Stack>
696
+ <Grid
697
+ container
698
+ spacing={2}
699
+ sx={{
700
+ pb: {
701
+ xs: isPaymentOverviewDrawerOpen ? cartItemCount * 4 + 18 : 0,
702
+ md: 0,
703
+ },
704
+ }}
705
+ >
706
+ <Grid size={{ xs: 12, md: 8 }}>
707
+ <Stepper
708
+ orientation="vertical"
709
+ sx={(theme) => ({
710
+ [theme.breakpoints.down('sm')]: {
711
+ '& .MuiStepContent-root': {
712
+ borderLeftWidth: 0,
713
+ paddingLeft: 0,
714
+ marginLeft: 0,
715
+ },
716
+ '& .MuiStepConnector-line': { borderLeftWidth: 0 },
617
717
  },
618
- '& .MuiStepConnector-line': { borderLeftWidth: 0 },
619
- },
620
- })}
621
- >
622
- {event.type === EventType.RECURRING && (
718
+ })}
719
+ >
720
+ {event.type === EventType.RECURRING && (
721
+ <Step active>
722
+ <StepLabel>{t('event.tickets.stepper.6.title')}</StepLabel>
723
+ <StepContent sx={{ pr: { xs: 0 } }}>
724
+ <TimeslotSelection event={event} />
725
+ </StepContent>
726
+ </Step>
727
+ )}
623
728
  <Step active>
624
- <StepLabel>{t('event.tickets.stepper.6.title')}</StepLabel>
729
+ <StepLabel>{t('event.tickets.stepper.1.title')}</StepLabel>
625
730
  <StepContent sx={{ pr: { xs: 0 } }}>
626
- <TimeslotSelection event={event} />
731
+ {event.mapId && seatingIframeUrl ? (
732
+ <TicketSelectionMap event={event} />
733
+ ) : event.hasMerchandise ? (
734
+ <TicketWithMerchandiseSelection event={event} />
735
+ ) : (
736
+ <TicketSelection event={event} />
737
+ )}
627
738
  </StepContent>
628
739
  </Step>
629
- )}
630
- <Step active>
631
- <StepLabel>{t('event.tickets.stepper.1.title')}</StepLabel>
632
- <StepContent sx={{ pr: { xs: 0 } }}>
633
- {event.mapId && seatingIframeUrl ? (
634
- <TicketSelectionMap event={event} />
635
- ) : event.hasMerchandise ? (
636
- <TicketWithMerchandiseSelection event={event} />
637
- ) : (
638
- <TicketSelection event={event} />
639
- )}
640
- </StepContent>
641
- </Step>
642
- {event.hasMerchandise && eventProducts.length && (
740
+ {event.hasMerchandise && eventProducts.length && (
741
+ <Step active>
742
+ <StepLabel>{t('event.tickets.stepper.4.title')}</StepLabel>
743
+ <StepContent sx={{ pr: { xs: 0 } }}>
744
+ <MerchandiseSelection
745
+ eventProducts={eventProducts}
746
+ eventId={event.id}
747
+ isLoading={isLoading}
748
+ />
749
+ </StepContent>
750
+ </Step>
751
+ )}
643
752
  <Step active>
644
- <StepLabel>{t('event.tickets.stepper.4.title')}</StepLabel>
753
+ <StepLabel>{t('event.tickets.stepper.8.title')}</StepLabel>
645
754
  <StepContent sx={{ pr: { xs: 0 } }}>
646
- <MerchandiseSelection
647
- eventProducts={eventProducts}
648
- eventId={event.id}
649
- isLoading={isLoading}
650
- />
755
+ <Services event={event} />
651
756
  </StepContent>
652
757
  </Step>
653
- )}
654
- <Step active>
655
- <StepLabel>{t('event.tickets.stepper.8.title')}</StepLabel>
656
- <StepContent sx={{ pr: { xs: 0 } }}>
657
- <Services event={event} />
658
- </StepContent>
659
- </Step>
660
- {event.children.length && (
758
+ {event.children.length && (
759
+ <Step active>
760
+ <StepLabel>{t('event.tickets.stepper.7.title')}</StepLabel>
761
+ <StepContent sx={{ pr: { xs: 0 } }}>
762
+ <ChildEventSection events={event.children} />
763
+ </StepContent>
764
+ </Step>
765
+ )}
661
766
  <Step active>
662
- <StepLabel>{t('event.tickets.stepper.7.title')}</StepLabel>
767
+ <StepLabel>{t('event.tickets.stepper.2.title')}</StepLabel>
663
768
  <StepContent sx={{ pr: { xs: 0 } }}>
664
- <ChildEventSection events={event.children} />
769
+ <ContactPerson event={event} />
665
770
  </StepContent>
666
771
  </Step>
667
- )}
668
- <Step active>
669
- <StepLabel>{t('event.tickets.stepper.2.title')}</StepLabel>
670
- <StepContent sx={{ pr: { xs: 0 } }}>
671
- <ContactPerson event={event} />
672
- </StepContent>
673
- </Step>
674
- {event.hasMerchandise && showShippingMethods() && (
772
+ {event.hasMerchandise && showShippingMethods() && (
773
+ <Step active>
774
+ <StepLabel>{t('event.tickets.stepper.5.title')}</StepLabel>
775
+ <StepContent sx={{ pr: { xs: 0 } }}>
776
+ <Shipping event={event} />
777
+ </StepContent>
778
+ </Step>
779
+ )}
675
780
  <Step active>
676
- <StepLabel>{t('event.tickets.stepper.5.title')}</StepLabel>
781
+ <StepLabel>
782
+ {t(
783
+ `event.tickets.stepper.3.${values.isPaymentVerify ? 'title_verify' : 'title'}`
784
+ )}
785
+ </StepLabel>
677
786
  <StepContent sx={{ pr: { xs: 0 } }}>
678
- <Shipping event={event} />
787
+ <Payment event={event} stripeReady={stripeReady} />
679
788
  </StepContent>
680
789
  </Step>
681
- )}
682
- <Step active>
683
- <StepLabel>
684
- {t(
685
- `event.tickets.stepper.3.${values.isPaymentVerify ? 'title_verify' : 'title'}`
686
- )}
687
- </StepLabel>
688
- <StepContent sx={{ pr: { xs: 0 } }}>
689
- <Payment event={event} />
690
- </StepContent>
691
- </Step>
692
- </Stepper>
693
- <Stack
694
- ref={termsAndConditionsRef}
695
- mt={2}
696
- ml={{ xs: 1, md: 4 }}
697
- sx={{ scrollMarginBottom: { xs: 220, md: 0 } }}
698
- >
699
- <RHFCheckbox
700
- name="termsAndConditions"
701
- label={
702
- <>
703
- <Trans
704
- text="event.tickets.terms_and_conditions"
705
- values={{
706
- termsAndConditionsCompanies: options?.termsAndConditionsCompanies
707
- ? options.termsAndConditionsCompanies.join(t('and'))
708
- : ['Eventlook', 'GoPay'].join(` ${t('and')} `),
709
- }}
710
- components={{
711
- 0: <CustomLink key={2} href={links.termsAndConditions} target="_blank" />,
712
- 1: <CustomLink key={1} href={links.gdpr} target="_blank" />,
713
- }}
714
- />
715
- </>
716
- }
717
- />
718
- {values.ticketInsurance && (
790
+ </Stepper>
791
+ <Stack
792
+ ref={termsAndConditionsRef}
793
+ mt={2}
794
+ ml={{ xs: 1, md: 4 }}
795
+ sx={{ scrollMarginBottom: { xs: 220, md: 0 } }}
796
+ >
719
797
  <RHFCheckbox
720
- name="insuranceTermsAndConditions"
798
+ name="termsAndConditions"
721
799
  label={
722
800
  <>
723
801
  <Trans
724
- text="event.tickets.insurance.checkbox"
802
+ text="event.tickets.terms_and_conditions"
803
+ values={{
804
+ termsAndConditionsCompanies: options?.termsAndConditionsCompanies
805
+ ? options.termsAndConditionsCompanies.join(t('and'))
806
+ : ['Eventlook', 'GoPay'].join(` ${t('and')} `),
807
+ }}
725
808
  components={{
726
809
  0: (
727
- <CustomLink
728
- key={2}
729
- href="https://eventigo.s3-central.vshosting.cloud/production/colonnade/pp-storno-cz-eventlook-012026.pdf"
730
- target="_blank"
731
- />
732
- ),
733
- 1: (
734
- <CustomLink
735
- key={1}
736
- href="https://eventigo.s3-central.vshosting.cloud/production/colonnade/ipid-storno-cz-112025.pdf"
737
- target="_blank"
738
- />
810
+ <CustomLink key={2} href={links.termsAndConditions} target="_blank" />
739
811
  ),
812
+ 1: <CustomLink key={1} href={links.gdpr} target="_blank" />,
740
813
  }}
741
814
  />
742
815
  </>
743
816
  }
744
817
  />
745
- )}
746
- </Stack>
747
- </Grid>
748
- <Grid size={12} sx={{ display: { xs: 'block', md: 'none' } }}>
749
- <Divider sx={{ borderStyle: 'dashed' }} />
818
+ {values.ticketInsurance && (
819
+ <RHFCheckbox
820
+ name="insuranceTermsAndConditions"
821
+ label={
822
+ <>
823
+ <Trans
824
+ text="event.tickets.insurance.checkbox"
825
+ components={{
826
+ 0: (
827
+ <CustomLink
828
+ key={2}
829
+ href="https://eventigo.s3-central.vshosting.cloud/production/colonnade/pp-storno-cz-eventlook-012026.pdf"
830
+ target="_blank"
831
+ />
832
+ ),
833
+ 1: (
834
+ <CustomLink
835
+ key={1}
836
+ href="https://eventigo.s3-central.vshosting.cloud/production/colonnade/ipid-storno-cz-112025.pdf"
837
+ target="_blank"
838
+ />
839
+ ),
840
+ }}
841
+ />
842
+ </>
843
+ }
844
+ />
845
+ )}
846
+ </Stack>
847
+ </Grid>
848
+ <Grid size={12} sx={{ display: { xs: 'block', md: 'none' } }}>
849
+ <Divider sx={{ borderStyle: 'dashed' }} />
850
+ </Grid>
851
+ <Grid size={{ xs: 12, md: 4 }} sx={{ mt: { xs: 0, md: 0 } }}>
852
+ <PaymentOverviewBox event={event} withoutPadding />
853
+ </Grid>
750
854
  </Grid>
751
- <Grid size={{ xs: 12, md: 4 }} sx={{ mt: { xs: 0, md: 0 } }}>
752
- <PaymentOverviewBox event={event} withoutPadding />
753
- </Grid>
754
- </Grid>
755
-
756
- {!isIframe && (
757
- <PaymentOverviewDrawer
758
- event={event}
759
- totalPrice={values.total}
760
- termsAndConditionsRef={termsAndConditionsRef}
761
- onOpenChange={setIsPaymentOverviewDrawerOpen}
855
+
856
+ {!isIframe && (
857
+ <PaymentOverviewDrawer
858
+ event={event}
859
+ totalPrice={values.total}
860
+ termsAndConditionsRef={termsAndConditionsRef}
861
+ onOpenChange={setIsPaymentOverviewDrawerOpen}
862
+ />
863
+ )}
864
+
865
+ <EmailConfirmation
866
+ open={formStep === 2 && !isIframe}
867
+ onClose={() => setFormStep(1)}
868
+ // @ts-ignore -- handleSubmit type mismatch with onConfirm prop
869
+ onConfirm={methods.handleSubmit(onSubmit, onInvalid)}
762
870
  />
763
- )}
764
-
765
- <EmailConfirmation
766
- open={formStep === 2 && !isIframe}
767
- onClose={() => setFormStep(1)}
768
- // @ts-ignore -- handleSubmit type mismatch with onConfirm prop
769
- onConfirm={methods.handleSubmit(onSubmit, onInvalid)}
770
- />
771
- </FormProvider>
871
+ </FormProvider>
872
+ </StripeCheckoutProvider>
772
873
  )}
773
874
  </Box>
774
875
  );