@bigz-app/booking-widget 1.3.4 → 1.4.1

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.
package/dist/index.cjs CHANGED
@@ -245,6 +245,8 @@ const de$1 = {
245
245
  "button.depositAndBook": "Anzahlen & buchen",
246
246
  "button.continueWithout": "Weiter ohne Extras",
247
247
  "button.continue": "Weiter",
248
+ "button.continueToPayment": "Weiter zur Zahlung",
249
+ "button.backToDetails": "Zurück zu den Angaben",
248
250
  "button.addExtras": "Extras hinzufügen",
249
251
  // Event types
250
252
  "events.noEventsAvailable": "Keine Veranstaltungen verfügbar",
@@ -254,6 +256,7 @@ const de$1 = {
254
256
  "events.availableFrom": "Freie Plätze ab {{date}}",
255
257
  "events.noAvailableDates": "Keine Termine frei",
256
258
  "events.previewSectionTitle": "Specials & nächste Termine",
259
+ "events.seeMoreDates": "Weitere Termine ansehen...",
257
260
  // Event instances
258
261
  "instances.title": "Terminauswahl",
259
262
  "instances.noAvailable": "Keine verfügbaren Termine",
@@ -307,6 +310,10 @@ const de$1 = {
307
310
  "booking.maxSpotsReached": "Maximal {{count}} Plätze verfügbar.",
308
311
  "booking.comment": "Kommentar (optional)",
309
312
  "booking.commentPlaceholder": "Zusätzliche Anmerkungen zur Buchung...",
313
+ "booking.stepDate": "Termin",
314
+ "booking.stepUpsells": "Extras",
315
+ "booking.stepDetails": "Angaben",
316
+ "booking.stepPayment": "Zahlung",
310
317
  // Booking summary
311
318
  "summary.title": "Buchungszusammenfassung",
312
319
  "summary.subtotal": "Zwischensumme:",
@@ -437,6 +444,9 @@ const de$1 = {
437
444
  "upsells.noExtras": "Keine Extras für diese Buchung verfügbar.",
438
445
  "upsells.selected": "{{count}} Extra ausgewählt",
439
446
  "upsells.selectedPlural": "{{count}} Extras ausgewählt",
447
+ "upsells.savePercent": "{{percent}}% sparen",
448
+ "booking.paymentUnavailable": "Online-Zahlung ist für diese Buchung nicht verfügbar. Bitte kontaktiere uns, um die Reservierung abzuschließen.",
449
+ "booking.depositNotConfigured": "Online-Anzahlung ist für dieses Event nicht verfügbar. Bitte kontaktiere uns, um die Reservierung abzuschließen.",
440
450
  "upsells.spotsFree": "{{count}} Plätze frei",
441
451
  "upsells.notAvailable": "Nicht verfügbar",
442
452
  "upsells.reason.outOfStock": "{{productName}} ist nicht auf Lager",
@@ -462,6 +472,9 @@ const de$1 = {
462
472
  "promo.giftCode": "Dein Geschenk-Code",
463
473
  "promo.copied": "Kopiert!",
464
474
  "promo.copy": "Kopieren",
475
+ "trust.securePayment": "Sichere Zahlung",
476
+ "trust.paypal": "PayPal",
477
+ "trust.stripe": "Stripe",
465
478
  };
466
479
 
467
480
  const en = {
@@ -521,6 +534,8 @@ const en = {
521
534
  "button.depositAndBook": "Pay deposit & book",
522
535
  "button.continueWithout": "Continue without extras",
523
536
  "button.continue": "Continue",
537
+ "button.continueToPayment": "Continue to payment",
538
+ "button.backToDetails": "Back to details",
524
539
  "button.addExtras": "Add extras",
525
540
  // Event types
526
541
  "events.noEventsAvailable": "No events available",
@@ -530,6 +545,7 @@ const en = {
530
545
  "events.availableFrom": "Available from {{date}}",
531
546
  "events.noAvailableDates": "No dates available",
532
547
  "events.previewSectionTitle": "Specials & upcoming dates",
548
+ "events.seeMoreDates": "See more dates...",
533
549
  // Event instances
534
550
  "instances.title": "Select a date",
535
551
  "instances.noAvailable": "No available dates",
@@ -583,6 +599,10 @@ const en = {
583
599
  "booking.maxSpotsReached": "Maximum {{count}} spots available.",
584
600
  "booking.comment": "Comment (optional)",
585
601
  "booking.commentPlaceholder": "Additional notes for the booking...",
602
+ "booking.stepDate": "Date",
603
+ "booking.stepUpsells": "Extras",
604
+ "booking.stepDetails": "Details",
605
+ "booking.stepPayment": "Payment",
586
606
  // Booking summary
587
607
  "summary.title": "Booking Summary",
588
608
  "summary.subtotal": "Subtotal:",
@@ -713,6 +733,9 @@ const en = {
713
733
  "upsells.noExtras": "No extras available for this booking.",
714
734
  "upsells.selected": "{{count}} extra selected",
715
735
  "upsells.selectedPlural": "{{count}} extras selected",
736
+ "upsells.savePercent": "Save {{percent}}%",
737
+ "booking.paymentUnavailable": "Online payment is not available for this booking. Please contact us to complete your reservation.",
738
+ "booking.depositNotConfigured": "Online deposit payment is not available for this event. Please contact us to complete your reservation.",
716
739
  "upsells.spotsFree": "{{count}} spots available",
717
740
  "upsells.notAvailable": "Not available",
718
741
  "upsells.reason.outOfStock": "{{productName}} is out of stock",
@@ -738,6 +761,9 @@ const en = {
738
761
  "promo.giftCode": "Your gift code",
739
762
  "promo.copied": "Copied!",
740
763
  "promo.copy": "Copy",
764
+ "trust.securePayment": "Secure payment",
765
+ "trust.paypal": "PayPal",
766
+ "trust.stripe": "Stripe",
741
767
  };
742
768
 
743
769
  const es = {
@@ -797,6 +823,8 @@ const es = {
797
823
  "button.depositAndBook": "Pagar depósito y reservar",
798
824
  "button.continueWithout": "Continuar sin extras",
799
825
  "button.continue": "Continuar",
826
+ "button.continueToPayment": "Continuar al pago",
827
+ "button.backToDetails": "Volver a los datos",
800
828
  "button.addExtras": "Añadir extras",
801
829
  // Event types
802
830
  "events.noEventsAvailable": "No hay eventos disponibles",
@@ -806,6 +834,7 @@ const es = {
806
834
  "events.availableFrom": "Disponible desde {{date}}",
807
835
  "events.noAvailableDates": "Sin fechas disponibles",
808
836
  "events.previewSectionTitle": "Especiales & próximas fechas",
837
+ "events.seeMoreDates": "Ver más fechas...",
809
838
  // Event instances
810
839
  "instances.title": "Seleccionar fecha",
811
840
  "instances.noAvailable": "Sin fechas disponibles",
@@ -859,6 +888,10 @@ const es = {
859
888
  "booking.maxSpotsReached": "Máximo {{count}} plazas disponibles.",
860
889
  "booking.comment": "Comentario (opcional)",
861
890
  "booking.commentPlaceholder": "Notas adicionales para la reserva...",
891
+ "booking.stepDate": "Fecha",
892
+ "booking.stepUpsells": "Extras",
893
+ "booking.stepDetails": "Datos",
894
+ "booking.stepPayment": "Pago",
862
895
  // Booking summary
863
896
  "summary.title": "Resumen de la reserva",
864
897
  "summary.subtotal": "Subtotal:",
@@ -989,6 +1022,9 @@ const es = {
989
1022
  "upsells.noExtras": "No hay extras disponibles para esta reserva.",
990
1023
  "upsells.selected": "{{count}} extra seleccionado",
991
1024
  "upsells.selectedPlural": "{{count}} extras seleccionados",
1025
+ "upsells.savePercent": "Ahorra {{percent}}%",
1026
+ "booking.paymentUnavailable": "El pago en línea no está disponible para esta reserva. Contáctanos para completarla.",
1027
+ "booking.depositNotConfigured": "El pago de depósito en línea no está disponible para este evento. Contáctanos para completar la reserva.",
992
1028
  "upsells.spotsFree": "{{count}} plazas disponibles",
993
1029
  "upsells.notAvailable": "No disponible",
994
1030
  "upsells.reason.outOfStock": "{{productName}} está agotado",
@@ -1014,6 +1050,9 @@ const es = {
1014
1050
  "promo.giftCode": "Tu codigo de regalo",
1015
1051
  "promo.copied": "Copiado!",
1016
1052
  "promo.copy": "Copiar",
1053
+ "trust.securePayment": "Pago seguro",
1054
+ "trust.paypal": "PayPal",
1055
+ "trust.stripe": "Stripe",
1017
1056
  };
1018
1057
 
1019
1058
  const pt = {
@@ -1073,6 +1112,8 @@ const pt = {
1073
1112
  "button.depositAndBook": "Pagar sinal e reservar",
1074
1113
  "button.continueWithout": "Continuar sem extras",
1075
1114
  "button.continue": "Continuar",
1115
+ "button.continueToPayment": "Continuar para pagamento",
1116
+ "button.backToDetails": "Voltar aos dados",
1076
1117
  "button.addExtras": "Adicionar extras",
1077
1118
  // Event types
1078
1119
  "events.noEventsAvailable": "Sem eventos disponíveis",
@@ -1082,6 +1123,7 @@ const pt = {
1082
1123
  "events.availableFrom": "Disponível a partir de {{date}}",
1083
1124
  "events.noAvailableDates": "Sem datas disponíveis",
1084
1125
  "events.previewSectionTitle": "Especiais & próximas datas",
1126
+ "events.seeMoreDates": "Ver mais datas...",
1085
1127
  // Event instances
1086
1128
  "instances.title": "Selecionar data",
1087
1129
  "instances.noAvailable": "Sem datas disponíveis",
@@ -1135,6 +1177,10 @@ const pt = {
1135
1177
  "booking.maxSpotsReached": "Máximo {{count}} lugares disponíveis.",
1136
1178
  "booking.comment": "Comentário (opcional)",
1137
1179
  "booking.commentPlaceholder": "Notas adicionais para a reserva...",
1180
+ "booking.stepDate": "Data",
1181
+ "booking.stepUpsells": "Extras",
1182
+ "booking.stepDetails": "Dados",
1183
+ "booking.stepPayment": "Pagamento",
1138
1184
  // Booking summary
1139
1185
  "summary.title": "Resumo da reserva",
1140
1186
  "summary.subtotal": "Subtotal:",
@@ -1265,6 +1311,9 @@ const pt = {
1265
1311
  "upsells.noExtras": "Sem extras disponíveis para esta reserva.",
1266
1312
  "upsells.selected": "{{count}} extra selecionado",
1267
1313
  "upsells.selectedPlural": "{{count}} extras selecionados",
1314
+ "upsells.savePercent": "Poupa {{percent}}%",
1315
+ "booking.paymentUnavailable": "O pagamento online não está disponível para esta reserva. Contacta-nos para concluir a reserva.",
1316
+ "booking.depositNotConfigured": "O pagamento de depósito online não está disponível para este evento. Contacta-nos para concluir a reserva.",
1268
1317
  "upsells.spotsFree": "{{count}} lugares disponíveis",
1269
1318
  "upsells.notAvailable": "Não disponível",
1270
1319
  "upsells.reason.outOfStock": "{{productName}} está esgotado",
@@ -1290,6 +1339,9 @@ const pt = {
1290
1339
  "promo.giftCode": "O teu codigo de oferta",
1291
1340
  "promo.copied": "Copiado!",
1292
1341
  "promo.copy": "Copiar",
1342
+ "trust.securePayment": "Pagamento seguro",
1343
+ "trust.paypal": "PayPal",
1344
+ "trust.stripe": "Stripe",
1293
1345
  };
1294
1346
 
1295
1347
  const sv = {
@@ -1349,6 +1401,8 @@ const sv = {
1349
1401
  "button.depositAndBook": "Betala handpenning & boka",
1350
1402
  "button.continueWithout": "Fortsätt utan tillägg",
1351
1403
  "button.continue": "Fortsätt",
1404
+ "button.continueToPayment": "Fortsätt till betalning",
1405
+ "button.backToDetails": "Tillbaka till uppgifter",
1352
1406
  "button.addExtras": "Lägg till tillägg",
1353
1407
  // Event types
1354
1408
  "events.noEventsAvailable": "Inga evenemang tillgängliga",
@@ -1358,6 +1412,7 @@ const sv = {
1358
1412
  "events.availableFrom": "Lediga platser från {{date}}",
1359
1413
  "events.noAvailableDates": "Inga datum lediga",
1360
1414
  "events.previewSectionTitle": "Specials & kommande datum",
1415
+ "events.seeMoreDates": "Se fler datum...",
1361
1416
  // Event instances
1362
1417
  "instances.title": "Välj datum",
1363
1418
  "instances.noAvailable": "Inga tillgängliga datum",
@@ -1411,6 +1466,10 @@ const sv = {
1411
1466
  "booking.maxSpotsReached": "Maximalt {{count}} platser tillgängliga.",
1412
1467
  "booking.comment": "Kommentar (valfritt)",
1413
1468
  "booking.commentPlaceholder": "Ytterligare anteckningar för bokningen...",
1469
+ "booking.stepDate": "Datum",
1470
+ "booking.stepUpsells": "Tillägg",
1471
+ "booking.stepDetails": "Uppgifter",
1472
+ "booking.stepPayment": "Betalning",
1414
1473
  // Booking summary
1415
1474
  "summary.title": "Bokningssammanfattning",
1416
1475
  "summary.subtotal": "Delsumma:",
@@ -1541,6 +1600,9 @@ const sv = {
1541
1600
  "upsells.noExtras": "Inga tillägg tillgängliga för denna bokning.",
1542
1601
  "upsells.selected": "{{count}} tillägg valt",
1543
1602
  "upsells.selectedPlural": "{{count}} tillägg valda",
1603
+ "upsells.savePercent": "Spara {{percent}}%",
1604
+ "booking.paymentUnavailable": "Onlinebetalning är inte tillgänglig för denna bokning. Kontakta oss för att slutföra bokningen.",
1605
+ "booking.depositNotConfigured": "Online deposition är inte tillgänglig för detta evenemang. Kontakta oss för att slutföra bokningen.",
1544
1606
  "upsells.spotsFree": "{{count}} platser lediga",
1545
1607
  "upsells.notAvailable": "Inte tillgängligt",
1546
1608
  "upsells.reason.outOfStock": "{{productName}} är slut i lager",
@@ -1566,6 +1628,9 @@ const sv = {
1566
1628
  "promo.giftCode": "Din presentkod",
1567
1629
  "promo.copied": "Kopierad!",
1568
1630
  "promo.copy": "Kopiera",
1631
+ "trust.securePayment": "Säker betalning",
1632
+ "trust.paypal": "PayPal",
1633
+ "trust.stripe": "Stripe",
1569
1634
  };
1570
1635
 
1571
1636
  const SUPPORTED_LOCALES = ["de", "en", "es", "sv", "pt"];
@@ -7264,6 +7329,55 @@ function Accordion({ title, priceInfo, children, isOpen, onToggle, }) {
7264
7329
  }, children: children }))] }));
7265
7330
  }
7266
7331
 
7332
+ function FlowProgress({ currentStep, hasUpsellsStep }) {
7333
+ const t = useTranslations();
7334
+ const steps = hasUpsellsStep
7335
+ ? [
7336
+ { key: "date", label: t("booking.stepDate") },
7337
+ { key: "upsells", label: t("booking.stepUpsells") },
7338
+ { key: "details", label: t("booking.stepDetails") },
7339
+ { key: "payment", label: t("booking.stepPayment") },
7340
+ ]
7341
+ : [
7342
+ { key: "date", label: t("booking.stepDate") },
7343
+ { key: "details", label: t("booking.stepDetails") },
7344
+ { key: "payment", label: t("booking.stepPayment") },
7345
+ ];
7346
+ const activeIndex = Math.max(steps.findIndex((step) => step.key === currentStep), 0);
7347
+ const progressPercent = steps.length > 1 ? (activeIndex / (steps.length - 1)) * 100 : 100;
7348
+ return (jsxRuntime.jsxs("div", { style: {
7349
+ backgroundColor: "var(--bw-surface-color)",
7350
+ border: "1px solid var(--bw-border-color)",
7351
+ borderRadius: "var(--bw-border-radius)",
7352
+ padding: "12px 14px",
7353
+ marginBottom: "16px",
7354
+ }, children: [jsxRuntime.jsx("div", { style: {
7355
+ display: "flex",
7356
+ justifyContent: "space-between",
7357
+ alignItems: "center",
7358
+ marginBottom: "10px",
7359
+ fontFamily: "var(--bw-font-family)",
7360
+ gap: "8px",
7361
+ }, children: steps.map((step, index) => (jsxRuntime.jsxs("span", { style: {
7362
+ fontSize: "12px",
7363
+ fontWeight: 700,
7364
+ color: index <= activeIndex ? "var(--bw-highlight-color)" : "var(--bw-text-muted)",
7365
+ whiteSpace: "nowrap",
7366
+ }, children: [index + 1, ". ", step.label] }, step.key))) }), jsxRuntime.jsx("div", { style: {
7367
+ width: "100%",
7368
+ height: "8px",
7369
+ borderRadius: "999px",
7370
+ backgroundColor: "var(--bw-background-color)",
7371
+ border: "1px solid var(--bw-border-color)",
7372
+ overflow: "hidden",
7373
+ }, children: jsxRuntime.jsx("div", { style: {
7374
+ width: `${progressPercent}%`,
7375
+ height: "100%",
7376
+ backgroundColor: "var(--bw-highlight-color)",
7377
+ transition: "width 0.25s ease",
7378
+ } }) })] }));
7379
+ }
7380
+
7267
7381
  // Spinner icon (kept local as it has animation style)
7268
7382
  const IconSpinner = ({ size = 16, color = "currentColor" }) => (jsxRuntime.jsx("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: color, strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", style: { animation: "spin 1s linear infinite" }, children: jsxRuntime.jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
7269
7383
  function VoucherInput({ config, orderValue, eventInstanceId, customerEmail, onVoucherValidated, appliedVouchers, onRemoveVoucher, disabled = false, }) {
@@ -11473,11 +11587,12 @@ const sectionHeaderStyles$1 = sectionStyles.header;
11473
11587
  const labelStyles$1 = formStyles.label;
11474
11588
  const inputStyles$1 = formStyles.input;
11475
11589
  const errorTextStyles$1 = formStyles.error;
11476
- function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError, onBackToEventInstances, onBackToEventTypes, selectedEventType, selectedEventInstance, isOpen, onClose, systemConfig, selectedUpsells = [], upsells = [], }) {
11590
+ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError, isOpen, onClose, systemConfig, selectedUpsells = [], upsells = [], persistedState = null, onPersistedStateChange, }) {
11477
11591
  const t$1 = useTranslations();
11478
11592
  const { locale } = useLocale();
11479
11593
  const timezone = useTimezone();
11480
11594
  const roundEnabled = systemConfig?.roundPricesEnabled !== false;
11595
+ const widgetPaymentMode = systemConfig?.widgetPaymentMode ?? "all";
11481
11596
  const participantFieldsConfig = eventDetails.participantFieldsConfig ?? DEFAULT_PARTICIPANT_FIELDS_CONFIG;
11482
11597
  const participantLevelOptions = eventDetails.participantLevelOptions ?? ["beginner", "advanced"];
11483
11598
  const roundDiscountUp = (minorUnits) => Math.ceil(minorUnits / 100) * 100;
@@ -11485,15 +11600,17 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11485
11600
  const raw = Math.round((baseAmount * basisPoints) / 10000);
11486
11601
  return round ? roundDiscountUp(raw) : raw;
11487
11602
  };
11488
- const [appliedVouchers, setAppliedVouchers] = React.useState([]);
11489
- const paymentSectionRef = React.useRef(null);
11603
+ const [appliedVouchers, setAppliedVouchers] = React.useState(() => persistedState?.appliedVouchers ?? []);
11604
+ const [checkoutStep, setCheckoutStep] = React.useState(() => persistedState?.checkoutStep ?? "details");
11490
11605
  // Payment option: "deposit" or "full" - only relevant when deposit is available
11491
- const [paymentOption, setPaymentOption] = React.useState("deposit");
11606
+ const [paymentOption, setPaymentOption] = React.useState(() => persistedState?.paymentOption ?? "deposit");
11492
11607
  // Per-participant upsell selections: participantIndex -> array of upsell package IDs
11493
- const [participantUpsells, setParticipantUpsells] = React.useState({});
11608
+ const [participantUpsells, setParticipantUpsells] = React.useState(() => persistedState?.participantUpsells ?? {});
11609
+ const [showPaymentValidationHint, setShowPaymentValidationHint] = React.useState(false);
11610
+ const wasOpenRef = React.useRef(false);
11494
11611
  const form = useForm({
11495
11612
  resolver: t(createBookingFormSchema(t$1, participantFieldsConfig)),
11496
- defaultValues: {
11613
+ defaultValues: persistedState?.formData ?? {
11497
11614
  customerName: "",
11498
11615
  customerEmail: "",
11499
11616
  customerPhone: "",
@@ -11503,6 +11620,28 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11503
11620
  acceptTerms: false,
11504
11621
  },
11505
11622
  });
11623
+ const persistState = React.useCallback(() => {
11624
+ onPersistedStateChange?.({
11625
+ formData: form.getValues(),
11626
+ checkoutStep,
11627
+ paymentOption,
11628
+ appliedVouchers,
11629
+ participantUpsells,
11630
+ });
11631
+ }, [onPersistedStateChange, form, checkoutStep, paymentOption, appliedVouchers, participantUpsells]);
11632
+ React.useEffect(() => {
11633
+ if (isOpen && !wasOpenRef.current && persistedState) {
11634
+ form.reset(persistedState.formData);
11635
+ setCheckoutStep(persistedState.checkoutStep);
11636
+ setPaymentOption(persistedState.paymentOption);
11637
+ setAppliedVouchers(persistedState.appliedVouchers);
11638
+ setParticipantUpsells(persistedState.participantUpsells);
11639
+ }
11640
+ if (!isOpen && wasOpenRef.current) {
11641
+ persistState();
11642
+ }
11643
+ wasOpenRef.current = isOpen;
11644
+ }, [isOpen, persistedState, form, persistState]);
11506
11645
  const watchedParticipants = form.watch("participants");
11507
11646
  const participantCount = watchedParticipants.length;
11508
11647
  const watchedCustomerName = form.watch("customerName");
@@ -11591,12 +11730,22 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11591
11730
  const totalDiscount = calculateTotalDiscount();
11592
11731
  const totalAmount = calculateTotal();
11593
11732
  const depositAmount = calculateDeposit();
11594
- // Deposit stays fixed unless the discounted total is lower than the deposit
11595
- // (discount applies to total price, not to the deposit itself)
11596
- const hasDepositOption = depositAmount > 0 && depositAmount < totalAmount;
11597
- const paymentAmount = hasDepositOption && paymentOption === "deposit"
11598
- ? Math.min(depositAmount, totalAmount)
11599
- : totalAmount;
11733
+ const allowsDepositInWidget = widgetPaymentMode === "all" || widgetPaymentMode === "deposits_only";
11734
+ const allowsFullInWidget = widgetPaymentMode === "all" || widgetPaymentMode === "full_only";
11735
+ const hasConfiguredDeposit = depositAmount > 0;
11736
+ const hasDepositChoice = allowsDepositInWidget && hasConfiguredDeposit && depositAmount < totalAmount;
11737
+ const depositsOnlyBlocked = widgetPaymentMode === "deposits_only" && !hasConfiguredDeposit;
11738
+ React.useEffect(() => {
11739
+ if (widgetPaymentMode === "deposits_only") {
11740
+ setPaymentOption("deposit");
11741
+ }
11742
+ else if (widgetPaymentMode === "full_only") {
11743
+ setPaymentOption("full");
11744
+ }
11745
+ }, [widgetPaymentMode]);
11746
+ const paymentAmount = allowsFullInWidget && (!hasDepositChoice || paymentOption === "full" || !allowsDepositInWidget)
11747
+ ? totalAmount
11748
+ : Math.min(depositAmount, totalAmount);
11600
11749
  // Convert per-participant upsells to UpsellSelection[] format for API
11601
11750
  // Includes participantIndices to track which participants selected each upsell
11602
11751
  const aggregatedUpsellSelections = React.useCallback(() => {
@@ -11627,6 +11776,18 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11627
11776
  }), [watchedCustomerName, watchedCustomerEmail, watchedCustomerPhone, watchedParticipants, watchedComment]);
11628
11777
  const appliedDiscountCode = appliedVouchers.find((v) => v.type === "discount");
11629
11778
  const appliedGiftCards = appliedVouchers.filter((v) => v.type === "giftCard");
11779
+ const discountCodeProp = appliedDiscountCode
11780
+ ? {
11781
+ id: appliedDiscountCode.id,
11782
+ code: appliedDiscountCode.code,
11783
+ description: appliedDiscountCode.description || undefined,
11784
+ type: appliedDiscountCode.discountType || "percentage",
11785
+ value: appliedDiscountCode.discountValue || 0,
11786
+ discountAmount: appliedDiscountCode.discountAmount,
11787
+ newTotal: appliedDiscountCode.newTotal,
11788
+ }
11789
+ : null;
11790
+ const hasPaymentProvider = Boolean(stripePromise || systemConfig?.paymentProvider === "mollie");
11630
11791
  const handleVoucherValidated = React.useCallback((voucher, _error) => {
11631
11792
  if (voucher) {
11632
11793
  setAppliedVouchers((prev) => [...prev, voucher]);
@@ -11738,19 +11899,44 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11738
11899
  });
11739
11900
  }, [config]);
11740
11901
  const handleClose = () => {
11902
+ persistState();
11903
+ setCheckoutStep("details");
11741
11904
  onClose();
11742
- if (selectedEventInstance && selectedEventType) {
11743
- onBackToEventInstances?.();
11905
+ };
11906
+ // Footer navigation
11907
+ const canContinueToPayment = isReadyForPayment();
11908
+ const handleContinueToPayment = async () => {
11909
+ if (canContinueToPayment && hasPaymentProvider) {
11910
+ setShowPaymentValidationHint(false);
11911
+ setCheckoutStep("payment");
11912
+ return;
11744
11913
  }
11745
- else if (selectedEventType) {
11746
- onBackToEventTypes?.();
11914
+ const participantErrors = await form.trigger("participants");
11915
+ const customerErrors = await form.trigger(["customerName", "customerEmail", "acceptTerms"]);
11916
+ if (!participantErrors || !customerErrors) {
11917
+ setShowPaymentValidationHint(true);
11747
11918
  }
11748
11919
  };
11749
- const scrollToPayment = () => {
11750
- paymentSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
11751
- };
11752
- // Footer navigation
11753
- const footerContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: handleClose, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: t$1("common.back") }), jsxRuntime.jsx("button", { type: "button", onClick: scrollToPayment, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), children: t$1("button.toPayment") })] }));
11920
+ React.useEffect(() => {
11921
+ if (showPaymentValidationHint && canContinueToPayment) {
11922
+ setShowPaymentValidationHint(false);
11923
+ }
11924
+ }, [showPaymentValidationHint, canContinueToPayment]);
11925
+ const footerContent = (jsxRuntime.jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "6px" }, children: [checkoutStep === "details" && (jsxRuntime.jsx("div", { style: {
11926
+ minHeight: "14px",
11927
+ fontSize: "11px",
11928
+ color: "var(--bw-error-color)",
11929
+ textAlign: "center",
11930
+ fontFamily: "var(--bw-font-family)",
11931
+ opacity: showPaymentValidationHint ? 1 : 0,
11932
+ transition: "opacity 0.15s ease",
11933
+ pointerEvents: "none",
11934
+ }, children: t$1("payment.fillRequired") })), jsxRuntime.jsxs("div", { style: { display: "flex", gap: "12px", width: "100%" }, children: [jsxRuntime.jsx("button", { type: "button", onClick: checkoutStep === "payment" ? () => setCheckoutStep("details") : handleClose, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: checkoutStep === "payment" ? t$1("button.backToDetails") : t$1("common.back") }), checkoutStep === "details" && (jsxRuntime.jsx("button", { type: "button", onClick: handleContinueToPayment, disabled: !hasPaymentProvider, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth, !canContinueToPayment
11935
+ ? {
11936
+ opacity: 0.55,
11937
+ cursor: "pointer",
11938
+ }
11939
+ : undefined), children: t$1("button.continueToPayment") }))] })] }));
11754
11940
  if (!eventDetails.bookingOpen) {
11755
11941
  return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.notPossible"), children: jsxRuntime.jsx("div", { style: {
11756
11942
  display: "flex",
@@ -11767,264 +11953,211 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11767
11953
  fontFamily: "var(--bw-font-family)",
11768
11954
  }, children: t$1("booking.notPossible") }), jsxRuntime.jsx("p", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.notPossibleMessage") })] }) }) }));
11769
11955
  }
11770
- return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.title", { name: eventDetails.name }), footer: footerContent, children: jsxRuntime.jsxs("div", { className: "booking-widget-container", style: { padding: "16px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.eventDetails") }), jsxRuntime.jsxs("div", { style: {
11771
- display: "grid",
11772
- gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11773
- gap: "12px",
11774
- fontSize: "14px",
11775
- }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
11776
- color: "var(--bw-text-muted)",
11777
- fontFamily: "var(--bw-font-family)",
11778
- display: "flex",
11779
- alignItems: "center",
11780
- gap: "4px",
11781
- }, children: [jsxRuntime.jsx(IconCalendar, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.date")] }), jsxRuntime.jsxs("span", { style: {
11782
- color: "var(--bw-text-color)",
11783
- fontWeight: 500,
11784
- fontFamily: "var(--bw-font-family)",
11785
- }, children: [formatEventDate(eventDetails.startTime, timezone, locale), " \u2022 ", formatTime(eventDetails.startTime, timezone, locale)] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
11786
- color: "var(--bw-text-muted)",
11787
- fontFamily: "var(--bw-font-family)",
11788
- display: "flex",
11789
- alignItems: "center",
11790
- gap: "4px",
11791
- }, children: [jsxRuntime.jsx(IconClock, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.duration")] }), jsxRuntime.jsxs("span", { style: {
11792
- color: "var(--bw-text-color)",
11793
- fontWeight: 500,
11794
- fontFamily: "var(--bw-font-family)",
11795
- }, children: [eventDetails.durationDays, " ", eventDetails.durationDays > 1 ? t$1("common.days") : t$1("common.day")] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
11796
- color: "var(--bw-text-muted)",
11797
- fontFamily: "var(--bw-font-family)",
11956
+ return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.title", { name: eventDetails.name }), footer: footerContent, children: jsxRuntime.jsxs("div", { className: "booking-widget-container", style: { padding: "16px" }, children: [jsxRuntime.jsx(FlowProgress, { currentStep: checkoutStep === "details" ? "details" : "payment", hasUpsellsStep: upsells.length > 0 }), checkoutStep === "details" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.eventDetails") }), jsxRuntime.jsxs("div", { style: {
11957
+ display: "grid",
11958
+ gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11959
+ gap: "12px",
11960
+ fontSize: "14px",
11961
+ }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
11962
+ color: "var(--bw-text-muted)",
11963
+ fontFamily: "var(--bw-font-family)",
11964
+ display: "flex",
11965
+ alignItems: "center",
11966
+ gap: "4px",
11967
+ }, children: [jsxRuntime.jsx(IconCalendar, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.date")] }), jsxRuntime.jsxs("span", { style: {
11968
+ color: "var(--bw-text-color)",
11969
+ fontWeight: 500,
11970
+ fontFamily: "var(--bw-font-family)",
11971
+ }, children: [formatEventDate(eventDetails.startTime, timezone, locale), " \u2022 ", formatTime(eventDetails.startTime, timezone, locale)] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
11972
+ color: "var(--bw-text-muted)",
11973
+ fontFamily: "var(--bw-font-family)",
11974
+ display: "flex",
11975
+ alignItems: "center",
11976
+ gap: "4px",
11977
+ }, children: [jsxRuntime.jsx(IconClock, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.duration")] }), jsxRuntime.jsxs("span", { style: {
11978
+ color: "var(--bw-text-color)",
11979
+ fontWeight: 500,
11980
+ fontFamily: "var(--bw-font-family)",
11981
+ }, children: [eventDetails.durationDays, " ", eventDetails.durationDays > 1 ? t$1("common.days") : t$1("common.day")] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
11982
+ color: "var(--bw-text-muted)",
11983
+ fontFamily: "var(--bw-font-family)",
11984
+ display: "flex",
11985
+ alignItems: "center",
11986
+ gap: "4px",
11987
+ }, children: [jsxRuntime.jsx(IconMoney, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.price")] }), jsxRuntime.jsxs("span", { style: {
11988
+ color: "var(--bw-text-color)",
11989
+ fontWeight: 500,
11990
+ fontFamily: "var(--bw-font-family)",
11991
+ }, children: [formatCurrency(eventDetails.price), " ", t$1("common.perPerson")] })] })] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.contactInfo") }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "16px" }, children: [jsxRuntime.jsxs("div", { style: {
11992
+ display: "grid",
11993
+ gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11994
+ gap: "16px",
11995
+ }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerName", style: labelStyles$1, children: t$1("booking.name") }), jsxRuntime.jsx("input", { id: "customerName", ...form.register("customerName"), type: "text", style: inputStyles$1, placeholder: t$1("booking.namePlaceholder") }), customerNameError && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: customerNameError.message }))] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerEmail", style: labelStyles$1, children: t$1("booking.email") }), jsxRuntime.jsx("input", { id: "customerEmail", ...form.register("customerEmail"), type: "email", style: inputStyles$1, placeholder: t$1("booking.emailPlaceholder") }), customerEmailError && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: customerEmailError.message }))] })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerPhone", style: labelStyles$1, children: t$1("booking.phone") }), jsxRuntime.jsx("input", { id: "customerPhone", ...form.register("customerPhone"), type: "tel", style: inputStyles$1, placeholder: t$1("booking.phonePlaceholder") })] }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", border: "1px solid var(--bw-border-color)", padding: "16px", borderRadius: "var(--bw-border-radius)" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("input", { id: "acceptTerms", ...form.register("acceptTerms"), type: "checkbox", style: formStyles.checkbox }), jsxRuntime.jsxs("label", { htmlFor: "acceptTerms", style: {
11996
+ fontSize: "14px",
11997
+ color: "var(--bw-text-muted)",
11998
+ fontFamily: "var(--bw-font-family)",
11999
+ maxWidth: "calc(100% - 32px)",
12000
+ overflowWrap: "break-word",
12001
+ cursor: "pointer",
12002
+ }, children: [t$1("booking.acceptTerms"), " ", jsxRuntime.jsx("a", { href: eventDetails.agbUrl || "/terms", style: { color: "var(--bw-highlight-color)", textDecoration: "none" }, target: "_blank", rel: "noopener noreferrer", children: t$1("booking.terms") }), "*"] })] }), form.formState.errors.acceptTerms && (jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, marginTop: "8px" }, children: form.formState.errors.acceptTerms.message }))] })] })] }), jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("div", { style: {
11798
12003
  display: "flex",
12004
+ justifyContent: "space-between",
11799
12005
  alignItems: "center",
11800
- gap: "4px",
11801
- }, children: [jsxRuntime.jsx(IconMoney, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.price")] }), jsxRuntime.jsxs("span", { style: {
11802
- color: "var(--bw-text-color)",
11803
- fontWeight: 500,
11804
- fontFamily: "var(--bw-font-family)",
11805
- }, children: [formatCurrency(eventDetails.price), " ", t$1("common.perPerson")] })] })] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.contactInfo") }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "16px" }, children: [jsxRuntime.jsxs("div", { style: {
11806
- display: "grid",
11807
- gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11808
- gap: "16px",
11809
- }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerName", style: labelStyles$1, children: t$1("booking.name") }), jsxRuntime.jsx("input", { id: "customerName", ...form.register("customerName"), type: "text", style: inputStyles$1, placeholder: t$1("booking.namePlaceholder") }), customerNameError && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: customerNameError.message }))] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerEmail", style: labelStyles$1, children: t$1("booking.email") }), jsxRuntime.jsx("input", { id: "customerEmail", ...form.register("customerEmail"), type: "email", style: inputStyles$1, placeholder: t$1("booking.emailPlaceholder") }), customerEmailError && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: customerEmailError.message }))] })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerPhone", style: labelStyles$1, children: t$1("booking.phone") }), jsxRuntime.jsx("input", { id: "customerPhone", ...form.register("customerPhone"), type: "tel", style: inputStyles$1, placeholder: t$1("booking.phonePlaceholder") })] }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", border: "1px solid var(--bw-border-color)", padding: "16px", borderRadius: "var(--bw-border-radius)" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("input", { id: "acceptTerms", ...form.register("acceptTerms"), type: "checkbox", style: formStyles.checkbox }), jsxRuntime.jsxs("label", { htmlFor: "acceptTerms", style: {
12006
+ marginBottom: "16px",
12007
+ }, children: jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: 0 }, children: t$1("booking.participants") }) }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [watchedParticipants.map((_, index) => (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [participantFieldsConfig.name.enabled && (jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-name-${index}`, style: labelStyles$1, children: t$1("booking.participantName") }), jsxRuntime.jsx("input", { id: `participant-name-${index}`, ...form.register(`participants.${index}.name`), type: "text", style: inputStyles$1, placeholder: t$1("booking.participantNamePlaceholder") }), form.formState.errors.participants?.[index]?.name && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.name?.message }))] })), participantFieldsConfig.age.enabled && (jsxRuntime.jsxs("div", { style: { width: "80px" }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-age-${index}`, style: labelStyles$1, children: t$1("booking.participantAge") }), jsxRuntime.jsx("input", { id: `participant-age-${index}`, ...form.register(`participants.${index}.age`, {
12008
+ setValueAs: (value) => {
12009
+ if (value === "" || value === null || value === undefined) {
12010
+ return undefined;
12011
+ }
12012
+ const num = Number(value);
12013
+ return Number.isNaN(num) ? undefined : num;
12014
+ },
12015
+ }), type: "number", min: "0", max: "120", style: inputStyles$1, placeholder: "25" })] })), watchedParticipants.length > 1 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { style: { ...labelStyles$1, visibility: "hidden" }, children: "\u00A0" }), jsxRuntime.jsx("button", { type: "button", onClick: () => removeParticipant(index), style: {
12016
+ color: "var(--bw-error-color)",
12017
+ backgroundColor: "var(--bw-surface-color)",
12018
+ border: "1px solid var(--bw-border-color)",
12019
+ borderRadius: "50%",
12020
+ width: "36px",
12021
+ height: "36px",
12022
+ display: "flex",
12023
+ alignItems: "center",
12024
+ justifyContent: "center",
12025
+ cursor: "pointer",
12026
+ transition: "all 0.2s ease",
12027
+ fontSize: "24px",
12028
+ fontWeight: 700,
12029
+ fontFamily: "var(--bw-font-family)",
12030
+ padding: 0,
12031
+ }, children: "\u00D7" })] }))] }), participantFieldsConfig.level.enabled && (jsxRuntime.jsxs("div", { style: { minWidth: "140px" }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-level-${index}`, style: labelStyles$1, children: t$1("booking.participantLevel") }), jsxRuntime.jsxs("select", { id: `participant-level-${index}`, ...form.register(`participants.${index}.level`), style: inputStyles$1, children: [jsxRuntime.jsx("option", { value: "", children: t$1("booking.participantLevelPlaceholder") }), participantLevelOptions.map((level) => (jsxRuntime.jsx("option", { value: level, children: t$1(`level.${level}`) }, level)))] }), form.formState.errors.participants?.[index]?.level && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.level?.message }))] })), upsells.length > 0 && (jsxRuntime.jsx("div", { style: participantUpsellStyles.container, children: upsells.map((upsell) => {
12032
+ const isSelected = (participantUpsells[index] || []).includes(upsell.id);
12033
+ return (jsxRuntime.jsxs("label", { htmlFor: `upsell-${index}-${upsell.id}`, style: isSelected ? participantUpsellStyles.labelSelected : participantUpsellStyles.label, children: [jsxRuntime.jsx("input", { id: `upsell-${index}-${upsell.id}`, type: "checkbox", style: participantUpsellStyles.checkbox, checked: isSelected, onChange: () => toggleParticipantUpsell(index, upsell.id) }), jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: upsell.name }), jsxRuntime.jsxs("span", { style: { fontSize: "12px", opacity: 0.8 }, children: ["(+", formatCurrency(upsell.price), ")"] })] }, upsell.id));
12034
+ }) }))] }, index))), watchedParticipants.length < eventDetails.availableSpots ? (jsxRuntime.jsx("div", { style: {
12035
+ display: "flex",
12036
+ flexDirection: "column",
12037
+ alignItems: "center",
12038
+ marginTop: "12px",
12039
+ }, children: jsxRuntime.jsx("button", { type: "button", onClick: addParticipant, style: {
12040
+ color: "#ffffff",
12041
+ fontSize: "14px",
12042
+ fontWeight: 600,
12043
+ padding: "8px 16px",
12044
+ borderRadius: "var(--bw-border-radius)",
12045
+ backgroundColor: "var(--bw-highlight-color)",
12046
+ border: "1px solid var(--bw-highlight-color)",
12047
+ cursor: "pointer",
12048
+ transition: "all 0.2s ease",
12049
+ marginBottom: "4px",
12050
+ fontFamily: "var(--bw-font-family)",
12051
+ boxShadow: "0 2px 8px 0 var(--bw-highlight-color)",
12052
+ }, children: t$1("booking.addParticipant", { number: watchedParticipants.length + 1 }) }) })) : (jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.maxSpotsReached", { count: eventDetails.availableSpots }) }))] })] }), jsxRuntime.jsx(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("label", { htmlFor: "booking-comment", style: labelStyles$1, children: t$1("booking.comment") }), jsxRuntime.jsx("textarea", { id: "booking-comment", ...form.register("comment"), placeholder: t$1("booking.commentPlaceholder"), rows: 3, style: {
12053
+ ...inputStyles$1,
12054
+ resize: "vertical",
12055
+ minHeight: "80px",
12056
+ } })] })] })] })), checkoutStep === "payment" && (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: "16px" }, children: t$1("summary.title") }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "12px" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.price") }), jsxRuntime.jsxs("div", { style: {
12057
+ color: "var(--bw-text-color)",
12058
+ fontWeight: 500,
12059
+ fontFamily: "var(--bw-font-family)",
12060
+ }, children: [jsxRuntime.jsxs("span", { style: { fontWeight: 200 }, children: [watchedParticipants.length > 1 ? watchedParticipants.length : 1, " x "] }), " ", formatCurrency(eventDetails.price)] })] }), upsellsTotal > 0 && (jsxRuntime.jsxs("div", { style: { marginTop: "8px", paddingTop: "8px", borderTop: "1px dashed var(--bw-border-color)" }, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)", fontSize: "13px", display: "block", marginBottom: "4px" }, children: [t$1("common.extras"), ":"] }), upsells.map((upsell) => {
12061
+ // Count how many participants have this upsell selected
12062
+ const countWithUpsell = watchedParticipants.filter((_, idx) => (participantUpsells[idx] || []).includes(upsell.id)).length;
12063
+ if (countWithUpsell === 0)
12064
+ return null;
12065
+ const upsellLineTotal = upsell.price * countWithUpsell;
12066
+ return (jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "2px", fontSize: "13px" }, children: jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+ ", upsell.name, " (", countWithUpsell, "\u00D7)"] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(upsellLineTotal) })] }) }, upsell.id));
12067
+ })] })), appliedVouchers.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.subtotal") }), jsxRuntime.jsx("span", { style: {
12068
+ fontFamily: "var(--bw-font-family)",
12069
+ color: totalDiscount > 0 ? "var(--bw-text-muted)" : "var(--bw-text-muted)",
12070
+ textDecoration: totalDiscount > 0 ? "line-through" : "none",
12071
+ }, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
12072
+ color: "var(--bw-success-color)",
12073
+ fontFamily: "var(--bw-font-family)",
12074
+ fontSize: "14px",
12075
+ }, children: t$1("summary.discount", { code: appliedDiscountCode.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
12076
+ color: "var(--bw-success-color)",
12077
+ fontFamily: "var(--bw-font-family)",
11810
12078
  fontSize: "14px",
12079
+ }, children: t$1("summary.giftCard", { code: giftCard.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), jsxRuntime.jsxs("div", { style: {
12080
+ borderTop: "1px solid var(--bw-border-color)",
12081
+ paddingTop: "12px",
12082
+ }, children: [hasDepositChoice && (jsxRuntime.jsxs("div", { style: {
12083
+ display: "flex",
12084
+ justifyContent: "space-between",
12085
+ alignItems: "center",
12086
+ fontSize: "14px",
12087
+ marginBottom: "12px",
12088
+ }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
11811
12089
  color: "var(--bw-text-muted)",
11812
12090
  fontFamily: "var(--bw-font-family)",
11813
- maxWidth: "calc(100% - 32px)",
11814
- overflowWrap: "break-word",
12091
+ fontWeight: 500,
12092
+ }, children: formatCurrency(totalAmount) })] })), hasDepositChoice && widgetPaymentMode === "all" && (jsxRuntime.jsxs("div", { style: {
12093
+ display: "flex",
12094
+ gap: "8px",
12095
+ marginBottom: "16px",
12096
+ }, children: [jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("deposit"), style: {
12097
+ flex: 1,
12098
+ padding: "12px",
12099
+ borderRadius: "var(--bw-border-radius)",
12100
+ border: paymentOption === "deposit"
12101
+ ? "2px solid var(--bw-highlight-color)"
12102
+ : "1px solid var(--bw-border-color)",
12103
+ backgroundColor: paymentOption === "deposit"
12104
+ ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
12105
+ : "var(--bw-surface-color)",
11815
12106
  cursor: "pointer",
11816
- }, children: [t$1("booking.acceptTerms"), " ", jsxRuntime.jsx("a", { href: eventDetails.agbUrl || "/terms", style: { color: "var(--bw-highlight-color)", textDecoration: "none" }, target: "_blank", rel: "noopener noreferrer", children: t$1("booking.terms") }), "*"] })] }), form.formState.errors.acceptTerms && (jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, marginTop: "8px" }, children: form.formState.errors.acceptTerms.message }))] })] })] }), jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("div", { style: {
11817
- display: "flex",
11818
- justifyContent: "space-between",
11819
- alignItems: "center",
11820
- marginBottom: "16px",
11821
- }, children: jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: 0 }, children: t$1("booking.participants") }) }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [watchedParticipants.map((_, index) => (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [participantFieldsConfig.name.enabled && (jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-name-${index}`, style: labelStyles$1, children: t$1("booking.participantName") }), jsxRuntime.jsx("input", { id: `participant-name-${index}`, ...form.register(`participants.${index}.name`), type: "text", style: inputStyles$1, placeholder: t$1("booking.participantNamePlaceholder") }), form.formState.errors.participants?.[index]?.name && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.name?.message }))] })), participantFieldsConfig.age.enabled && (jsxRuntime.jsxs("div", { style: { width: "80px" }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-age-${index}`, style: labelStyles$1, children: t$1("booking.participantAge") }), jsxRuntime.jsx("input", { id: `participant-age-${index}`, ...form.register(`participants.${index}.age`, {
11822
- setValueAs: (value) => {
11823
- if (value === "" || value === null || value === undefined) {
11824
- return undefined;
11825
- }
11826
- const num = Number(value);
11827
- return Number.isNaN(num) ? undefined : num;
11828
- },
11829
- }), type: "number", min: "0", max: "120", style: inputStyles$1, placeholder: "25" })] })), watchedParticipants.length > 1 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { style: { ...labelStyles$1, visibility: "hidden" }, children: "\u00A0" }), jsxRuntime.jsx("button", { type: "button", onClick: () => removeParticipant(index), style: {
11830
- color: "var(--bw-error-color)",
11831
- backgroundColor: "var(--bw-surface-color)",
11832
- border: "1px solid var(--bw-border-color)",
11833
- borderRadius: "50%",
11834
- width: "36px",
11835
- height: "36px",
11836
- display: "flex",
11837
- alignItems: "center",
11838
- justifyContent: "center",
11839
- cursor: "pointer",
11840
- transition: "all 0.2s ease",
11841
- fontSize: "24px",
12107
+ fontFamily: "var(--bw-font-family)",
12108
+ transition: "all 0.2s ease",
12109
+ }, children: [jsxRuntime.jsx("div", { style: {
12110
+ fontSize: "13px",
12111
+ color: "var(--bw-text-muted)",
12112
+ marginBottom: "4px",
12113
+ }, children: t$1("summary.deposit") }), jsxRuntime.jsx("div", { style: {
12114
+ fontSize: "18px",
11842
12115
  fontWeight: 700,
11843
- fontFamily: "var(--bw-font-family)",
11844
- padding: 0,
11845
- }, children: "\u00D7" })] }))] }), participantFieldsConfig.level.enabled && (jsxRuntime.jsxs("div", { style: { minWidth: "140px" }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-level-${index}`, style: labelStyles$1, children: t$1("booking.participantLevel") }), jsxRuntime.jsxs("select", { id: `participant-level-${index}`, ...form.register(`participants.${index}.level`), style: inputStyles$1, children: [jsxRuntime.jsx("option", { value: "", children: t$1("booking.participantLevelPlaceholder") }), participantLevelOptions.map((level) => (jsxRuntime.jsx("option", { value: level, children: t$1(`level.${level}`) }, level)))] }), form.formState.errors.participants?.[index]?.level && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.level?.message }))] })), upsells.length > 0 && (jsxRuntime.jsx("div", { style: participantUpsellStyles.container, children: upsells.map((upsell) => {
11846
- const isSelected = (participantUpsells[index] || []).includes(upsell.id);
11847
- return (jsxRuntime.jsxs("label", { htmlFor: `upsell-${index}-${upsell.id}`, style: isSelected ? participantUpsellStyles.labelSelected : participantUpsellStyles.label, children: [jsxRuntime.jsx("input", { id: `upsell-${index}-${upsell.id}`, type: "checkbox", style: participantUpsellStyles.checkbox, checked: isSelected, onChange: () => toggleParticipantUpsell(index, upsell.id) }), jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: upsell.name }), jsxRuntime.jsxs("span", { style: { fontSize: "12px", opacity: 0.8 }, children: ["(+", formatCurrency(upsell.price), ")"] })] }, upsell.id));
11848
- }) }))] }, index))), watchedParticipants.length < eventDetails.availableSpots ? (jsxRuntime.jsx("div", { style: {
11849
- display: "flex",
11850
- flexDirection: "column",
11851
- alignItems: "center",
11852
- marginTop: "12px",
11853
- }, children: jsxRuntime.jsx("button", { type: "button", onClick: addParticipant, style: {
11854
- color: "#ffffff",
11855
- fontSize: "14px",
11856
- fontWeight: 600,
11857
- padding: "8px 16px",
11858
- borderRadius: "var(--bw-border-radius)",
11859
- backgroundColor: "var(--bw-highlight-color)",
11860
- border: "1px solid var(--bw-highlight-color)",
11861
- cursor: "pointer",
11862
- transition: "all 0.2s ease",
11863
- marginBottom: "4px",
11864
- fontFamily: "var(--bw-font-family)",
11865
- boxShadow: "0 2px 8px 0 var(--bw-highlight-color)",
11866
- }, children: t$1("booking.addParticipant", { number: watchedParticipants.length + 1 }) }) })) : (jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.maxSpotsReached", { count: eventDetails.availableSpots }) }))] })] }), jsxRuntime.jsx(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("label", { htmlFor: "booking-comment", style: labelStyles$1, children: t$1("booking.comment") }), jsxRuntime.jsx("textarea", { id: "booking-comment", ...form.register("comment"), placeholder: t$1("booking.commentPlaceholder"), rows: 3, style: {
11867
- ...inputStyles$1,
11868
- resize: "vertical",
11869
- minHeight: "80px",
11870
- } })] }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: "16px" }, children: t$1("summary.title") }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "12px" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.price") }), jsxRuntime.jsxs("div", { style: {
11871
- color: "var(--bw-text-color)",
11872
- fontWeight: 500,
12116
+ color: paymentOption === "deposit"
12117
+ ? "var(--bw-highlight-color)"
12118
+ : "var(--bw-text-color)",
12119
+ }, children: formatCurrency(depositAmount) })] }), jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("full"), style: {
12120
+ flex: 1,
12121
+ padding: "12px",
12122
+ borderRadius: "var(--bw-border-radius)",
12123
+ border: paymentOption === "full"
12124
+ ? "2px solid var(--bw-highlight-color)"
12125
+ : "1px solid var(--bw-border-color)",
12126
+ backgroundColor: paymentOption === "full"
12127
+ ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
12128
+ : "var(--bw-surface-color)",
12129
+ cursor: "pointer",
11873
12130
  fontFamily: "var(--bw-font-family)",
11874
- }, children: [jsxRuntime.jsxs("span", { style: { fontWeight: 200 }, children: [watchedParticipants.length > 1 ? watchedParticipants.length : 1, " x "] }), " ", formatCurrency(eventDetails.price)] })] }), upsellsTotal > 0 && (jsxRuntime.jsxs("div", { style: { marginTop: "8px", paddingTop: "8px", borderTop: "1px dashed var(--bw-border-color)" }, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)", fontSize: "13px", display: "block", marginBottom: "4px" }, children: [t$1("common.extras"), ":"] }), upsells.map((upsell) => {
11875
- // Count how many participants have this upsell selected
11876
- const countWithUpsell = watchedParticipants.filter((_, idx) => (participantUpsells[idx] || []).includes(upsell.id)).length;
11877
- if (countWithUpsell === 0)
11878
- return null;
11879
- const upsellLineTotal = upsell.price * countWithUpsell;
11880
- return (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", fontSize: "13px" }, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+ ", upsell.name, " (", countWithUpsell, "\u00D7)"] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(upsellLineTotal) })] }, upsell.id));
11881
- })] })), appliedVouchers.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.subtotal") }), jsxRuntime.jsx("span", { style: {
11882
- fontFamily: "var(--bw-font-family)",
11883
- color: totalDiscount > 0 ? "var(--bw-text-muted)" : "var(--bw-text-muted)",
11884
- textDecoration: totalDiscount > 0 ? "line-through" : "none",
11885
- }, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
11886
- color: "var(--bw-success-color)",
11887
- fontFamily: "var(--bw-font-family)",
11888
- fontSize: "14px",
11889
- }, children: t$1("summary.discount", { code: appliedDiscountCode.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
11890
- color: "var(--bw-success-color)",
11891
- fontFamily: "var(--bw-font-family)",
11892
- fontSize: "14px",
11893
- }, children: t$1("summary.giftCard", { code: giftCard.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), jsxRuntime.jsxs("div", { style: {
11894
- borderTop: "1px solid var(--bw-border-color)",
11895
- paddingTop: "12px",
11896
- }, children: [hasDepositOption && (jsxRuntime.jsxs("div", { style: {
11897
- display: "flex",
11898
- gap: "8px",
11899
- marginBottom: "16px",
11900
- }, children: [jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("deposit"), style: {
11901
- flex: 1,
11902
- padding: "12px",
11903
- borderRadius: "var(--bw-border-radius)",
11904
- border: paymentOption === "deposit"
11905
- ? "2px solid var(--bw-highlight-color)"
11906
- : "1px solid var(--bw-border-color)",
11907
- backgroundColor: paymentOption === "deposit"
11908
- ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
11909
- : "var(--bw-surface-color)",
11910
- cursor: "pointer",
11911
- fontFamily: "var(--bw-font-family)",
11912
- transition: "all 0.2s ease",
11913
- }, children: [jsxRuntime.jsx("div", { style: {
11914
- fontSize: "13px",
11915
- color: "var(--bw-text-muted)",
11916
- marginBottom: "4px",
11917
- }, children: t$1("summary.deposit") }), jsxRuntime.jsx("div", { style: {
11918
- fontSize: "18px",
11919
- fontWeight: 700,
11920
- color: paymentOption === "deposit"
11921
- ? "var(--bw-highlight-color)"
11922
- : "var(--bw-text-color)",
11923
- }, children: formatCurrency(depositAmount) })] }), jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("full"), style: {
11924
- flex: 1,
11925
- padding: "12px",
11926
- borderRadius: "var(--bw-border-radius)",
11927
- border: paymentOption === "full"
11928
- ? "2px solid var(--bw-highlight-color)"
11929
- : "1px solid var(--bw-border-color)",
11930
- backgroundColor: paymentOption === "full"
11931
- ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
11932
- : "var(--bw-surface-color)",
11933
- cursor: "pointer",
11934
- fontFamily: "var(--bw-font-family)",
11935
- transition: "all 0.2s ease",
11936
- }, children: [jsxRuntime.jsx("div", { style: {
11937
- fontSize: "13px",
11938
- color: "var(--bw-text-muted)",
11939
- marginBottom: "4px",
11940
- }, children: t$1("summary.payFull") }), jsxRuntime.jsx("div", { style: {
11941
- fontSize: "18px",
11942
- fontWeight: 700,
11943
- color: paymentOption === "full"
11944
- ? "var(--bw-highlight-color)"
11945
- : "var(--bw-text-color)",
11946
- }, children: formatCurrency(totalAmount) })] })] })), hasDepositOption && paymentOption === "deposit" && (jsxRuntime.jsxs("div", { style: {
11947
- display: "flex",
11948
- justifyContent: "space-between",
11949
- alignItems: "center",
11950
- fontSize: "14px",
11951
- marginBottom: "8px",
11952
- }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
12131
+ transition: "all 0.2s ease",
12132
+ }, children: [jsxRuntime.jsx("div", { style: {
12133
+ fontSize: "13px",
11953
12134
  color: "var(--bw-text-muted)",
11954
- fontFamily: "var(--bw-font-family)",
11955
- fontWeight: 500,
11956
- }, children: formatCurrency(totalAmount) })] })), jsxRuntime.jsxs("div", { style: {
11957
- display: "flex",
11958
- justifyContent: "space-between",
11959
- alignItems: "center",
11960
- fontSize: "18px",
11961
- fontWeight: 600,
11962
- }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: hasDepositOption && paymentOption === "deposit"
11963
- ? t$1("summary.payToday")
11964
- : t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
11965
- color: "var(--bw-highlight-color)",
11966
- fontFamily: "var(--bw-font-family)",
12135
+ marginBottom: "4px",
12136
+ }, children: t$1("summary.payFull") }), jsxRuntime.jsx("div", { style: {
12137
+ fontSize: "18px",
11967
12138
  fontWeight: 700,
11968
- }, children: formatCurrency(paymentAmount) })] }), hasDepositOption && paymentOption === "deposit" && (jsxRuntime.jsx("div", { style: {
11969
- fontSize: "12px",
11970
- color: "var(--bw-text-muted)",
12139
+ color: paymentOption === "full"
12140
+ ? "var(--bw-highlight-color)"
12141
+ : "var(--bw-text-color)",
12142
+ }, children: formatCurrency(totalAmount) })] })] })), jsxRuntime.jsxs("div", { style: {
12143
+ display: "flex",
12144
+ justifyContent: "space-between",
12145
+ alignItems: "center",
12146
+ fontSize: "18px",
12147
+ fontWeight: 600,
12148
+ }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: hasDepositChoice && paymentOption === "deposit"
12149
+ ? t$1("summary.payToday")
12150
+ : t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
12151
+ color: "var(--bw-highlight-color)",
11971
12152
  fontFamily: "var(--bw-font-family)",
11972
- marginTop: "8px",
11973
- textAlign: "right",
11974
- }, children: t$1("summary.remainingOnSite", { amount: formatCurrency(totalAmount - depositAmount) }) }))] })] })] }), jsxRuntime.jsx("div", { ref: paymentSectionRef, children: (stripePromise || systemConfig?.paymentProvider === "mollie") &&
11975
- (() => {
11976
- if (!isReadyForPayment()) {
11977
- const participantsWithNames = watchedParticipants.filter((p) => p.name?.trim()).length;
11978
- const totalParticipantRows = watchedParticipants.length;
11979
- const participantsWithoutNames = totalParticipantRows - participantsWithNames;
11980
- const missing = [];
11981
- if (participantFieldsConfig.name.required) {
11982
- if (participantsWithNames === 0) {
11983
- missing.push(t$1("payment.needParticipant"));
11984
- }
11985
- else if (participantsWithoutNames > 0) {
11986
- missing.push(t$1("payment.needAllNames", { count: totalParticipantRows }));
11987
- }
11988
- }
11989
- if (participantsWithNames > (eventDetails?.availableSpots || 0)) {
11990
- missing.push(t$1("payment.reduceParticipants", { count: eventDetails?.availableSpots || 0 }));
11991
- }
11992
- if (!watchedCustomerName || watchedCustomerName.trim().length < 2 || customerNameError) {
11993
- missing.push(t$1("payment.needValidName"));
11994
- }
11995
- if (!watchedCustomerEmail || watchedCustomerEmail.trim().length === 0 || customerEmailError) {
11996
- missing.push(t$1("payment.needValidEmail"));
11997
- }
11998
- if (!watchedAcceptTerms) {
11999
- missing.push(t$1("payment.needAcceptTerms"));
12000
- }
12001
- const message = missing.length > 0
12002
- ? t$1("payment.missingFields", { fields: missing.join(", ") })
12003
- : t$1("payment.fillRequired");
12004
- return (jsxRuntime.jsx("div", { style: {
12005
- ...cardStyles$1,
12006
- border: "1px solid var(--bw-warning-color)",
12007
- color: "var(--bw-warning-color)",
12153
+ fontWeight: 700,
12154
+ }, children: formatCurrency(paymentAmount) })] }), hasDepositChoice && paymentOption === "deposit" && (jsxRuntime.jsx("div", { style: {
12155
+ fontSize: "12px",
12156
+ color: "var(--bw-text-muted)",
12008
12157
  fontFamily: "var(--bw-font-family)",
12009
- textAlign: "center",
12010
- }, children: message }));
12011
- }
12012
- const discountCodeProp = appliedDiscountCode
12013
- ? {
12014
- id: appliedDiscountCode.id,
12015
- code: appliedDiscountCode.code,
12016
- description: appliedDiscountCode.description || undefined,
12017
- type: appliedDiscountCode.discountType || "percentage",
12018
- value: appliedDiscountCode.discountValue || 0,
12019
- discountAmount: appliedDiscountCode.discountAmount,
12020
- newTotal: appliedDiscountCode.newTotal,
12021
- }
12022
- : null;
12023
- if (systemConfig?.paymentProvider === "mollie") {
12024
- return (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(MolliePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, upsellSelections: aggregatedUpsellSelections(), mollieProfileId: systemConfig?.mollieProfileId, mollieTestmode: systemConfig?.mollieTestmode })] }));
12025
- }
12026
- return (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(StripePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, systemConfig: systemConfig ?? null, stripePromise: stripePromise, stripeAppearance: stripeAppearance, upsellSelections: aggregatedUpsellSelections() })] }));
12027
- })() })] })] })] }) }));
12158
+ marginTop: "8px",
12159
+ textAlign: "right",
12160
+ }, children: t$1("summary.remainingOnSite", { amount: formatCurrency(totalAmount - depositAmount) }) }))] })] })] }), depositsOnlyBlocked && (jsxRuntime.jsx("div", { style: cardStyles$1, children: jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.depositNotConfigured") }) })), !hasPaymentProvider && !depositsOnlyBlocked && (jsxRuntime.jsx("div", { style: cardStyles$1, children: jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.paymentUnavailable") }) })), hasPaymentProvider && !depositsOnlyBlocked && (systemConfig?.paymentProvider === "mollie" ? (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(MolliePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, upsellSelections: aggregatedUpsellSelections(), mollieProfileId: systemConfig?.mollieProfileId, mollieTestmode: systemConfig?.mollieTestmode })] })) : (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(StripePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, systemConfig: systemConfig ?? null, stripePromise: stripePromise, stripeAppearance: stripeAppearance, upsellSelections: aggregatedUpsellSelections() })] })))] }))] }) }));
12028
12161
  }
12029
12162
 
12030
12163
  /**
@@ -12872,6 +13005,40 @@ const ImageCarousel = ({ images, eventName }) => {
12872
13005
  } }))] }));
12873
13006
  };
12874
13007
 
13008
+ function PaymentLogosStrip() {
13009
+ const logoHeight = 20;
13010
+ const logoCellStyle = {
13011
+ display: "inline-flex",
13012
+ alignItems: "center",
13013
+ justifyContent: "center",
13014
+ padding: "0px 6px",
13015
+ minHeight: "29px", // +7px from previous 22px
13016
+ borderRadius: "6px",
13017
+ };
13018
+ return (jsxRuntime.jsxs("div", { style: {
13019
+ padding: "6px 14px 10px 14px",
13020
+ backgroundColor: "color-mix(in srgb, var(--bw-text-color) 100%, var(--bw-surface-color) 18%)",
13021
+ display: "flex",
13022
+ alignItems: "center",
13023
+ justifyContent: "center",
13024
+ borderRadius: "var(--bw-border-radius)",
13025
+ gap: "4px",
13026
+ flexWrap: "wrap",
13027
+ width: "fit-content",
13028
+ margin: "20px auto",
13029
+ }, children: [jsxRuntime.jsxs("span", { style: logoCellStyle, children: [jsxRuntime.jsx("span", { style: { color: "#003087", fontSize: "14px", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "Pay" }), jsxRuntime.jsx("span", { style: { color: "#009cde", fontSize: "14px", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "Pal" })] }), jsxRuntime.jsx("span", { style: logoCellStyle, children: jsxRuntime.jsxs("svg", { width: "34", height: logoHeight, viewBox: "0 0 34 20", "aria-label": "Maestro", children: [jsxRuntime.jsx("circle", { cx: "13", cy: "10", r: "8", fill: "#eb001b" }), jsxRuntime.jsx("circle", { cx: "21", cy: "10", r: "8", fill: "#00a2e5", fillOpacity: "0.92" })] }) }), jsxRuntime.jsx("span", { style: logoCellStyle, children: jsxRuntime.jsx("span", { style: { color: "#1434CB", fontSize: "14px", fontStyle: "italic", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "VISA" }) }), jsxRuntime.jsx("span", { style: logoCellStyle, children: jsxRuntime.jsx("span", { style: { color: "purple", fontSize: "14px", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "Klarna" }) }), jsxRuntime.jsx("span", { style: logoCellStyle, children: jsxRuntime.jsxs("svg", { width: "74", height: logoHeight, viewBox: "0 0 74 20", "aria-label": "Amazon Pay", children: [jsxRuntime.jsx("text", { x: "0", y: "14", fontSize: "12", fill: "#111827", fontFamily: "Arial, sans-serif", children: "amazon" }), jsxRuntime.jsx("text", { x: "45", y: "14", fontSize: "12", fill: "#111827", fontFamily: "Arial, sans-serif", children: "pay" }), jsxRuntime.jsx("path", { d: "M5 15 C17 20, 35 20, 48 15", stroke: "#f59e0b", strokeWidth: "1.6", fill: "none", strokeLinecap: "round" })] }) }), jsxRuntime.jsxs("span", { style: logoCellStyle, children: [jsxRuntime.jsx("span", { style: {
13030
+ fontSize: "16px",
13031
+ fontWeight: 800,
13032
+ fontFamily: "Arial, sans-serif",
13033
+ lineHeight: 1,
13034
+ background: "conic-gradient(from 25deg, #4285F4 0 24%, #DB4437 24% 48%, #F4B400 48% 73%, #0F9D58 73% 100%)",
13035
+ WebkitBackgroundClip: "text",
13036
+ backgroundClip: "text",
13037
+ color: "transparent",
13038
+ WebkitTextFillColor: "transparent",
13039
+ }, children: "G" }), jsxRuntime.jsx("span", { style: { color: "#5f6368", fontSize: "14px", fontWeight: 600, fontFamily: "Arial, sans-serif", marginLeft: "3px", lineHeight: 1 }, children: "Pay" })] }), jsxRuntime.jsx("span", { style: logoCellStyle, children: jsxRuntime.jsxs("svg", { width: "60", height: logoHeight, viewBox: "0 0 60 20", "aria-label": "Apple Pay", children: [jsxRuntime.jsx("text", { x: "0", y: "14.5", fontSize: "14.5", fill: "#111827", fontFamily: "-apple-system, BlinkMacSystemFont, Arial, sans-serif", children: "\uF8FF" }), jsxRuntime.jsx("text", { x: "14", y: "14.5", fontSize: "14.5", fill: "#111827", fontFamily: "-apple-system, BlinkMacSystemFont, Arial, sans-serif", children: "Pay" })] }) })] }));
13040
+ }
13041
+
12875
13042
  function VoucherPurchaseCard({ config, minEventPrice, fallbackImages = [], onClick, standalone = false, }) {
12876
13043
  const t = useTranslations();
12877
13044
  const [activeSlideIndex, setActiveSlideIndex] = React.useState(0);
@@ -13991,7 +14158,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
13991
14158
  display: "flex",
13992
14159
  flexDirection: "column",
13993
14160
  justifyContent: "space-between",
13994
- height: "490px",
14161
+ height: "540px",
13995
14162
  }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h2", { className: "event-type-title", style: {
13996
14163
  fontSize: "clamp(1.1rem, 2.5vw, 24px)",
13997
14164
  fontWeight: 700,
@@ -14061,19 +14228,9 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14061
14228
  }) }) })) : (jsxRuntime.jsx("div", { className: "event-type-desc", style: {
14062
14229
  margin: "10px 0",
14063
14230
  height: "7.5em", // Same height as highlights
14064
- }, children: "\u00A0" })) })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("div", { className: "event-type-price", style: {
14065
- fontWeight: 700,
14066
- color: "var(--bw-text-color)",
14067
- fontFamily: "var(--bw-font-family)",
14068
- textAlign: "right",
14069
- }, children: jsxRuntime.jsx("span", { children: formatDurationInfo(eventType.durationInfo, t) }) }), jsxRuntime.jsx("div", { className: "event-type-price", style: {
14070
- fontSize: "clamp(1.72rem, 4vw, 32px)",
14071
- fontWeight: 700,
14072
- color: "var(--bw-text-color)",
14073
- fontFamily: "var(--bw-font-family)",
14074
- textAlign: "right",
14075
- }, children: jsxRuntime.jsxs("span", { children: [t("common.from"), " ", formatCurrency(eventType.minPrice)] }) })] }), (() => {
14231
+ }, children: "\u00A0" })) })] }), jsxRuntime.jsxs("div", { children: [(() => {
14076
14232
  const preview = eventType.cardPreview ?? [];
14233
+ const hasMoreDates = eventType.availableInstancesCount > preview.length;
14077
14234
  return (jsxRuntime.jsxs("div", { style: {
14078
14235
  marginTop: "12px",
14079
14236
  borderTop: "1px solid var(--bw-border-color)",
@@ -14107,8 +14264,33 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14107
14264
  transition: "background 0.15s",
14108
14265
  boxSizing: "border-box",
14109
14266
  }, children: [jsxRuntime.jsxs("span", { style: { whiteSpace: "nowrap", display: "flex", alignItems: "center", gap: "3px" }, children: [item.isSpecial && (jsxRuntime.jsx("span", { style: { color: "var(--bw-highlight-color)", fontSize: "11px", lineHeight: 1 }, children: "\u2605" })), formatWeekday(item.startTime, timezone, locale), " ", formatDate(item.startTime, timezone, locale)] }), jsxRuntime.jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", opacity: 0.75 }, children: item.name }), jsxRuntime.jsxs("span", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [hasDiscount && (jsxRuntime.jsx("span", { style: { textDecoration: "line-through", opacity: 0.55, fontSize: "11px" }, children: formatCurrency(item.basePrice) })), jsxRuntime.jsx("span", { style: { fontWeight: 700, color: item.isSpecial ? "var(--bw-highlight-color)" : "var(--bw-text-color)" }, children: formatCurrency(item.price) })] }), item.specialDescription ? (jsxRuntime.jsx(InfoBadge, { text: item.specialDescription })) : (jsxRuntime.jsx("span", {}))] }, item.id));
14110
- }) })] }));
14111
- })(), jsxRuntime.jsxs("div", { style: {
14267
+ }) }), hasMoreDates && (jsxRuntime.jsx("button", { type: "button", onClick: (e) => {
14268
+ e.stopPropagation();
14269
+ onEventTypeSelect(eventType);
14270
+ }, style: {
14271
+ marginTop: "6px",
14272
+ padding: 0,
14273
+ border: "none",
14274
+ background: "none",
14275
+ color: "var(--bw-highlight-color)",
14276
+ fontFamily: "var(--bw-font-family)",
14277
+ fontSize: "13px",
14278
+ fontWeight: 600,
14279
+ cursor: "pointer",
14280
+ textDecoration: "underline",
14281
+ }, children: t("events.seeMoreDates") }))] }));
14282
+ })(), jsxRuntime.jsxs("div", { style: { marginBottom: "16px" }, children: [jsxRuntime.jsx("div", { className: "event-type-price", style: {
14283
+ fontWeight: 700,
14284
+ color: "var(--bw-text-color)",
14285
+ fontFamily: "var(--bw-font-family)",
14286
+ textAlign: "right",
14287
+ }, children: jsxRuntime.jsx("span", { children: formatDurationInfo(eventType.durationInfo, t) }) }), jsxRuntime.jsx("div", { className: "event-type-price", style: {
14288
+ fontSize: "clamp(1.72rem, 4vw, 32px)",
14289
+ fontWeight: 700,
14290
+ color: "var(--bw-text-color)",
14291
+ fontFamily: "var(--bw-font-family)",
14292
+ textAlign: "right",
14293
+ }, children: jsxRuntime.jsxs("span", { children: [t("common.from"), " ", formatCurrency(eventType.minPrice)] }) })] }), jsxRuntime.jsxs("div", { style: {
14112
14294
  display: "flex",
14113
14295
  justifyContent: "flex-end",
14114
14296
  alignItems: "center",
@@ -14166,7 +14348,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14166
14348
  fontFamily: "var(--bw-font-family)",
14167
14349
  boxShadow: "var(--bw-shadow-md)",
14168
14350
  }, children: t("events.soldOut") }) }))] }, eventType.id));
14169
- }) }) })), jsxRuntime.jsx(EventTypeDetailsDialog, { isOpen: detailsDialogOpen, onClose: handleCloseDetails, eventType: selectedEventTypeForDetails, onEventTypeSelect: onEventTypeSelect })] }));
14351
+ }) }) })), jsxRuntime.jsx(PaymentLogosStrip, {}), jsxRuntime.jsx(EventTypeDetailsDialog, { isOpen: detailsDialogOpen, onClose: handleCloseDetails, eventType: selectedEventTypeForDetails, onEventTypeSelect: onEventTypeSelect })] }));
14170
14352
  }
14171
14353
 
14172
14354
  const getAllocationBadgeInfo = (availableSpots, maxParticipants, t) => {
@@ -14293,7 +14475,7 @@ const PriceDisplay = ({ price, yearPrices, t }) => {
14293
14475
  boxShadow: displayInfo ? "0 2px 4px rgba(0, 0, 0, 0.2)" : "none",
14294
14476
  }, children: formatCurrency(price) }));
14295
14477
  };
14296
- function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, }) {
14478
+ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, hasUpsellsStep = false, }) {
14297
14479
  const t = useTranslations();
14298
14480
  const { locale } = useLocale();
14299
14481
  const timezone = useTimezone();
@@ -14359,88 +14541,88 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
14359
14541
  const footerNav = (jsxRuntime.jsx("button", { type: "button", onClick: handleClose, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: t("common.back") }));
14360
14542
  // Show loading state first if we're loading event instances
14361
14543
  if (isLoadingEventInstances) {
14362
- return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsxRuntime.jsx("div", { style: { padding: "24px" }, children: jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "20px" }, children: Array.from({ length: 3 }).map((_, idx) => (jsxRuntime.jsxs("div", { className: "skeleton-shimmer", style: {
14363
- backgroundColor: "var(--bw-surface-color)",
14364
- border: "1px solid var(--bw-border-color)",
14365
- borderRadius: "var(--bw-border-radius)",
14366
- overflow: "hidden",
14367
- }, children: [jsxRuntime.jsxs("div", { style: {
14368
- display: "flex",
14369
- justifyContent: "space-between",
14370
- alignItems: "center",
14371
- padding: "16px 20px",
14372
- cursor: "pointer",
14373
- borderBottom: "1px solid var(--bw-border-color)",
14374
- }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [jsxRuntime.jsx("div", { style: {
14375
- width: "80px",
14376
- height: "20px",
14377
- backgroundColor: "var(--bw-border-color)",
14378
- borderRadius: "var(--bw-border-radius-small)",
14379
- } }), jsxRuntime.jsx("div", { style: {
14380
- width: "16px",
14381
- height: "16px",
14382
- backgroundColor: "var(--bw-border-color)",
14383
- borderRadius: "var(--bw-border-radius-small)",
14384
- } })] }), jsxRuntime.jsx("div", { style: {
14385
- width: "70px",
14386
- height: "16px",
14387
- backgroundColor: "var(--bw-highlight-color)",
14388
- opacity: 0.3,
14389
- borderRadius: "var(--bw-border-radius-small)",
14390
- } })] }), jsxRuntime.jsx("div", { style: {
14391
- display: "flex",
14392
- flexDirection: "column",
14393
- gap: "12px",
14394
- paddingTop: "12px",
14395
- padding: "12px 20px 20px 20px",
14396
- }, children: Array.from({ length: 2 }).map((_, eventIdx) => (jsxRuntime.jsxs("div", { style: {
14397
- position: "relative",
14398
- border: "1px solid var(--bw-border-color)",
14399
- backgroundColor: "var(--bw-surface-color)",
14400
- borderRadius: "var(--bw-border-radius)",
14544
+ return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsxRuntime.jsxs("div", { style: { padding: "24px" }, children: [jsxRuntime.jsx(FlowProgress, { currentStep: "date", hasUpsellsStep: hasUpsellsStep }), jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "20px" }, children: Array.from({ length: 3 }).map((_, idx) => (jsxRuntime.jsxs("div", { className: "skeleton-shimmer", style: {
14545
+ backgroundColor: "var(--bw-surface-color)",
14546
+ border: "1px solid var(--bw-border-color)",
14547
+ borderRadius: "var(--bw-border-radius)",
14548
+ overflow: "hidden",
14549
+ }, children: [jsxRuntime.jsxs("div", { style: {
14550
+ display: "flex",
14551
+ justifyContent: "space-between",
14552
+ alignItems: "center",
14401
14553
  padding: "16px 20px",
14402
- fontFamily: "var(--bw-font-family)",
14403
- }, children: [jsxRuntime.jsxs("div", { style: {
14404
- display: "flex",
14405
- justifyContent: "space-between",
14406
- width: "100%",
14407
- alignItems: "flex-start",
14408
- gap: "12px",
14409
- marginBottom: "4px",
14410
- }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("div", { style: {
14411
- width: "40px",
14412
- height: "40px",
14413
- backgroundColor: "var(--bw-background-color)",
14414
- border: "1px solid var(--bw-border-color)",
14415
- borderTopWidth: "4px",
14416
- borderRadius: "var(--bw-border-radius-small)",
14417
- } }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [jsxRuntime.jsx("div", { style: {
14418
- width: "80px",
14419
- height: "16px",
14420
- backgroundColor: "var(--bw-border-color)",
14421
- borderRadius: "var(--bw-border-radius)",
14422
- } }), jsxRuntime.jsx("div", { style: {
14423
- width: "60px",
14424
- height: "14px",
14425
- backgroundColor: "var(--bw-border-color)",
14426
- borderRadius: "var(--bw-border-radius)",
14427
- } })] })] }), jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end" }, children: jsxRuntime.jsx("div", { style: {
14428
- width: "70px",
14429
- height: "20px",
14430
- backgroundColor: "var(--bw-highlight-color)",
14431
- opacity: 0.3,
14432
- borderRadius: "var(--bw-border-radius)",
14433
- } }) })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [jsxRuntime.jsx("div", { style: {
14434
- width: "120px",
14435
- height: "16px",
14554
+ cursor: "pointer",
14555
+ borderBottom: "1px solid var(--bw-border-color)",
14556
+ }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [jsxRuntime.jsx("div", { style: {
14557
+ width: "80px",
14558
+ height: "20px",
14436
14559
  backgroundColor: "var(--bw-border-color)",
14437
- borderRadius: "var(--bw-border-radius)",
14560
+ borderRadius: "var(--bw-border-radius-small)",
14438
14561
  } }), jsxRuntime.jsx("div", { style: {
14439
- width: "50px",
14440
- height: "20px",
14562
+ width: "16px",
14563
+ height: "16px",
14441
14564
  backgroundColor: "var(--bw-border-color)",
14442
- borderRadius: "16px",
14443
- } })] })] }, eventIdx))) })] }, idx))) }) }) }));
14565
+ borderRadius: "var(--bw-border-radius-small)",
14566
+ } })] }), jsxRuntime.jsx("div", { style: {
14567
+ width: "70px",
14568
+ height: "16px",
14569
+ backgroundColor: "var(--bw-highlight-color)",
14570
+ opacity: 0.3,
14571
+ borderRadius: "var(--bw-border-radius-small)",
14572
+ } })] }), jsxRuntime.jsx("div", { style: {
14573
+ display: "flex",
14574
+ flexDirection: "column",
14575
+ gap: "12px",
14576
+ paddingTop: "12px",
14577
+ padding: "12px 20px 20px 20px",
14578
+ }, children: Array.from({ length: 2 }).map((_, eventIdx) => (jsxRuntime.jsxs("div", { style: {
14579
+ position: "relative",
14580
+ border: "1px solid var(--bw-border-color)",
14581
+ backgroundColor: "var(--bw-surface-color)",
14582
+ borderRadius: "var(--bw-border-radius)",
14583
+ padding: "16px 20px",
14584
+ fontFamily: "var(--bw-font-family)",
14585
+ }, children: [jsxRuntime.jsxs("div", { style: {
14586
+ display: "flex",
14587
+ justifyContent: "space-between",
14588
+ width: "100%",
14589
+ alignItems: "flex-start",
14590
+ gap: "12px",
14591
+ marginBottom: "4px",
14592
+ }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("div", { style: {
14593
+ width: "40px",
14594
+ height: "40px",
14595
+ backgroundColor: "var(--bw-background-color)",
14596
+ border: "1px solid var(--bw-border-color)",
14597
+ borderTopWidth: "4px",
14598
+ borderRadius: "var(--bw-border-radius-small)",
14599
+ } }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [jsxRuntime.jsx("div", { style: {
14600
+ width: "80px",
14601
+ height: "16px",
14602
+ backgroundColor: "var(--bw-border-color)",
14603
+ borderRadius: "var(--bw-border-radius)",
14604
+ } }), jsxRuntime.jsx("div", { style: {
14605
+ width: "60px",
14606
+ height: "14px",
14607
+ backgroundColor: "var(--bw-border-color)",
14608
+ borderRadius: "var(--bw-border-radius)",
14609
+ } })] })] }), jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end" }, children: jsxRuntime.jsx("div", { style: {
14610
+ width: "70px",
14611
+ height: "20px",
14612
+ backgroundColor: "var(--bw-highlight-color)",
14613
+ opacity: 0.3,
14614
+ borderRadius: "var(--bw-border-radius)",
14615
+ } }) })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [jsxRuntime.jsx("div", { style: {
14616
+ width: "120px",
14617
+ height: "16px",
14618
+ backgroundColor: "var(--bw-border-color)",
14619
+ borderRadius: "var(--bw-border-radius)",
14620
+ } }), jsxRuntime.jsx("div", { style: {
14621
+ width: "50px",
14622
+ height: "20px",
14623
+ backgroundColor: "var(--bw-border-color)",
14624
+ borderRadius: "16px",
14625
+ } })] })] }, eventIdx))) })] }, idx))) })] }) }));
14444
14626
  }
14445
14627
  // Show empty state only if not loading and no event instances
14446
14628
  if (eventInstances.length === 0) {
@@ -14459,116 +14641,116 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
14459
14641
  fontFamily: "var(--bw-font-family)",
14460
14642
  }, children: t("instances.noAvailable") }), jsxRuntime.jsx("p", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t("instances.noAvailableMessage") })] }) }) }));
14461
14643
  }
14462
- return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsxRuntime.jsx("div", { style: { padding: "20px 10px" }, children: jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: monthYearGroups.map(({ key, label, events, minPrice, year }, idx) => {
14463
- const monthPriceDisplayInfo = getMonthPriceDisplayInfo(minPrice);
14464
- return (jsxRuntime.jsxs(React.Fragment, { children: [idx > 0 && monthYearGroups[idx - 1].year !== year && (jsxRuntime.jsx("div", { style: { height: "1px", backgroundColor: "var(--bw-border-color)", margin: "4px 0" } })), jsxRuntime.jsx(Accordion, { title: label, priceInfo: jsxRuntime.jsx("div", { style: {
14465
- fontSize: "16px",
14466
- fontWeight: 500,
14467
- marginLeft: "auto",
14468
- padding: "4px 8px",
14469
- borderRadius: "var(--bw-border-radius-small)",
14470
- backgroundColor: monthPriceDisplayInfo
14471
- ? monthPriceDisplayInfo.backgroundColor
14472
- : "#14532d",
14473
- color: monthPriceDisplayInfo
14474
- ? monthPriceDisplayInfo.textColor
14475
- : "#4ade80",
14476
- boxShadow: monthPriceDisplayInfo
14477
- ? "0 2px 4px rgba(0, 0, 0, 0.2)"
14478
- : undefined,
14479
- }, children: `${t("common.from")} ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", paddingTop: "12px" }, children: events.map((event) => {
14480
- const availableSpots = event.maxParticipants - event.participantCount;
14481
- const isFullyBooked = availableSpots === 0;
14482
- const startDate = new Date(event.startTime);
14483
- const isPastEvent = today.toISOString() >= startDate.toISOString();
14484
- const isDisabled = isFullyBooked || isPastEvent || !event.bookingOpen;
14485
- return (jsxRuntime.jsxs("div", { style: {
14486
- position: "relative",
14487
- border: "1px solid var(--bw-border-color)",
14488
- backgroundColor: "var(--bw-surface-color)",
14489
- borderRadius: "var(--bw-border-radius)",
14490
- padding: "16px 10px",
14491
- transition: "all 0.2s ease",
14492
- fontFamily: "var(--bw-font-family)",
14493
- opacity: isDisabled ? 0.3 : 1,
14494
- filter: isDisabled ? "grayscale(40%)" : "none",
14495
- cursor: isDisabled ? "not-allowed" : "pointer",
14496
- }, onClick: () => {
14497
- if (!isDisabled) {
14498
- handleEventInstanceSelect(event);
14499
- }
14500
- }, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsxRuntime.jsx("div", { style: {
14501
- position: "absolute",
14502
- inset: 0,
14503
- backgroundColor: "rgba(15, 23, 42, 0.8)",
14504
- borderRadius: "var(--bw-border-radius)",
14505
- display: "flex",
14506
- alignItems: "center",
14507
- justifyContent: "center",
14508
- }, children: jsxRuntime.jsx("div", { style: {
14509
- width: "32px",
14510
- height: "32px",
14511
- color: "var(--bw-highlight-color)",
14512
- opacity: 0.8,
14513
- fontSize: "32px",
14514
- }, children: spinner() }) })), jsxRuntime.jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsxRuntime.jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants, t: t }), jsxRuntime.jsxs("div", { style: {
14515
- display: "flex",
14516
- justifyContent: "space-between",
14517
- width: "100%",
14518
- alignItems: "flex-start",
14519
- gap: "12px",
14520
- marginBottom: "4px",
14521
- }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("div", { style: {
14522
- fontSize: "16px",
14523
- transition: "all 0.2s ease",
14524
- borderRadius: "var(--bw-border-radius-small)",
14525
- borderTop: "4px solid var(--bw-border-color)",
14526
- border: "1px solid var(--bw-border-color)",
14527
- width: "40px",
14528
- height: "40px",
14529
- display: "flex",
14530
- alignItems: "center",
14531
- justifyContent: "center",
14532
- fontWeight: 700,
14533
- color: "var(--bw-text-color)",
14534
- backgroundColor: "var(--bw-background-color)",
14535
- }, children: startDate.getDate() }), jsxRuntime.jsxs("div", { style: {
14536
- fontSize: "16px",
14537
- color: "var(--bw-text-color)",
14538
- display: "flex",
14539
- flexDirection: "column",
14540
- alignItems: "flex-start",
14541
- justifyContent: "flex-start",
14542
- lineHeight: 1.25,
14543
- }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.startTime, timezone, locale) }), formatWeekday(event.startTime, timezone, locale) !==
14544
- formatWeekday(event.endTime, timezone, locale) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsxRuntime.jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.endTime, timezone, locale) })] }))] }), jsxRuntime.jsx("div", { children: formatWeekday(event.startTime, timezone, locale) ===
14545
- formatWeekday(event.endTime, timezone, locale) ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.startTime, timezone, locale) }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.endTime, timezone, locale) })] })) : (jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime, timezone, locale), " ", t("instances.oclock")] })) })] }), jsxRuntime.jsxs("span", { style: {
14546
- fontSize: "12px",
14547
- fontWeight: 400,
14548
- color: "var(--bw-text-muted)",
14549
- marginLeft: "6px",
14550
- backgroundColor: "rgba(0, 0, 0, 0.05)",
14551
- whiteSpace: "nowrap",
14552
- padding: "2px 6px",
14553
- borderRadius: "var(--bw-border-radius-small)",
14554
- }, children: [event.durationDays, " ", event.durationDays > 1 ? t("common.days") : t("common.day")] })] }), jsxRuntime.jsx("div", { style: {
14555
- textAlign: "right",
14556
- display: "flex",
14557
- flexDirection: "column",
14558
- alignItems: "flex-end",
14559
- }, children: jsxRuntime.jsx(PriceDisplay, { price: event.price, yearPrices: yearPrices, t: t }) })] }), event.name !== selectedEventType?.name && (jsxRuntime.jsx("h4", { style: {
14560
- fontSize: "16px",
14561
- fontWeight: 600,
14562
- color: "var(--bw-text-color)",
14563
- lineHeight: 1.25,
14564
- margin: "0 0 2px 0",
14565
- display: "flex",
14566
- alignItems: "center",
14567
- gap: "8px",
14568
- maxWidth: "230px",
14569
- }, children: event.name }))] }, event.id));
14570
- }) }) })] }, key));
14571
- }) }) }) }));
14644
+ return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsxRuntime.jsxs("div", { style: { padding: "20px 10px" }, children: [jsxRuntime.jsx(FlowProgress, { currentStep: "date", hasUpsellsStep: hasUpsellsStep }), jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: monthYearGroups.map(({ key, label, events, minPrice, year }, idx) => {
14645
+ const monthPriceDisplayInfo = getMonthPriceDisplayInfo(minPrice);
14646
+ return (jsxRuntime.jsxs(React.Fragment, { children: [idx > 0 && monthYearGroups[idx - 1].year !== year && (jsxRuntime.jsx("div", { style: { height: "1px", backgroundColor: "var(--bw-border-color)", margin: "4px 0" } })), jsxRuntime.jsx(Accordion, { title: label, priceInfo: jsxRuntime.jsx("div", { style: {
14647
+ fontSize: "16px",
14648
+ fontWeight: 500,
14649
+ marginLeft: "auto",
14650
+ padding: "4px 8px",
14651
+ borderRadius: "var(--bw-border-radius-small)",
14652
+ backgroundColor: monthPriceDisplayInfo
14653
+ ? monthPriceDisplayInfo.backgroundColor
14654
+ : "#14532d",
14655
+ color: monthPriceDisplayInfo
14656
+ ? monthPriceDisplayInfo.textColor
14657
+ : "#4ade80",
14658
+ boxShadow: monthPriceDisplayInfo
14659
+ ? "0 2px 4px rgba(0, 0, 0, 0.2)"
14660
+ : undefined,
14661
+ }, children: `${t("common.from")} ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", paddingTop: "12px" }, children: events.map((event) => {
14662
+ const availableSpots = event.maxParticipants - event.participantCount;
14663
+ const isFullyBooked = availableSpots === 0;
14664
+ const startDate = new Date(event.startTime);
14665
+ const isPastEvent = today.toISOString() >= startDate.toISOString();
14666
+ const isDisabled = isFullyBooked || isPastEvent || !event.bookingOpen;
14667
+ return (jsxRuntime.jsxs("div", { style: {
14668
+ position: "relative",
14669
+ border: "1px solid var(--bw-border-color)",
14670
+ backgroundColor: "var(--bw-surface-color)",
14671
+ borderRadius: "var(--bw-border-radius)",
14672
+ padding: "16px 10px",
14673
+ transition: "all 0.2s ease",
14674
+ fontFamily: "var(--bw-font-family)",
14675
+ opacity: isDisabled ? 0.3 : 1,
14676
+ filter: isDisabled ? "grayscale(40%)" : "none",
14677
+ cursor: isDisabled ? "not-allowed" : "pointer",
14678
+ }, onClick: () => {
14679
+ if (!isDisabled) {
14680
+ handleEventInstanceSelect(event);
14681
+ }
14682
+ }, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsxRuntime.jsx("div", { style: {
14683
+ position: "absolute",
14684
+ inset: 0,
14685
+ backgroundColor: "rgba(15, 23, 42, 0.8)",
14686
+ borderRadius: "var(--bw-border-radius)",
14687
+ display: "flex",
14688
+ alignItems: "center",
14689
+ justifyContent: "center",
14690
+ }, children: jsxRuntime.jsx("div", { style: {
14691
+ width: "32px",
14692
+ height: "32px",
14693
+ color: "var(--bw-highlight-color)",
14694
+ opacity: 0.8,
14695
+ fontSize: "32px",
14696
+ }, children: spinner() }) })), jsxRuntime.jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsxRuntime.jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants, t: t }), jsxRuntime.jsxs("div", { style: {
14697
+ display: "flex",
14698
+ justifyContent: "space-between",
14699
+ width: "100%",
14700
+ alignItems: "flex-start",
14701
+ gap: "12px",
14702
+ marginBottom: "4px",
14703
+ }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("div", { style: {
14704
+ fontSize: "16px",
14705
+ transition: "all 0.2s ease",
14706
+ borderRadius: "var(--bw-border-radius-small)",
14707
+ borderTop: "4px solid var(--bw-border-color)",
14708
+ border: "1px solid var(--bw-border-color)",
14709
+ width: "40px",
14710
+ height: "40px",
14711
+ display: "flex",
14712
+ alignItems: "center",
14713
+ justifyContent: "center",
14714
+ fontWeight: 700,
14715
+ color: "var(--bw-text-color)",
14716
+ backgroundColor: "var(--bw-background-color)",
14717
+ }, children: startDate.getDate() }), jsxRuntime.jsxs("div", { style: {
14718
+ fontSize: "16px",
14719
+ color: "var(--bw-text-color)",
14720
+ display: "flex",
14721
+ flexDirection: "column",
14722
+ alignItems: "flex-start",
14723
+ justifyContent: "flex-start",
14724
+ lineHeight: 1.25,
14725
+ }, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.startTime, timezone, locale) }), formatWeekday(event.startTime, timezone, locale) !==
14726
+ formatWeekday(event.endTime, timezone, locale) && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsxRuntime.jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.endTime, timezone, locale) })] }))] }), jsxRuntime.jsx("div", { children: formatWeekday(event.startTime, timezone, locale) ===
14727
+ formatWeekday(event.endTime, timezone, locale) ? (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.startTime, timezone, locale) }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.endTime, timezone, locale) })] })) : (jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime, timezone, locale), " ", t("instances.oclock")] })) })] }), jsxRuntime.jsxs("span", { style: {
14728
+ fontSize: "12px",
14729
+ fontWeight: 400,
14730
+ color: "var(--bw-text-muted)",
14731
+ marginLeft: "6px",
14732
+ backgroundColor: "rgba(0, 0, 0, 0.05)",
14733
+ whiteSpace: "nowrap",
14734
+ padding: "2px 6px",
14735
+ borderRadius: "var(--bw-border-radius-small)",
14736
+ }, children: [event.durationDays, " ", event.durationDays > 1 ? t("common.days") : t("common.day")] })] }), jsxRuntime.jsx("div", { style: {
14737
+ textAlign: "right",
14738
+ display: "flex",
14739
+ flexDirection: "column",
14740
+ alignItems: "flex-end",
14741
+ }, children: jsxRuntime.jsx(PriceDisplay, { price: event.price, yearPrices: yearPrices, t: t }) })] }), event.name !== selectedEventType?.name && (jsxRuntime.jsx("h4", { style: {
14742
+ fontSize: "16px",
14743
+ fontWeight: 600,
14744
+ color: "var(--bw-text-color)",
14745
+ lineHeight: 1.25,
14746
+ margin: "0 0 2px 0",
14747
+ display: "flex",
14748
+ alignItems: "center",
14749
+ gap: "8px",
14750
+ maxWidth: "230px",
14751
+ }, children: event.name }))] }, event.id));
14752
+ }) }) })] }, key));
14753
+ }) })] }) }));
14572
14754
  }
14573
14755
 
14574
14756
  function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText, showAllButton, isLoadingEventDetails = false, isLoadingShowAll = false, isLoading = false, }) {
@@ -15191,12 +15373,11 @@ function PromoDialog({ config, onClose, onCtaClick }) {
15191
15373
  return ReactDOM.createPortal(dialogContent, portalContainer);
15192
15374
  }
15193
15375
 
15194
- // Upsell card styles
15195
15376
  const cardBaseStyles = {
15196
15377
  position: "relative",
15197
15378
  display: "flex",
15198
15379
  flexDirection: "column",
15199
- padding: "16px",
15380
+ padding: "12px",
15200
15381
  backgroundColor: "var(--bw-surface-color)",
15201
15382
  borderWidth: "2px",
15202
15383
  borderStyle: "solid",
@@ -15216,19 +15397,13 @@ const cardDisabledStyles = {
15216
15397
  opacity: 0.6,
15217
15398
  cursor: "not-allowed",
15218
15399
  };
15219
- const checkboxContainerStyles = {
15220
- position: "absolute",
15221
- bottom: "12px",
15222
- left: "12px",
15223
- zIndex: 1,
15224
- };
15225
15400
  const checkboxInnerStyles = {
15226
- width: "24px",
15227
- height: "24px",
15401
+ width: "48px",
15402
+ height: "48px",
15228
15403
  borderWidth: "2px",
15229
15404
  borderStyle: "solid",
15230
15405
  borderColor: "var(--bw-border-color)",
15231
- borderRadius: "6px",
15406
+ borderRadius: "12px",
15232
15407
  display: "flex",
15233
15408
  alignItems: "center",
15234
15409
  justifyContent: "center",
@@ -15240,13 +15415,13 @@ const checkboxSelectedStyles = {
15240
15415
  borderColor: "var(--bw-highlight-color)",
15241
15416
  backgroundColor: "var(--bw-highlight-color)",
15242
15417
  };
15243
- const imageContainerStyles = {
15244
- width: "100%",
15245
- height: "120px",
15246
- marginBottom: "12px",
15418
+ const previewImageContainerStyles = {
15419
+ width: "56px",
15420
+ height: "56px",
15247
15421
  borderRadius: "calc(var(--bw-border-radius) - 4px)",
15248
15422
  overflow: "hidden",
15249
15423
  backgroundColor: "var(--bw-background-color)",
15424
+ flexShrink: 0,
15250
15425
  };
15251
15426
  const imageStyles = {
15252
15427
  width: "100%",
@@ -15261,23 +15436,53 @@ const imagePlaceholderStyles = {
15261
15436
  justifyContent: "center",
15262
15437
  color: "var(--bw-text-muted)",
15263
15438
  };
15264
- const nameStyles = {
15439
+ const previewNameStyles = {
15265
15440
  fontSize: "16px",
15266
15441
  fontWeight: 600,
15267
15442
  color: "var(--bw-text-color)",
15268
- margin: "0 0 6px 0",
15269
- paddingRight: "36px",
15443
+ margin: 0,
15270
15444
  fontFamily: "var(--bw-font-family)",
15271
15445
  };
15446
+ const previewHeaderStyles = {
15447
+ display: "flex",
15448
+ alignItems: "center",
15449
+ gap: "10px",
15450
+ };
15451
+ const previewPriceStyles = {
15452
+ fontSize: "13px",
15453
+ color: "var(--bw-text-muted)",
15454
+ marginTop: "2px",
15455
+ fontFamily: "var(--bw-font-family)",
15456
+ };
15457
+ const headerRightStyles = {
15458
+ marginLeft: "auto",
15459
+ display: "flex",
15460
+ alignItems: "center",
15461
+ gap: "8px",
15462
+ };
15463
+ const chevronStyles = {
15464
+ fontSize: "12px",
15465
+ color: "var(--bw-text-muted)",
15466
+ transition: "transform 0.2s ease",
15467
+ };
15468
+ const expandedContentStyles = {
15469
+ marginTop: "12px",
15470
+ paddingTop: "12px",
15471
+ borderTop: "1px solid var(--bw-border-color)",
15472
+ };
15473
+ const expandedImageContainerStyles = {
15474
+ width: "100%",
15475
+ height: "180px",
15476
+ marginBottom: "12px",
15477
+ borderRadius: "calc(var(--bw-border-radius) - 4px)",
15478
+ overflow: "hidden",
15479
+ backgroundColor: "var(--bw-background-color)",
15480
+ };
15272
15481
  const descriptionStyles = {
15273
15482
  fontSize: "13px",
15274
15483
  color: "var(--bw-text-muted)",
15275
15484
  margin: "0 0 10px 0",
15276
15485
  lineHeight: 1.4,
15277
- display: "-webkit-box",
15278
- WebkitLineClamp: 5,
15279
- WebkitBoxOrient: "vertical",
15280
- overflow: "hidden",
15281
15486
  fontFamily: "var(--bw-font-family)",
15282
15487
  };
15283
15488
  const itemsContainerStyles = {
@@ -15359,6 +15564,8 @@ function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
15359
15564
  const { locale } = useLocale();
15360
15565
  const totalPrice = upsell.price * participantCount;
15361
15566
  const isDisabled = !upsell.available;
15567
+ const [isExpanded, setIsExpanded] = React.useState(false);
15568
+ const hasSavings = (upsell.savingsPercent ?? 0) > 0;
15362
15569
  const getCardStyles = () => {
15363
15570
  if (isDisabled)
15364
15571
  return cardDisabledStyles;
@@ -15366,16 +15573,22 @@ function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
15366
15573
  return cardSelectedStyles;
15367
15574
  return cardBaseStyles;
15368
15575
  };
15369
- return (jsxRuntime.jsxs("div", { style: getCardStyles(), onClick: !isDisabled ? onSelect : undefined, role: "checkbox", "aria-checked": isSelected, tabIndex: isDisabled ? -1 : 0, onKeyDown: (e) => {
15576
+ const toggleExpanded = () => {
15577
+ setIsExpanded((current) => !current);
15578
+ };
15579
+ return (jsxRuntime.jsxs("div", { style: getCardStyles(), onClick: !isDisabled ? toggleExpanded : undefined, role: "button", "aria-expanded": isExpanded, tabIndex: isDisabled ? -1 : 0, onKeyDown: (e) => {
15370
15580
  if (!isDisabled && (e.key === "Enter" || e.key === " ")) {
15371
15581
  e.preventDefault();
15372
- onSelect();
15582
+ toggleExpanded();
15373
15583
  }
15374
- }, children: [jsxRuntime.jsx("div", { style: checkboxContainerStyles, children: jsxRuntime.jsx("div", { style: isSelected ? checkboxSelectedStyles : checkboxInnerStyles, children: isSelected && (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", style: { width: "16px", height: "16px" }, children: jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) })) }) }), jsxRuntime.jsx("div", { style: imageContainerStyles, children: upsell.image ? (jsxRuntime.jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsxRuntime.jsx("div", { style: imagePlaceholderStyles, children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "40px", height: "40px", opacity: 0.4 }, children: jsxRuntime.jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("h4", { style: nameStyles, children: upsell.name }), upsell.description && (jsxRuntime.jsx("p", { style: descriptionStyles, children: upsell.description })), upsell.items.length > 0 && (jsxRuntime.jsx("div", { style: itemsContainerStyles, children: upsell.items.map((item, index) => (jsxRuntime.jsxs("span", { style: itemStyles, children: [item.type === "product" ? "📦" : "🎫", " ", item.name, item.quantity > 1 && ` (${item.quantity}x)`] }, index))) })), upsell.suggestedEventInstance && (jsxRuntime.jsxs("div", { style: eventInfoStyles, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-color)", fontWeight: 500 }, children: ["\uD83D\uDCC5 ", new Date(upsell.suggestedEventInstance.date).toLocaleDateString(locale === "de" ? "de-DE" : locale === "en" ? "en-US" : locale === "es" ? "es-ES" : locale === "sv" ? "sv-SE" : "pt-PT", {
15584
+ }, children: [jsxRuntime.jsxs("div", { style: previewHeaderStyles, children: [jsxRuntime.jsx("div", { style: previewImageContainerStyles, children: upsell.image ? (jsxRuntime.jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsxRuntime.jsx("div", { style: imagePlaceholderStyles, children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "32px", height: "32px", opacity: 0.4 }, children: jsxRuntime.jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [jsxRuntime.jsx("h4", { style: previewNameStyles, children: upsell.name }), jsxRuntime.jsxs("div", { style: previewPriceStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), hasSavings && (jsxRuntime.jsx("div", { style: { ...previewPriceStyles, color: "var(--bw-highlight-color)" }, children: t("upsells.savePercent", { percent: upsell.savingsPercent ?? 0 }) }))] }), jsxRuntime.jsxs("div", { style: headerRightStyles, children: [jsxRuntime.jsx("button", { type: "button", onClick: (event) => {
15585
+ event.stopPropagation();
15586
+ onSelect();
15587
+ }, "aria-label": t("common.extras"), style: { background: "transparent", border: "none", cursor: "pointer", padding: 0 }, disabled: isDisabled, children: jsxRuntime.jsx("div", { style: isSelected ? checkboxSelectedStyles : checkboxInnerStyles, children: isSelected && (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", style: { width: "32px", height: "32px" }, children: jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) })) }) }), jsxRuntime.jsx("span", { style: { ...chevronStyles, transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)" }, children: "\u25BC" })] })] }), isExpanded && (jsxRuntime.jsxs("div", { style: expandedContentStyles, children: [jsxRuntime.jsx("div", { style: expandedImageContainerStyles, children: upsell.image ? (jsxRuntime.jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsxRuntime.jsx("div", { style: imagePlaceholderStyles, children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "40px", height: "40px", opacity: 0.4 }, children: jsxRuntime.jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), upsell.description && (jsxRuntime.jsx("p", { style: descriptionStyles, children: upsell.description })), upsell.items.length > 0 && (jsxRuntime.jsx("div", { style: itemsContainerStyles, children: upsell.items.map((item, index) => (jsxRuntime.jsxs("span", { style: itemStyles, children: [item.type === "product" ? "📦" : "🎫", " ", item.name, item.quantity > 1 && ` (${item.quantity}x)`] }, index))) })), upsell.suggestedEventInstance && (jsxRuntime.jsxs("div", { style: eventInfoStyles, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-color)", fontWeight: 500 }, children: ["\uD83D\uDCC5 ", new Date(upsell.suggestedEventInstance.date).toLocaleDateString(locale === "de" ? "de-DE" : locale === "en" ? "en-US" : locale === "es" ? "es-ES" : locale === "sv" ? "sv-SE" : "pt-PT", {
15375
15588
  weekday: "short",
15376
15589
  day: "numeric",
15377
15590
  month: "short",
15378
- })] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)" }, children: t("upsells.spotsFree", { count: upsell.suggestedEventInstance.availableSpots }) })] }))] }), jsxRuntime.jsxs("div", { style: priceContainerStyles, children: [jsxRuntime.jsxs("span", { style: pricePerPersonStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), participantCount > 1 && (jsxRuntime.jsxs("span", { style: priceTotalStyles, children: ["= ", formatCurrency(totalPrice)] }))] }), isDisabled && (jsxRuntime.jsx("div", { style: unavailableOverlayStyles, children: jsxRuntime.jsx("span", { children: upsell.unavailableReason
15591
+ })] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)" }, children: t("upsells.spotsFree", { count: upsell.suggestedEventInstance.availableSpots }) })] })), jsxRuntime.jsxs("div", { style: priceContainerStyles, children: [jsxRuntime.jsxs("span", { style: pricePerPersonStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), participantCount > 1 && (jsxRuntime.jsxs("span", { style: priceTotalStyles, children: ["= ", formatCurrency(totalPrice)] })), hasSavings && (jsxRuntime.jsx("span", { style: priceTotalStyles, children: t("upsells.savePercent", { percent: upsell.savingsPercent ?? 0 }) }))] })] })), isDisabled && (jsxRuntime.jsx("div", { style: unavailableOverlayStyles, children: jsxRuntime.jsx("span", { children: upsell.unavailableReason
15379
15592
  ? formatUnavailableReason(upsell.unavailableReason, t)
15380
15593
  : t("upsells.notAvailable") }) }))] }));
15381
15594
  }
@@ -15394,20 +15607,9 @@ function UpsellsStep({ upsells, selectedUpsells, participantCount, isLoading, is
15394
15607
  }
15395
15608
  };
15396
15609
  const isSelected = (upsellId) => selectedUpsells.some((s) => s.upsellPackageId === upsellId);
15397
- // Calculate total for selected upsells
15398
- const calculateTotal = () => {
15399
- return selectedUpsells.reduce((total, selection) => {
15400
- const upsell = upsells.find((u) => u.id === selection.upsellPackageId);
15401
- if (upsell) {
15402
- return total + upsell.price * selection.quantity;
15403
- }
15404
- return total;
15405
- }, 0);
15406
- };
15407
- const selectedTotal = calculateTotal();
15408
15610
  const selectedCount = selectedUpsells.length;
15409
15611
  const footerContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: onBack, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), className: buttonClassName, children: t("common.back") }), jsxRuntime.jsx("button", { type: "button", onClick: onContinue, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), className: buttonClassName, children: selectedCount === 0 ? t("button.continueWithout") : t("button.continue") })] }));
15410
- return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: onClose, title: t("upsells.title"), footer: footerContent, children: jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", padding: "16px 16px" }, children: [isLoading && (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "12px", padding: "40px 20px", ...textStyles.muted }, children: [spinner(), jsxRuntime.jsx("span", { children: t("upsells.loading") })] })), !isLoading && upsells.length === 0 && (jsxRuntime.jsx("div", { style: { textAlign: "center", padding: "40px 20px", ...textStyles.muted }, children: jsxRuntime.jsx("p", { children: t("upsells.noExtras") }) })), !isLoading && upsells.length > 0 && (jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", flex: 1, overflowY: "auto", paddingBottom: "16px" }, children: upsells.map((upsell) => (jsxRuntime.jsx(UpsellCard, { upsell: upsell, isSelected: isSelected(upsell.id), participantCount: participantCount, onSelect: () => selectUpsell(upsell.id) }, upsell.id))) })), selectedCount > 0 && (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", marginTop: "16px", paddingBottom: "16px", paddingTop: "16px", borderTop: "1px solid var(--bw-border-color)", fontSize: "14px" }, children: [jsxRuntime.jsx("span", { style: textStyles.muted, children: selectedCount === 1 ? t("upsells.selected", { count: selectedCount }) : t("upsells.selectedPlural", { count: selectedCount }) }), jsxRuntime.jsxs("span", { style: { fontWeight: 600, color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+", formatCurrency(selectedTotal)] })] }))] }) }));
15612
+ return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: onClose, title: t("upsells.title"), footer: footerContent, children: jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", padding: "16px 16px" }, children: [jsxRuntime.jsx(FlowProgress, { currentStep: "upsells", hasUpsellsStep: true }), isLoading && (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "12px", padding: "40px 20px", ...textStyles.muted }, children: [spinner(), jsxRuntime.jsx("span", { children: t("upsells.loading") })] })), !isLoading && upsells.length === 0 && (jsxRuntime.jsx("div", { style: { textAlign: "center", padding: "40px 20px", ...textStyles.muted }, children: jsxRuntime.jsx("p", { children: t("upsells.noExtras") }) })), !isLoading && upsells.length > 0 && (jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", flex: 1, overflowY: "auto", paddingBottom: "16px" }, children: upsells.map((upsell) => (jsxRuntime.jsx(UpsellCard, { upsell: upsell, isSelected: isSelected(upsell.id), participantCount: participantCount, onSelect: () => selectUpsell(upsell.id) }, upsell.id))) })), selectedCount > 0 && (jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", marginTop: "16px", paddingBottom: "16px", paddingTop: "16px", borderTop: "1px solid var(--bw-border-color)", fontSize: "14px" }, children: jsxRuntime.jsx("span", { style: textStyles.muted, children: selectedCount === 1 ? t("upsells.selected", { count: selectedCount }) : t("upsells.selectedPlural", { count: selectedCount }) }) }))] }) }));
15411
15613
  }
15412
15614
 
15413
15615
  /**
@@ -15545,8 +15747,10 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
15545
15747
  // Upsells state
15546
15748
  const [upsells, setUpsells] = React.useState([]);
15547
15749
  const [selectedUpsells, setSelectedUpsells] = React.useState([]);
15750
+ const [bookingPersistedState, setBookingPersistedState] = React.useState(null);
15548
15751
  const [isLoadingUpsells, setIsLoadingUpsells] = React.useState(false);
15549
15752
  const [tempParticipantCount, setTempParticipantCount] = React.useState(1); // Used during upsell step
15753
+ const hasUpsellsFlowStep = upsells.length > 0 || currentStep === "upsells";
15550
15754
  // State for upcoming events (next-events view mode)
15551
15755
  const [upcomingEvents, setUpcomingEvents] = React.useState([]);
15552
15756
  const [showingPreview, setShowingPreview] = React.useState(true);
@@ -15673,6 +15877,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
15673
15877
  ...(data.mollieProfileId ? { mollieProfileId: data.mollieProfileId } : {}),
15674
15878
  ...(data.mollieTestmode !== undefined ? { mollieTestmode: data.mollieTestmode } : {}),
15675
15879
  roundPricesEnabled: data.roundPricesEnabled ?? true,
15880
+ widgetPaymentMode: data.widgetPaymentMode ?? "all",
15676
15881
  });
15677
15882
  }
15678
15883
  }
@@ -16037,6 +16242,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16037
16242
  mollieProfileId: data.mollieProfileId,
16038
16243
  mollieTestmode: data.mollieTestmode,
16039
16244
  roundPricesEnabled: data.roundPricesEnabled ?? true,
16245
+ widgetPaymentMode: data.widgetPaymentMode ?? "all",
16040
16246
  });
16041
16247
  }
16042
16248
  if (data.stripePublishableKey) {
@@ -16097,6 +16303,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16097
16303
  mollieProfileId: data.mollieProfileId,
16098
16304
  mollieTestmode: data.mollieTestmode,
16099
16305
  roundPricesEnabled: data.roundPricesEnabled ?? true,
16306
+ widgetPaymentMode: data.widgetPaymentMode ?? "all",
16100
16307
  });
16101
16308
  if (!stripePromise && data.stripePublishableKey) {
16102
16309
  const stripeOptions = {
@@ -16199,6 +16406,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16199
16406
  const handleEventInstanceSelect = async (eventInstance) => {
16200
16407
  trackEvent("event_instance_selected", { eventInstanceId: eventInstance.id, eventInstanceName: eventInstance.name });
16201
16408
  setSelectedEventInstance(eventInstance);
16409
+ setBookingPersistedState(null);
16202
16410
  bookingReturnStep.current = "eventInstances";
16203
16411
  // Set default participant count for upsell calculations
16204
16412
  const defaultParticipantCount = 1;
@@ -16252,6 +16460,21 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16252
16460
  setCurrentStep(bookingReturnStep.current);
16253
16461
  setSelectedEventInstance(null);
16254
16462
  setEventDetails(null);
16463
+ setBookingPersistedState(null);
16464
+ };
16465
+ const handleBackFromBooking = () => {
16466
+ if (upsells.length > 0) {
16467
+ setCurrentStep("upsells");
16468
+ return;
16469
+ }
16470
+ if (isDirectInstanceMode) {
16471
+ setCurrentStep("eventTypes");
16472
+ setSidebarOpen(false);
16473
+ setEventDetails(null);
16474
+ setBookingPersistedState(null);
16475
+ return;
16476
+ }
16477
+ handleBackToEventInstances();
16255
16478
  };
16256
16479
  const handleBookingSuccess = (result) => {
16257
16480
  trackEvent("booking_completed", { paymentIntentId: result.paymentIntent?.id });
@@ -16259,6 +16482,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16259
16482
  setSuccessPaymentId(result.paymentIntent.id);
16260
16483
  setSidebarOpen(false);
16261
16484
  setShouldRenderBookingForm(false);
16485
+ setBookingPersistedState(null);
16262
16486
  config.onSuccess?.(result);
16263
16487
  };
16264
16488
  const handleBookingError = (errorMessage) => {
@@ -16327,6 +16551,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16327
16551
  ? (eventTypes.find((et) => et.id === eventTypeId) ?? selectedEventType)
16328
16552
  : selectedEventType;
16329
16553
  if (resolvedEventType && resolvedEventType !== selectedEventType) {
16554
+ trackEvent("event_type_selected", { eventTypeId: resolvedEventType.id, eventTypeName: resolvedEventType.name });
16330
16555
  setSelectedEventType(resolvedEventType);
16331
16556
  }
16332
16557
  // Check if this is coming from a card preview (eventTypeId was provided)
@@ -16380,7 +16605,9 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16380
16605
  }
16381
16606
  : null;
16382
16607
  if (eventInstance) {
16608
+ trackEvent("event_instance_selected", { eventInstanceId: eventInstance.id, eventInstanceName: eventInstance.name });
16383
16609
  setSelectedEventInstance(eventInstance);
16610
+ setBookingPersistedState(null);
16384
16611
  }
16385
16612
  setError(null);
16386
16613
  // Check for upsells before going to booking (same as handleEventInstanceSelect)
@@ -16544,19 +16771,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16544
16771
  }
16545
16772
  // Main view based on view mode
16546
16773
  if (viewMode === "next-events" && showingPreview) {
16547
- return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: () => {
16548
- setCurrentStep("eventTypes");
16549
- setShowingPreview(true);
16550
- setEventDetails(null);
16551
- }, onBackToEventTypes: () => {
16552
- setCurrentStep("eventTypes");
16553
- setShowingPreview(true);
16554
- setEventDetails(null);
16555
- }, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => {
16556
- setCurrentStep("eventTypes");
16557
- setShowingPreview(true);
16558
- setEventDetails(null);
16559
- }, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16774
+ return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16560
16775
  setIsSuccess(false);
16561
16776
  setCurrentStep("eventTypes");
16562
16777
  setShowingPreview(true);
@@ -16566,6 +16781,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16566
16781
  setShouldRenderBookingForm(false);
16567
16782
  setSelectedUpsells([]);
16568
16783
  setUpsells([]);
16784
+ setBookingPersistedState(null);
16569
16785
  const url = new URL(window.location.href);
16570
16786
  url.searchParams.delete("payment_intent");
16571
16787
  url.searchParams.delete("payment_intent_client_secret");
@@ -16576,19 +16792,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16576
16792
  }, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsxRuntime.jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16577
16793
  }
16578
16794
  if (viewMode === "specials" && showingPreview) {
16579
- return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(SpecialsView, { specials: specials, onEventSelect: handleUpcomingEventSelect, isLoading: isLoadingSpecials, showSavingsAmount: config.specialsSettings?.showSavingsAmount ?? true, showSavingsPercent: config.specialsSettings?.showSavingsPercent ?? false, emptyStateText: config.specialsSettings?.emptyStateText }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: () => {
16580
- setCurrentStep("eventTypes");
16581
- setShowingPreview(true);
16582
- setEventDetails(null);
16583
- }, onBackToEventTypes: () => {
16584
- setCurrentStep("eventTypes");
16585
- setShowingPreview(true);
16586
- setEventDetails(null);
16587
- }, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => {
16588
- setCurrentStep("eventTypes");
16589
- setShowingPreview(true);
16590
- setEventDetails(null);
16591
- }, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16795
+ return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(SpecialsView, { specials: specials, onEventSelect: handleUpcomingEventSelect, isLoading: isLoadingSpecials, showSavingsAmount: config.specialsSettings?.showSavingsAmount ?? true, showSavingsPercent: config.specialsSettings?.showSavingsPercent ?? false, emptyStateText: config.specialsSettings?.emptyStateText }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16592
16796
  setIsSuccess(false);
16593
16797
  setCurrentStep("eventTypes");
16594
16798
  setShowingPreview(true);
@@ -16598,6 +16802,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16598
16802
  setShouldRenderBookingForm(false);
16599
16803
  setSelectedUpsells([]);
16600
16804
  setUpsells([]);
16805
+ setBookingPersistedState(null);
16601
16806
  }, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsxRuntime.jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16602
16807
  }
16603
16808
  if (viewMode === "next-events" && !showingPreview && currentStep === "eventInstances") {
@@ -16607,7 +16812,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16607
16812
  }, isOpen: currentStep === "eventInstances", onClose: () => {
16608
16813
  setShowingPreview(true);
16609
16814
  setCurrentStep("eventTypes");
16610
- }, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16815
+ }, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16611
16816
  setIsSuccess(false);
16612
16817
  setCurrentStep("eventTypes");
16613
16818
  setShowingPreview(true);
@@ -16650,7 +16855,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16650
16855
  setShouldRenderInstanceSelection(true);
16651
16856
  }
16652
16857
  }, children: config.buttonText ||
16653
- (isDirectInstanceMode ? t("button.bookNow") : t("button.selectDate")) }), shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: () => setCurrentStep(isDirectInstanceMode ? "eventTypes" : "eventInstances"), onBackToEventTypes: () => setSidebarOpen(false), selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => setCurrentStep(isDirectInstanceMode ? "eventTypes" : "eventInstances"), systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16858
+ (isDirectInstanceMode ? t("button.bookNow") : t("button.selectDate")) }), shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16654
16859
  setIsSuccess(false);
16655
16860
  setCurrentStep("eventTypes");
16656
16861
  setSidebarOpen(false);
@@ -16682,32 +16887,36 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16682
16887
  // Determine the correct back handlers based on view mode
16683
16888
  const getBackHandlers = () => {
16684
16889
  if (viewMode === "next-events") {
16685
- return {
16686
- onBackToEventInstances: () => {
16687
- setCurrentStep("eventInstances");
16890
+ const backFromBooking = () => {
16891
+ if (upsells.length > 0) {
16892
+ setCurrentStep("upsells");
16688
16893
  setShowingPreview(false);
16689
- setEventDetails(null);
16690
- },
16894
+ return;
16895
+ }
16896
+ setCurrentStep("eventInstances");
16897
+ setShowingPreview(false);
16898
+ setEventDetails(null);
16899
+ setBookingPersistedState(null);
16900
+ };
16901
+ return {
16902
+ onBackToEventInstances: backFromBooking,
16691
16903
  onBackToEventTypes: () => {
16692
16904
  setShowingPreview(true);
16693
16905
  setCurrentStep("eventTypes");
16694
16906
  setEventDetails(null);
16907
+ setBookingPersistedState(null);
16695
16908
  },
16696
- onClose: () => {
16697
- setCurrentStep("eventInstances");
16698
- setShowingPreview(false);
16699
- setEventDetails(null);
16700
- },
16909
+ onClose: backFromBooking,
16701
16910
  };
16702
16911
  }
16703
16912
  return {
16704
- onBackToEventInstances: handleBackToEventInstances,
16913
+ onBackToEventInstances: handleBackFromBooking,
16705
16914
  onBackToEventTypes: handleBackToEventTypes,
16706
- onClose: handleBackToEventInstances,
16915
+ onClose: handleBackFromBooking,
16707
16916
  };
16708
16917
  };
16709
16918
  const backHandlers = getBackHandlers();
16710
- return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: backHandlers.onBackToEventInstances, onBackToEventTypes: backHandlers.onBackToEventTypes, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: backHandlers.onClose, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess && !voucherPurchaseResult, onClose: () => {
16919
+ return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: backHandlers.onClose, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess && !voucherPurchaseResult, onClose: () => {
16711
16920
  setIsSuccess(false);
16712
16921
  setCurrentStep("eventTypes");
16713
16922
  setSuccessPaymentId(null);