@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.esm.js CHANGED
@@ -225,6 +225,8 @@ const de$1 = {
225
225
  "button.depositAndBook": "Anzahlen & buchen",
226
226
  "button.continueWithout": "Weiter ohne Extras",
227
227
  "button.continue": "Weiter",
228
+ "button.continueToPayment": "Weiter zur Zahlung",
229
+ "button.backToDetails": "Zurück zu den Angaben",
228
230
  "button.addExtras": "Extras hinzufügen",
229
231
  // Event types
230
232
  "events.noEventsAvailable": "Keine Veranstaltungen verfügbar",
@@ -234,6 +236,7 @@ const de$1 = {
234
236
  "events.availableFrom": "Freie Plätze ab {{date}}",
235
237
  "events.noAvailableDates": "Keine Termine frei",
236
238
  "events.previewSectionTitle": "Specials & nächste Termine",
239
+ "events.seeMoreDates": "Weitere Termine ansehen...",
237
240
  // Event instances
238
241
  "instances.title": "Terminauswahl",
239
242
  "instances.noAvailable": "Keine verfügbaren Termine",
@@ -287,6 +290,10 @@ const de$1 = {
287
290
  "booking.maxSpotsReached": "Maximal {{count}} Plätze verfügbar.",
288
291
  "booking.comment": "Kommentar (optional)",
289
292
  "booking.commentPlaceholder": "Zusätzliche Anmerkungen zur Buchung...",
293
+ "booking.stepDate": "Termin",
294
+ "booking.stepUpsells": "Extras",
295
+ "booking.stepDetails": "Angaben",
296
+ "booking.stepPayment": "Zahlung",
290
297
  // Booking summary
291
298
  "summary.title": "Buchungszusammenfassung",
292
299
  "summary.subtotal": "Zwischensumme:",
@@ -417,6 +424,9 @@ const de$1 = {
417
424
  "upsells.noExtras": "Keine Extras für diese Buchung verfügbar.",
418
425
  "upsells.selected": "{{count}} Extra ausgewählt",
419
426
  "upsells.selectedPlural": "{{count}} Extras ausgewählt",
427
+ "upsells.savePercent": "{{percent}}% sparen",
428
+ "booking.paymentUnavailable": "Online-Zahlung ist für diese Buchung nicht verfügbar. Bitte kontaktiere uns, um die Reservierung abzuschließen.",
429
+ "booking.depositNotConfigured": "Online-Anzahlung ist für dieses Event nicht verfügbar. Bitte kontaktiere uns, um die Reservierung abzuschließen.",
420
430
  "upsells.spotsFree": "{{count}} Plätze frei",
421
431
  "upsells.notAvailable": "Nicht verfügbar",
422
432
  "upsells.reason.outOfStock": "{{productName}} ist nicht auf Lager",
@@ -442,6 +452,9 @@ const de$1 = {
442
452
  "promo.giftCode": "Dein Geschenk-Code",
443
453
  "promo.copied": "Kopiert!",
444
454
  "promo.copy": "Kopieren",
455
+ "trust.securePayment": "Sichere Zahlung",
456
+ "trust.paypal": "PayPal",
457
+ "trust.stripe": "Stripe",
445
458
  };
446
459
 
447
460
  const en = {
@@ -501,6 +514,8 @@ const en = {
501
514
  "button.depositAndBook": "Pay deposit & book",
502
515
  "button.continueWithout": "Continue without extras",
503
516
  "button.continue": "Continue",
517
+ "button.continueToPayment": "Continue to payment",
518
+ "button.backToDetails": "Back to details",
504
519
  "button.addExtras": "Add extras",
505
520
  // Event types
506
521
  "events.noEventsAvailable": "No events available",
@@ -510,6 +525,7 @@ const en = {
510
525
  "events.availableFrom": "Available from {{date}}",
511
526
  "events.noAvailableDates": "No dates available",
512
527
  "events.previewSectionTitle": "Specials & upcoming dates",
528
+ "events.seeMoreDates": "See more dates...",
513
529
  // Event instances
514
530
  "instances.title": "Select a date",
515
531
  "instances.noAvailable": "No available dates",
@@ -563,6 +579,10 @@ const en = {
563
579
  "booking.maxSpotsReached": "Maximum {{count}} spots available.",
564
580
  "booking.comment": "Comment (optional)",
565
581
  "booking.commentPlaceholder": "Additional notes for the booking...",
582
+ "booking.stepDate": "Date",
583
+ "booking.stepUpsells": "Extras",
584
+ "booking.stepDetails": "Details",
585
+ "booking.stepPayment": "Payment",
566
586
  // Booking summary
567
587
  "summary.title": "Booking Summary",
568
588
  "summary.subtotal": "Subtotal:",
@@ -693,6 +713,9 @@ const en = {
693
713
  "upsells.noExtras": "No extras available for this booking.",
694
714
  "upsells.selected": "{{count}} extra selected",
695
715
  "upsells.selectedPlural": "{{count}} extras selected",
716
+ "upsells.savePercent": "Save {{percent}}%",
717
+ "booking.paymentUnavailable": "Online payment is not available for this booking. Please contact us to complete your reservation.",
718
+ "booking.depositNotConfigured": "Online deposit payment is not available for this event. Please contact us to complete your reservation.",
696
719
  "upsells.spotsFree": "{{count}} spots available",
697
720
  "upsells.notAvailable": "Not available",
698
721
  "upsells.reason.outOfStock": "{{productName}} is out of stock",
@@ -718,6 +741,9 @@ const en = {
718
741
  "promo.giftCode": "Your gift code",
719
742
  "promo.copied": "Copied!",
720
743
  "promo.copy": "Copy",
744
+ "trust.securePayment": "Secure payment",
745
+ "trust.paypal": "PayPal",
746
+ "trust.stripe": "Stripe",
721
747
  };
722
748
 
723
749
  const es = {
@@ -777,6 +803,8 @@ const es = {
777
803
  "button.depositAndBook": "Pagar depósito y reservar",
778
804
  "button.continueWithout": "Continuar sin extras",
779
805
  "button.continue": "Continuar",
806
+ "button.continueToPayment": "Continuar al pago",
807
+ "button.backToDetails": "Volver a los datos",
780
808
  "button.addExtras": "Añadir extras",
781
809
  // Event types
782
810
  "events.noEventsAvailable": "No hay eventos disponibles",
@@ -786,6 +814,7 @@ const es = {
786
814
  "events.availableFrom": "Disponible desde {{date}}",
787
815
  "events.noAvailableDates": "Sin fechas disponibles",
788
816
  "events.previewSectionTitle": "Especiales & próximas fechas",
817
+ "events.seeMoreDates": "Ver más fechas...",
789
818
  // Event instances
790
819
  "instances.title": "Seleccionar fecha",
791
820
  "instances.noAvailable": "Sin fechas disponibles",
@@ -839,6 +868,10 @@ const es = {
839
868
  "booking.maxSpotsReached": "Máximo {{count}} plazas disponibles.",
840
869
  "booking.comment": "Comentario (opcional)",
841
870
  "booking.commentPlaceholder": "Notas adicionales para la reserva...",
871
+ "booking.stepDate": "Fecha",
872
+ "booking.stepUpsells": "Extras",
873
+ "booking.stepDetails": "Datos",
874
+ "booking.stepPayment": "Pago",
842
875
  // Booking summary
843
876
  "summary.title": "Resumen de la reserva",
844
877
  "summary.subtotal": "Subtotal:",
@@ -969,6 +1002,9 @@ const es = {
969
1002
  "upsells.noExtras": "No hay extras disponibles para esta reserva.",
970
1003
  "upsells.selected": "{{count}} extra seleccionado",
971
1004
  "upsells.selectedPlural": "{{count}} extras seleccionados",
1005
+ "upsells.savePercent": "Ahorra {{percent}}%",
1006
+ "booking.paymentUnavailable": "El pago en línea no está disponible para esta reserva. Contáctanos para completarla.",
1007
+ "booking.depositNotConfigured": "El pago de depósito en línea no está disponible para este evento. Contáctanos para completar la reserva.",
972
1008
  "upsells.spotsFree": "{{count}} plazas disponibles",
973
1009
  "upsells.notAvailable": "No disponible",
974
1010
  "upsells.reason.outOfStock": "{{productName}} está agotado",
@@ -994,6 +1030,9 @@ const es = {
994
1030
  "promo.giftCode": "Tu codigo de regalo",
995
1031
  "promo.copied": "Copiado!",
996
1032
  "promo.copy": "Copiar",
1033
+ "trust.securePayment": "Pago seguro",
1034
+ "trust.paypal": "PayPal",
1035
+ "trust.stripe": "Stripe",
997
1036
  };
998
1037
 
999
1038
  const pt = {
@@ -1053,6 +1092,8 @@ const pt = {
1053
1092
  "button.depositAndBook": "Pagar sinal e reservar",
1054
1093
  "button.continueWithout": "Continuar sem extras",
1055
1094
  "button.continue": "Continuar",
1095
+ "button.continueToPayment": "Continuar para pagamento",
1096
+ "button.backToDetails": "Voltar aos dados",
1056
1097
  "button.addExtras": "Adicionar extras",
1057
1098
  // Event types
1058
1099
  "events.noEventsAvailable": "Sem eventos disponíveis",
@@ -1062,6 +1103,7 @@ const pt = {
1062
1103
  "events.availableFrom": "Disponível a partir de {{date}}",
1063
1104
  "events.noAvailableDates": "Sem datas disponíveis",
1064
1105
  "events.previewSectionTitle": "Especiais & próximas datas",
1106
+ "events.seeMoreDates": "Ver mais datas...",
1065
1107
  // Event instances
1066
1108
  "instances.title": "Selecionar data",
1067
1109
  "instances.noAvailable": "Sem datas disponíveis",
@@ -1115,6 +1157,10 @@ const pt = {
1115
1157
  "booking.maxSpotsReached": "Máximo {{count}} lugares disponíveis.",
1116
1158
  "booking.comment": "Comentário (opcional)",
1117
1159
  "booking.commentPlaceholder": "Notas adicionais para a reserva...",
1160
+ "booking.stepDate": "Data",
1161
+ "booking.stepUpsells": "Extras",
1162
+ "booking.stepDetails": "Dados",
1163
+ "booking.stepPayment": "Pagamento",
1118
1164
  // Booking summary
1119
1165
  "summary.title": "Resumo da reserva",
1120
1166
  "summary.subtotal": "Subtotal:",
@@ -1245,6 +1291,9 @@ const pt = {
1245
1291
  "upsells.noExtras": "Sem extras disponíveis para esta reserva.",
1246
1292
  "upsells.selected": "{{count}} extra selecionado",
1247
1293
  "upsells.selectedPlural": "{{count}} extras selecionados",
1294
+ "upsells.savePercent": "Poupa {{percent}}%",
1295
+ "booking.paymentUnavailable": "O pagamento online não está disponível para esta reserva. Contacta-nos para concluir a reserva.",
1296
+ "booking.depositNotConfigured": "O pagamento de depósito online não está disponível para este evento. Contacta-nos para concluir a reserva.",
1248
1297
  "upsells.spotsFree": "{{count}} lugares disponíveis",
1249
1298
  "upsells.notAvailable": "Não disponível",
1250
1299
  "upsells.reason.outOfStock": "{{productName}} está esgotado",
@@ -1270,6 +1319,9 @@ const pt = {
1270
1319
  "promo.giftCode": "O teu codigo de oferta",
1271
1320
  "promo.copied": "Copiado!",
1272
1321
  "promo.copy": "Copiar",
1322
+ "trust.securePayment": "Pagamento seguro",
1323
+ "trust.paypal": "PayPal",
1324
+ "trust.stripe": "Stripe",
1273
1325
  };
1274
1326
 
1275
1327
  const sv = {
@@ -1329,6 +1381,8 @@ const sv = {
1329
1381
  "button.depositAndBook": "Betala handpenning & boka",
1330
1382
  "button.continueWithout": "Fortsätt utan tillägg",
1331
1383
  "button.continue": "Fortsätt",
1384
+ "button.continueToPayment": "Fortsätt till betalning",
1385
+ "button.backToDetails": "Tillbaka till uppgifter",
1332
1386
  "button.addExtras": "Lägg till tillägg",
1333
1387
  // Event types
1334
1388
  "events.noEventsAvailable": "Inga evenemang tillgängliga",
@@ -1338,6 +1392,7 @@ const sv = {
1338
1392
  "events.availableFrom": "Lediga platser från {{date}}",
1339
1393
  "events.noAvailableDates": "Inga datum lediga",
1340
1394
  "events.previewSectionTitle": "Specials & kommande datum",
1395
+ "events.seeMoreDates": "Se fler datum...",
1341
1396
  // Event instances
1342
1397
  "instances.title": "Välj datum",
1343
1398
  "instances.noAvailable": "Inga tillgängliga datum",
@@ -1391,6 +1446,10 @@ const sv = {
1391
1446
  "booking.maxSpotsReached": "Maximalt {{count}} platser tillgängliga.",
1392
1447
  "booking.comment": "Kommentar (valfritt)",
1393
1448
  "booking.commentPlaceholder": "Ytterligare anteckningar för bokningen...",
1449
+ "booking.stepDate": "Datum",
1450
+ "booking.stepUpsells": "Tillägg",
1451
+ "booking.stepDetails": "Uppgifter",
1452
+ "booking.stepPayment": "Betalning",
1394
1453
  // Booking summary
1395
1454
  "summary.title": "Bokningssammanfattning",
1396
1455
  "summary.subtotal": "Delsumma:",
@@ -1521,6 +1580,9 @@ const sv = {
1521
1580
  "upsells.noExtras": "Inga tillägg tillgängliga för denna bokning.",
1522
1581
  "upsells.selected": "{{count}} tillägg valt",
1523
1582
  "upsells.selectedPlural": "{{count}} tillägg valda",
1583
+ "upsells.savePercent": "Spara {{percent}}%",
1584
+ "booking.paymentUnavailable": "Onlinebetalning är inte tillgänglig för denna bokning. Kontakta oss för att slutföra bokningen.",
1585
+ "booking.depositNotConfigured": "Online deposition är inte tillgänglig för detta evenemang. Kontakta oss för att slutföra bokningen.",
1524
1586
  "upsells.spotsFree": "{{count}} platser lediga",
1525
1587
  "upsells.notAvailable": "Inte tillgängligt",
1526
1588
  "upsells.reason.outOfStock": "{{productName}} är slut i lager",
@@ -1546,6 +1608,9 @@ const sv = {
1546
1608
  "promo.giftCode": "Din presentkod",
1547
1609
  "promo.copied": "Kopierad!",
1548
1610
  "promo.copy": "Kopiera",
1611
+ "trust.securePayment": "Säker betalning",
1612
+ "trust.paypal": "PayPal",
1613
+ "trust.stripe": "Stripe",
1549
1614
  };
1550
1615
 
1551
1616
  const SUPPORTED_LOCALES = ["de", "en", "es", "sv", "pt"];
@@ -7244,6 +7309,55 @@ function Accordion({ title, priceInfo, children, isOpen, onToggle, }) {
7244
7309
  }, children: children }))] }));
7245
7310
  }
7246
7311
 
7312
+ function FlowProgress({ currentStep, hasUpsellsStep }) {
7313
+ const t = useTranslations();
7314
+ const steps = hasUpsellsStep
7315
+ ? [
7316
+ { key: "date", label: t("booking.stepDate") },
7317
+ { key: "upsells", label: t("booking.stepUpsells") },
7318
+ { key: "details", label: t("booking.stepDetails") },
7319
+ { key: "payment", label: t("booking.stepPayment") },
7320
+ ]
7321
+ : [
7322
+ { key: "date", label: t("booking.stepDate") },
7323
+ { key: "details", label: t("booking.stepDetails") },
7324
+ { key: "payment", label: t("booking.stepPayment") },
7325
+ ];
7326
+ const activeIndex = Math.max(steps.findIndex((step) => step.key === currentStep), 0);
7327
+ const progressPercent = steps.length > 1 ? (activeIndex / (steps.length - 1)) * 100 : 100;
7328
+ return (jsxs("div", { style: {
7329
+ backgroundColor: "var(--bw-surface-color)",
7330
+ border: "1px solid var(--bw-border-color)",
7331
+ borderRadius: "var(--bw-border-radius)",
7332
+ padding: "12px 14px",
7333
+ marginBottom: "16px",
7334
+ }, children: [jsx("div", { style: {
7335
+ display: "flex",
7336
+ justifyContent: "space-between",
7337
+ alignItems: "center",
7338
+ marginBottom: "10px",
7339
+ fontFamily: "var(--bw-font-family)",
7340
+ gap: "8px",
7341
+ }, children: steps.map((step, index) => (jsxs("span", { style: {
7342
+ fontSize: "12px",
7343
+ fontWeight: 700,
7344
+ color: index <= activeIndex ? "var(--bw-highlight-color)" : "var(--bw-text-muted)",
7345
+ whiteSpace: "nowrap",
7346
+ }, children: [index + 1, ". ", step.label] }, step.key))) }), jsx("div", { style: {
7347
+ width: "100%",
7348
+ height: "8px",
7349
+ borderRadius: "999px",
7350
+ backgroundColor: "var(--bw-background-color)",
7351
+ border: "1px solid var(--bw-border-color)",
7352
+ overflow: "hidden",
7353
+ }, children: jsx("div", { style: {
7354
+ width: `${progressPercent}%`,
7355
+ height: "100%",
7356
+ backgroundColor: "var(--bw-highlight-color)",
7357
+ transition: "width 0.25s ease",
7358
+ } }) })] }));
7359
+ }
7360
+
7247
7361
  // Spinner icon (kept local as it has animation style)
7248
7362
  const IconSpinner = ({ size = 16, color = "currentColor" }) => (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: jsx("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" }) }));
7249
7363
  function VoucherInput({ config, orderValue, eventInstanceId, customerEmail, onVoucherValidated, appliedVouchers, onRemoveVoucher, disabled = false, }) {
@@ -11453,11 +11567,12 @@ const sectionHeaderStyles$1 = sectionStyles.header;
11453
11567
  const labelStyles$1 = formStyles.label;
11454
11568
  const inputStyles$1 = formStyles.input;
11455
11569
  const errorTextStyles$1 = formStyles.error;
11456
- function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError, onBackToEventInstances, onBackToEventTypes, selectedEventType, selectedEventInstance, isOpen, onClose, systemConfig, selectedUpsells = [], upsells = [], }) {
11570
+ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError, isOpen, onClose, systemConfig, selectedUpsells = [], upsells = [], persistedState = null, onPersistedStateChange, }) {
11457
11571
  const t$1 = useTranslations();
11458
11572
  const { locale } = useLocale();
11459
11573
  const timezone = useTimezone();
11460
11574
  const roundEnabled = systemConfig?.roundPricesEnabled !== false;
11575
+ const widgetPaymentMode = systemConfig?.widgetPaymentMode ?? "all";
11461
11576
  const participantFieldsConfig = eventDetails.participantFieldsConfig ?? DEFAULT_PARTICIPANT_FIELDS_CONFIG;
11462
11577
  const participantLevelOptions = eventDetails.participantLevelOptions ?? ["beginner", "advanced"];
11463
11578
  const roundDiscountUp = (minorUnits) => Math.ceil(minorUnits / 100) * 100;
@@ -11465,15 +11580,17 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11465
11580
  const raw = Math.round((baseAmount * basisPoints) / 10000);
11466
11581
  return round ? roundDiscountUp(raw) : raw;
11467
11582
  };
11468
- const [appliedVouchers, setAppliedVouchers] = useState([]);
11469
- const paymentSectionRef = useRef(null);
11583
+ const [appliedVouchers, setAppliedVouchers] = useState(() => persistedState?.appliedVouchers ?? []);
11584
+ const [checkoutStep, setCheckoutStep] = useState(() => persistedState?.checkoutStep ?? "details");
11470
11585
  // Payment option: "deposit" or "full" - only relevant when deposit is available
11471
- const [paymentOption, setPaymentOption] = useState("deposit");
11586
+ const [paymentOption, setPaymentOption] = useState(() => persistedState?.paymentOption ?? "deposit");
11472
11587
  // Per-participant upsell selections: participantIndex -> array of upsell package IDs
11473
- const [participantUpsells, setParticipantUpsells] = useState({});
11588
+ const [participantUpsells, setParticipantUpsells] = useState(() => persistedState?.participantUpsells ?? {});
11589
+ const [showPaymentValidationHint, setShowPaymentValidationHint] = useState(false);
11590
+ const wasOpenRef = useRef(false);
11474
11591
  const form = useForm({
11475
11592
  resolver: t(createBookingFormSchema(t$1, participantFieldsConfig)),
11476
- defaultValues: {
11593
+ defaultValues: persistedState?.formData ?? {
11477
11594
  customerName: "",
11478
11595
  customerEmail: "",
11479
11596
  customerPhone: "",
@@ -11483,6 +11600,28 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11483
11600
  acceptTerms: false,
11484
11601
  },
11485
11602
  });
11603
+ const persistState = useCallback(() => {
11604
+ onPersistedStateChange?.({
11605
+ formData: form.getValues(),
11606
+ checkoutStep,
11607
+ paymentOption,
11608
+ appliedVouchers,
11609
+ participantUpsells,
11610
+ });
11611
+ }, [onPersistedStateChange, form, checkoutStep, paymentOption, appliedVouchers, participantUpsells]);
11612
+ useEffect(() => {
11613
+ if (isOpen && !wasOpenRef.current && persistedState) {
11614
+ form.reset(persistedState.formData);
11615
+ setCheckoutStep(persistedState.checkoutStep);
11616
+ setPaymentOption(persistedState.paymentOption);
11617
+ setAppliedVouchers(persistedState.appliedVouchers);
11618
+ setParticipantUpsells(persistedState.participantUpsells);
11619
+ }
11620
+ if (!isOpen && wasOpenRef.current) {
11621
+ persistState();
11622
+ }
11623
+ wasOpenRef.current = isOpen;
11624
+ }, [isOpen, persistedState, form, persistState]);
11486
11625
  const watchedParticipants = form.watch("participants");
11487
11626
  const participantCount = watchedParticipants.length;
11488
11627
  const watchedCustomerName = form.watch("customerName");
@@ -11571,12 +11710,22 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11571
11710
  const totalDiscount = calculateTotalDiscount();
11572
11711
  const totalAmount = calculateTotal();
11573
11712
  const depositAmount = calculateDeposit();
11574
- // Deposit stays fixed unless the discounted total is lower than the deposit
11575
- // (discount applies to total price, not to the deposit itself)
11576
- const hasDepositOption = depositAmount > 0 && depositAmount < totalAmount;
11577
- const paymentAmount = hasDepositOption && paymentOption === "deposit"
11578
- ? Math.min(depositAmount, totalAmount)
11579
- : totalAmount;
11713
+ const allowsDepositInWidget = widgetPaymentMode === "all" || widgetPaymentMode === "deposits_only";
11714
+ const allowsFullInWidget = widgetPaymentMode === "all" || widgetPaymentMode === "full_only";
11715
+ const hasConfiguredDeposit = depositAmount > 0;
11716
+ const hasDepositChoice = allowsDepositInWidget && hasConfiguredDeposit && depositAmount < totalAmount;
11717
+ const depositsOnlyBlocked = widgetPaymentMode === "deposits_only" && !hasConfiguredDeposit;
11718
+ useEffect(() => {
11719
+ if (widgetPaymentMode === "deposits_only") {
11720
+ setPaymentOption("deposit");
11721
+ }
11722
+ else if (widgetPaymentMode === "full_only") {
11723
+ setPaymentOption("full");
11724
+ }
11725
+ }, [widgetPaymentMode]);
11726
+ const paymentAmount = allowsFullInWidget && (!hasDepositChoice || paymentOption === "full" || !allowsDepositInWidget)
11727
+ ? totalAmount
11728
+ : Math.min(depositAmount, totalAmount);
11580
11729
  // Convert per-participant upsells to UpsellSelection[] format for API
11581
11730
  // Includes participantIndices to track which participants selected each upsell
11582
11731
  const aggregatedUpsellSelections = useCallback(() => {
@@ -11607,6 +11756,18 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11607
11756
  }), [watchedCustomerName, watchedCustomerEmail, watchedCustomerPhone, watchedParticipants, watchedComment]);
11608
11757
  const appliedDiscountCode = appliedVouchers.find((v) => v.type === "discount");
11609
11758
  const appliedGiftCards = appliedVouchers.filter((v) => v.type === "giftCard");
11759
+ const discountCodeProp = appliedDiscountCode
11760
+ ? {
11761
+ id: appliedDiscountCode.id,
11762
+ code: appliedDiscountCode.code,
11763
+ description: appliedDiscountCode.description || undefined,
11764
+ type: appliedDiscountCode.discountType || "percentage",
11765
+ value: appliedDiscountCode.discountValue || 0,
11766
+ discountAmount: appliedDiscountCode.discountAmount,
11767
+ newTotal: appliedDiscountCode.newTotal,
11768
+ }
11769
+ : null;
11770
+ const hasPaymentProvider = Boolean(stripePromise || systemConfig?.paymentProvider === "mollie");
11610
11771
  const handleVoucherValidated = useCallback((voucher, _error) => {
11611
11772
  if (voucher) {
11612
11773
  setAppliedVouchers((prev) => [...prev, voucher]);
@@ -11718,19 +11879,44 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11718
11879
  });
11719
11880
  }, [config]);
11720
11881
  const handleClose = () => {
11882
+ persistState();
11883
+ setCheckoutStep("details");
11721
11884
  onClose();
11722
- if (selectedEventInstance && selectedEventType) {
11723
- onBackToEventInstances?.();
11885
+ };
11886
+ // Footer navigation
11887
+ const canContinueToPayment = isReadyForPayment();
11888
+ const handleContinueToPayment = async () => {
11889
+ if (canContinueToPayment && hasPaymentProvider) {
11890
+ setShowPaymentValidationHint(false);
11891
+ setCheckoutStep("payment");
11892
+ return;
11724
11893
  }
11725
- else if (selectedEventType) {
11726
- onBackToEventTypes?.();
11894
+ const participantErrors = await form.trigger("participants");
11895
+ const customerErrors = await form.trigger(["customerName", "customerEmail", "acceptTerms"]);
11896
+ if (!participantErrors || !customerErrors) {
11897
+ setShowPaymentValidationHint(true);
11727
11898
  }
11728
11899
  };
11729
- const scrollToPayment = () => {
11730
- paymentSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
11731
- };
11732
- // Footer navigation
11733
- const footerContent = (jsxs(Fragment, { children: [jsx("button", { type: "button", onClick: handleClose, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: t$1("common.back") }), jsx("button", { type: "button", onClick: scrollToPayment, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), children: t$1("button.toPayment") })] }));
11900
+ useEffect(() => {
11901
+ if (showPaymentValidationHint && canContinueToPayment) {
11902
+ setShowPaymentValidationHint(false);
11903
+ }
11904
+ }, [showPaymentValidationHint, canContinueToPayment]);
11905
+ const footerContent = (jsxs("div", { style: { width: "100%", display: "flex", flexDirection: "column", gap: "6px" }, children: [checkoutStep === "details" && (jsx("div", { style: {
11906
+ minHeight: "14px",
11907
+ fontSize: "11px",
11908
+ color: "var(--bw-error-color)",
11909
+ textAlign: "center",
11910
+ fontFamily: "var(--bw-font-family)",
11911
+ opacity: showPaymentValidationHint ? 1 : 0,
11912
+ transition: "opacity 0.15s ease",
11913
+ pointerEvents: "none",
11914
+ }, children: t$1("payment.fillRequired") })), jsxs("div", { style: { display: "flex", gap: "12px", width: "100%" }, children: [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" && (jsx("button", { type: "button", onClick: handleContinueToPayment, disabled: !hasPaymentProvider, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth, !canContinueToPayment
11915
+ ? {
11916
+ opacity: 0.55,
11917
+ cursor: "pointer",
11918
+ }
11919
+ : undefined), children: t$1("button.continueToPayment") }))] })] }));
11734
11920
  if (!eventDetails.bookingOpen) {
11735
11921
  return (jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.notPossible"), children: jsx("div", { style: {
11736
11922
  display: "flex",
@@ -11747,264 +11933,211 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
11747
11933
  fontFamily: "var(--bw-font-family)",
11748
11934
  }, children: t$1("booking.notPossible") }), jsx("p", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.notPossibleMessage") })] }) }) }));
11749
11935
  }
11750
- return (jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.title", { name: eventDetails.name }), footer: footerContent, children: jsxs("div", { className: "booking-widget-container", style: { padding: "16px" }, children: [jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.eventDetails") }), jsxs("div", { style: {
11751
- display: "grid",
11752
- gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11753
- gap: "12px",
11754
- fontSize: "14px",
11755
- }, children: [jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxs("span", { style: {
11756
- color: "var(--bw-text-muted)",
11757
- fontFamily: "var(--bw-font-family)",
11758
- display: "flex",
11759
- alignItems: "center",
11760
- gap: "4px",
11761
- }, children: [jsx(IconCalendar, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.date")] }), jsxs("span", { style: {
11762
- color: "var(--bw-text-color)",
11763
- fontWeight: 500,
11764
- fontFamily: "var(--bw-font-family)",
11765
- }, children: [formatEventDate(eventDetails.startTime, timezone, locale), " \u2022 ", formatTime(eventDetails.startTime, timezone, locale)] })] }), jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxs("span", { style: {
11766
- color: "var(--bw-text-muted)",
11767
- fontFamily: "var(--bw-font-family)",
11768
- display: "flex",
11769
- alignItems: "center",
11770
- gap: "4px",
11771
- }, children: [jsx(IconClock, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.duration")] }), jsxs("span", { style: {
11772
- color: "var(--bw-text-color)",
11773
- fontWeight: 500,
11774
- fontFamily: "var(--bw-font-family)",
11775
- }, children: [eventDetails.durationDays, " ", eventDetails.durationDays > 1 ? t$1("common.days") : t$1("common.day")] })] }), jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxs("span", { style: {
11776
- color: "var(--bw-text-muted)",
11777
- fontFamily: "var(--bw-font-family)",
11936
+ return (jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.title", { name: eventDetails.name }), footer: footerContent, children: jsxs("div", { className: "booking-widget-container", style: { padding: "16px" }, children: [jsx(FlowProgress, { currentStep: checkoutStep === "details" ? "details" : "payment", hasUpsellsStep: upsells.length > 0 }), checkoutStep === "details" && (jsxs(Fragment, { children: [jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.eventDetails") }), jsxs("div", { style: {
11937
+ display: "grid",
11938
+ gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11939
+ gap: "12px",
11940
+ fontSize: "14px",
11941
+ }, children: [jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxs("span", { style: {
11942
+ color: "var(--bw-text-muted)",
11943
+ fontFamily: "var(--bw-font-family)",
11944
+ display: "flex",
11945
+ alignItems: "center",
11946
+ gap: "4px",
11947
+ }, children: [jsx(IconCalendar, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.date")] }), jsxs("span", { style: {
11948
+ color: "var(--bw-text-color)",
11949
+ fontWeight: 500,
11950
+ fontFamily: "var(--bw-font-family)",
11951
+ }, children: [formatEventDate(eventDetails.startTime, timezone, locale), " \u2022 ", formatTime(eventDetails.startTime, timezone, locale)] })] }), jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxs("span", { style: {
11952
+ color: "var(--bw-text-muted)",
11953
+ fontFamily: "var(--bw-font-family)",
11954
+ display: "flex",
11955
+ alignItems: "center",
11956
+ gap: "4px",
11957
+ }, children: [jsx(IconClock, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.duration")] }), jsxs("span", { style: {
11958
+ color: "var(--bw-text-color)",
11959
+ fontWeight: 500,
11960
+ fontFamily: "var(--bw-font-family)",
11961
+ }, children: [eventDetails.durationDays, " ", eventDetails.durationDays > 1 ? t$1("common.days") : t$1("common.day")] })] }), jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [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: [jsx(IconMoney, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.price")] }), jsxs("span", { style: {
11968
+ color: "var(--bw-text-color)",
11969
+ fontWeight: 500,
11970
+ fontFamily: "var(--bw-font-family)",
11971
+ }, children: [formatCurrency(eventDetails.price), " ", t$1("common.perPerson")] })] })] })] }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.contactInfo") }), jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "16px" }, children: [jsxs("div", { style: {
11972
+ display: "grid",
11973
+ gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11974
+ gap: "16px",
11975
+ }, children: [jsxs("div", { children: [jsx("label", { htmlFor: "customerName", style: labelStyles$1, children: t$1("booking.name") }), jsx("input", { id: "customerName", ...form.register("customerName"), type: "text", style: inputStyles$1, placeholder: t$1("booking.namePlaceholder") }), customerNameError && (jsx("p", { style: errorTextStyles$1, children: customerNameError.message }))] }), jsxs("div", { children: [jsx("label", { htmlFor: "customerEmail", style: labelStyles$1, children: t$1("booking.email") }), jsx("input", { id: "customerEmail", ...form.register("customerEmail"), type: "email", style: inputStyles$1, placeholder: t$1("booking.emailPlaceholder") }), customerEmailError && (jsx("p", { style: errorTextStyles$1, children: customerEmailError.message }))] })] }), jsxs("div", { children: [jsx("label", { htmlFor: "customerPhone", style: labelStyles$1, children: t$1("booking.phone") }), jsx("input", { id: "customerPhone", ...form.register("customerPhone"), type: "tel", style: inputStyles$1, placeholder: t$1("booking.phonePlaceholder") })] }), jsxs("div", { style: { marginTop: "10px", border: "1px solid var(--bw-border-color)", padding: "16px", borderRadius: "var(--bw-border-radius)" }, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("input", { id: "acceptTerms", ...form.register("acceptTerms"), type: "checkbox", style: formStyles.checkbox }), jsxs("label", { htmlFor: "acceptTerms", style: {
11976
+ fontSize: "14px",
11977
+ color: "var(--bw-text-muted)",
11978
+ fontFamily: "var(--bw-font-family)",
11979
+ maxWidth: "calc(100% - 32px)",
11980
+ overflowWrap: "break-word",
11981
+ cursor: "pointer",
11982
+ }, children: [t$1("booking.acceptTerms"), " ", 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 && (jsx("p", { style: { ...errorTextStyles$1, marginTop: "8px" }, children: form.formState.errors.acceptTerms.message }))] })] })] }), jsxs("div", { style: cardStyles$1, children: [jsx("div", { style: {
11778
11983
  display: "flex",
11984
+ justifyContent: "space-between",
11779
11985
  alignItems: "center",
11780
- gap: "4px",
11781
- }, children: [jsx(IconMoney, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.price")] }), jsxs("span", { style: {
11782
- color: "var(--bw-text-color)",
11783
- fontWeight: 500,
11784
- fontFamily: "var(--bw-font-family)",
11785
- }, children: [formatCurrency(eventDetails.price), " ", t$1("common.perPerson")] })] })] })] }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.contactInfo") }), jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "16px" }, children: [jsxs("div", { style: {
11786
- display: "grid",
11787
- gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
11788
- gap: "16px",
11789
- }, children: [jsxs("div", { children: [jsx("label", { htmlFor: "customerName", style: labelStyles$1, children: t$1("booking.name") }), jsx("input", { id: "customerName", ...form.register("customerName"), type: "text", style: inputStyles$1, placeholder: t$1("booking.namePlaceholder") }), customerNameError && (jsx("p", { style: errorTextStyles$1, children: customerNameError.message }))] }), jsxs("div", { children: [jsx("label", { htmlFor: "customerEmail", style: labelStyles$1, children: t$1("booking.email") }), jsx("input", { id: "customerEmail", ...form.register("customerEmail"), type: "email", style: inputStyles$1, placeholder: t$1("booking.emailPlaceholder") }), customerEmailError && (jsx("p", { style: errorTextStyles$1, children: customerEmailError.message }))] })] }), jsxs("div", { children: [jsx("label", { htmlFor: "customerPhone", style: labelStyles$1, children: t$1("booking.phone") }), jsx("input", { id: "customerPhone", ...form.register("customerPhone"), type: "tel", style: inputStyles$1, placeholder: t$1("booking.phonePlaceholder") })] }), jsxs("div", { style: { marginTop: "10px", border: "1px solid var(--bw-border-color)", padding: "16px", borderRadius: "var(--bw-border-radius)" }, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("input", { id: "acceptTerms", ...form.register("acceptTerms"), type: "checkbox", style: formStyles.checkbox }), jsxs("label", { htmlFor: "acceptTerms", style: {
11986
+ marginBottom: "16px",
11987
+ }, children: jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: 0 }, children: t$1("booking.participants") }) }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [watchedParticipants.map((_, index) => (jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [participantFieldsConfig.name.enabled && (jsxs("div", { style: { flex: 1 }, children: [jsx("label", { htmlFor: `participant-name-${index}`, style: labelStyles$1, children: t$1("booking.participantName") }), 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 && (jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.name?.message }))] })), participantFieldsConfig.age.enabled && (jsxs("div", { style: { width: "80px" }, children: [jsx("label", { htmlFor: `participant-age-${index}`, style: labelStyles$1, children: t$1("booking.participantAge") }), jsx("input", { id: `participant-age-${index}`, ...form.register(`participants.${index}.age`, {
11988
+ setValueAs: (value) => {
11989
+ if (value === "" || value === null || value === undefined) {
11990
+ return undefined;
11991
+ }
11992
+ const num = Number(value);
11993
+ return Number.isNaN(num) ? undefined : num;
11994
+ },
11995
+ }), type: "number", min: "0", max: "120", style: inputStyles$1, placeholder: "25" })] })), watchedParticipants.length > 1 && (jsxs("div", { children: [jsx("label", { style: { ...labelStyles$1, visibility: "hidden" }, children: "\u00A0" }), jsx("button", { type: "button", onClick: () => removeParticipant(index), style: {
11996
+ color: "var(--bw-error-color)",
11997
+ backgroundColor: "var(--bw-surface-color)",
11998
+ border: "1px solid var(--bw-border-color)",
11999
+ borderRadius: "50%",
12000
+ width: "36px",
12001
+ height: "36px",
12002
+ display: "flex",
12003
+ alignItems: "center",
12004
+ justifyContent: "center",
12005
+ cursor: "pointer",
12006
+ transition: "all 0.2s ease",
12007
+ fontSize: "24px",
12008
+ fontWeight: 700,
12009
+ fontFamily: "var(--bw-font-family)",
12010
+ padding: 0,
12011
+ }, children: "\u00D7" })] }))] }), participantFieldsConfig.level.enabled && (jsxs("div", { style: { minWidth: "140px" }, children: [jsx("label", { htmlFor: `participant-level-${index}`, style: labelStyles$1, children: t$1("booking.participantLevel") }), jsxs("select", { id: `participant-level-${index}`, ...form.register(`participants.${index}.level`), style: inputStyles$1, children: [jsx("option", { value: "", children: t$1("booking.participantLevelPlaceholder") }), participantLevelOptions.map((level) => (jsx("option", { value: level, children: t$1(`level.${level}`) }, level)))] }), form.formState.errors.participants?.[index]?.level && (jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.level?.message }))] })), upsells.length > 0 && (jsx("div", { style: participantUpsellStyles.container, children: upsells.map((upsell) => {
12012
+ const isSelected = (participantUpsells[index] || []).includes(upsell.id);
12013
+ return (jsxs("label", { htmlFor: `upsell-${index}-${upsell.id}`, style: isSelected ? participantUpsellStyles.labelSelected : participantUpsellStyles.label, children: [jsx("input", { id: `upsell-${index}-${upsell.id}`, type: "checkbox", style: participantUpsellStyles.checkbox, checked: isSelected, onChange: () => toggleParticipantUpsell(index, upsell.id) }), jsx("span", { style: { fontWeight: 500 }, children: upsell.name }), jsxs("span", { style: { fontSize: "12px", opacity: 0.8 }, children: ["(+", formatCurrency(upsell.price), ")"] })] }, upsell.id));
12014
+ }) }))] }, index))), watchedParticipants.length < eventDetails.availableSpots ? (jsx("div", { style: {
12015
+ display: "flex",
12016
+ flexDirection: "column",
12017
+ alignItems: "center",
12018
+ marginTop: "12px",
12019
+ }, children: jsx("button", { type: "button", onClick: addParticipant, style: {
12020
+ color: "#ffffff",
12021
+ fontSize: "14px",
12022
+ fontWeight: 600,
12023
+ padding: "8px 16px",
12024
+ borderRadius: "var(--bw-border-radius)",
12025
+ backgroundColor: "var(--bw-highlight-color)",
12026
+ border: "1px solid var(--bw-highlight-color)",
12027
+ cursor: "pointer",
12028
+ transition: "all 0.2s ease",
12029
+ marginBottom: "4px",
12030
+ fontFamily: "var(--bw-font-family)",
12031
+ boxShadow: "0 2px 8px 0 var(--bw-highlight-color)",
12032
+ }, children: t$1("booking.addParticipant", { number: watchedParticipants.length + 1 }) }) })) : (jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.maxSpotsReached", { count: eventDetails.availableSpots }) }))] })] }), jsx(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), jsxs("div", { style: cardStyles$1, children: [jsx("label", { htmlFor: "booking-comment", style: labelStyles$1, children: t$1("booking.comment") }), jsx("textarea", { id: "booking-comment", ...form.register("comment"), placeholder: t$1("booking.commentPlaceholder"), rows: 3, style: {
12033
+ ...inputStyles$1,
12034
+ resize: "vertical",
12035
+ minHeight: "80px",
12036
+ } })] })] })] })), checkoutStep === "payment" && (jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: "16px" }, children: t$1("summary.title") }), jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "12px" }, children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.price") }), jsxs("div", { style: {
12037
+ color: "var(--bw-text-color)",
12038
+ fontWeight: 500,
12039
+ fontFamily: "var(--bw-font-family)",
12040
+ }, children: [jsxs("span", { style: { fontWeight: 200 }, children: [watchedParticipants.length > 1 ? watchedParticipants.length : 1, " x "] }), " ", formatCurrency(eventDetails.price)] })] }), upsellsTotal > 0 && (jsxs("div", { style: { marginTop: "8px", paddingTop: "8px", borderTop: "1px dashed var(--bw-border-color)" }, children: [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) => {
12041
+ // Count how many participants have this upsell selected
12042
+ const countWithUpsell = watchedParticipants.filter((_, idx) => (participantUpsells[idx] || []).includes(upsell.id)).length;
12043
+ if (countWithUpsell === 0)
12044
+ return null;
12045
+ const upsellLineTotal = upsell.price * countWithUpsell;
12046
+ return (jsx("div", { style: { display: "flex", flexDirection: "column", gap: "2px", fontSize: "13px" }, children: jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxs("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+ ", upsell.name, " (", countWithUpsell, "\u00D7)"] }), jsx("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(upsellLineTotal) })] }) }, upsell.id));
12047
+ })] })), appliedVouchers.length > 0 && (jsxs(Fragment, { children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.subtotal") }), jsx("span", { style: {
12048
+ fontFamily: "var(--bw-font-family)",
12049
+ color: totalDiscount > 0 ? "var(--bw-text-muted)" : "var(--bw-text-muted)",
12050
+ textDecoration: totalDiscount > 0 ? "line-through" : "none",
12051
+ }, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: {
12052
+ color: "var(--bw-success-color)",
12053
+ fontFamily: "var(--bw-font-family)",
12054
+ fontSize: "14px",
12055
+ }, children: t$1("summary.discount", { code: appliedDiscountCode.code }) }), jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: {
12056
+ color: "var(--bw-success-color)",
12057
+ fontFamily: "var(--bw-font-family)",
11790
12058
  fontSize: "14px",
12059
+ }, children: t$1("summary.giftCard", { code: giftCard.code }) }), jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), jsxs("div", { style: {
12060
+ borderTop: "1px solid var(--bw-border-color)",
12061
+ paddingTop: "12px",
12062
+ }, children: [hasDepositChoice && (jsxs("div", { style: {
12063
+ display: "flex",
12064
+ justifyContent: "space-between",
12065
+ alignItems: "center",
12066
+ fontSize: "14px",
12067
+ marginBottom: "12px",
12068
+ }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.totalAmount") }), jsx("span", { style: {
11791
12069
  color: "var(--bw-text-muted)",
11792
12070
  fontFamily: "var(--bw-font-family)",
11793
- maxWidth: "calc(100% - 32px)",
11794
- overflowWrap: "break-word",
12071
+ fontWeight: 500,
12072
+ }, children: formatCurrency(totalAmount) })] })), hasDepositChoice && widgetPaymentMode === "all" && (jsxs("div", { style: {
12073
+ display: "flex",
12074
+ gap: "8px",
12075
+ marginBottom: "16px",
12076
+ }, children: [jsxs("button", { type: "button", onClick: () => setPaymentOption("deposit"), style: {
12077
+ flex: 1,
12078
+ padding: "12px",
12079
+ borderRadius: "var(--bw-border-radius)",
12080
+ border: paymentOption === "deposit"
12081
+ ? "2px solid var(--bw-highlight-color)"
12082
+ : "1px solid var(--bw-border-color)",
12083
+ backgroundColor: paymentOption === "deposit"
12084
+ ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
12085
+ : "var(--bw-surface-color)",
11795
12086
  cursor: "pointer",
11796
- }, children: [t$1("booking.acceptTerms"), " ", 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 && (jsx("p", { style: { ...errorTextStyles$1, marginTop: "8px" }, children: form.formState.errors.acceptTerms.message }))] })] })] }), jsxs("div", { style: cardStyles$1, children: [jsx("div", { style: {
11797
- display: "flex",
11798
- justifyContent: "space-between",
11799
- alignItems: "center",
11800
- marginBottom: "16px",
11801
- }, children: jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: 0 }, children: t$1("booking.participants") }) }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [watchedParticipants.map((_, index) => (jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [participantFieldsConfig.name.enabled && (jsxs("div", { style: { flex: 1 }, children: [jsx("label", { htmlFor: `participant-name-${index}`, style: labelStyles$1, children: t$1("booking.participantName") }), 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 && (jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.name?.message }))] })), participantFieldsConfig.age.enabled && (jsxs("div", { style: { width: "80px" }, children: [jsx("label", { htmlFor: `participant-age-${index}`, style: labelStyles$1, children: t$1("booking.participantAge") }), jsx("input", { id: `participant-age-${index}`, ...form.register(`participants.${index}.age`, {
11802
- setValueAs: (value) => {
11803
- if (value === "" || value === null || value === undefined) {
11804
- return undefined;
11805
- }
11806
- const num = Number(value);
11807
- return Number.isNaN(num) ? undefined : num;
11808
- },
11809
- }), type: "number", min: "0", max: "120", style: inputStyles$1, placeholder: "25" })] })), watchedParticipants.length > 1 && (jsxs("div", { children: [jsx("label", { style: { ...labelStyles$1, visibility: "hidden" }, children: "\u00A0" }), jsx("button", { type: "button", onClick: () => removeParticipant(index), style: {
11810
- color: "var(--bw-error-color)",
11811
- backgroundColor: "var(--bw-surface-color)",
11812
- border: "1px solid var(--bw-border-color)",
11813
- borderRadius: "50%",
11814
- width: "36px",
11815
- height: "36px",
11816
- display: "flex",
11817
- alignItems: "center",
11818
- justifyContent: "center",
11819
- cursor: "pointer",
11820
- transition: "all 0.2s ease",
11821
- fontSize: "24px",
12087
+ fontFamily: "var(--bw-font-family)",
12088
+ transition: "all 0.2s ease",
12089
+ }, children: [jsx("div", { style: {
12090
+ fontSize: "13px",
12091
+ color: "var(--bw-text-muted)",
12092
+ marginBottom: "4px",
12093
+ }, children: t$1("summary.deposit") }), jsx("div", { style: {
12094
+ fontSize: "18px",
11822
12095
  fontWeight: 700,
11823
- fontFamily: "var(--bw-font-family)",
11824
- padding: 0,
11825
- }, children: "\u00D7" })] }))] }), participantFieldsConfig.level.enabled && (jsxs("div", { style: { minWidth: "140px" }, children: [jsx("label", { htmlFor: `participant-level-${index}`, style: labelStyles$1, children: t$1("booking.participantLevel") }), jsxs("select", { id: `participant-level-${index}`, ...form.register(`participants.${index}.level`), style: inputStyles$1, children: [jsx("option", { value: "", children: t$1("booking.participantLevelPlaceholder") }), participantLevelOptions.map((level) => (jsx("option", { value: level, children: t$1(`level.${level}`) }, level)))] }), form.formState.errors.participants?.[index]?.level && (jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.level?.message }))] })), upsells.length > 0 && (jsx("div", { style: participantUpsellStyles.container, children: upsells.map((upsell) => {
11826
- const isSelected = (participantUpsells[index] || []).includes(upsell.id);
11827
- return (jsxs("label", { htmlFor: `upsell-${index}-${upsell.id}`, style: isSelected ? participantUpsellStyles.labelSelected : participantUpsellStyles.label, children: [jsx("input", { id: `upsell-${index}-${upsell.id}`, type: "checkbox", style: participantUpsellStyles.checkbox, checked: isSelected, onChange: () => toggleParticipantUpsell(index, upsell.id) }), jsx("span", { style: { fontWeight: 500 }, children: upsell.name }), jsxs("span", { style: { fontSize: "12px", opacity: 0.8 }, children: ["(+", formatCurrency(upsell.price), ")"] })] }, upsell.id));
11828
- }) }))] }, index))), watchedParticipants.length < eventDetails.availableSpots ? (jsx("div", { style: {
11829
- display: "flex",
11830
- flexDirection: "column",
11831
- alignItems: "center",
11832
- marginTop: "12px",
11833
- }, children: jsx("button", { type: "button", onClick: addParticipant, style: {
11834
- color: "#ffffff",
11835
- fontSize: "14px",
11836
- fontWeight: 600,
11837
- padding: "8px 16px",
11838
- borderRadius: "var(--bw-border-radius)",
11839
- backgroundColor: "var(--bw-highlight-color)",
11840
- border: "1px solid var(--bw-highlight-color)",
11841
- cursor: "pointer",
11842
- transition: "all 0.2s ease",
11843
- marginBottom: "4px",
11844
- fontFamily: "var(--bw-font-family)",
11845
- boxShadow: "0 2px 8px 0 var(--bw-highlight-color)",
11846
- }, children: t$1("booking.addParticipant", { number: watchedParticipants.length + 1 }) }) })) : (jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.maxSpotsReached", { count: eventDetails.availableSpots }) }))] })] }), jsx(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), jsxs("div", { style: cardStyles$1, children: [jsx("label", { htmlFor: "booking-comment", style: labelStyles$1, children: t$1("booking.comment") }), jsx("textarea", { id: "booking-comment", ...form.register("comment"), placeholder: t$1("booking.commentPlaceholder"), rows: 3, style: {
11847
- ...inputStyles$1,
11848
- resize: "vertical",
11849
- minHeight: "80px",
11850
- } })] }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: "16px" }, children: t$1("summary.title") }), jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "12px" }, children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.price") }), jsxs("div", { style: {
11851
- color: "var(--bw-text-color)",
11852
- fontWeight: 500,
12096
+ color: paymentOption === "deposit"
12097
+ ? "var(--bw-highlight-color)"
12098
+ : "var(--bw-text-color)",
12099
+ }, children: formatCurrency(depositAmount) })] }), jsxs("button", { type: "button", onClick: () => setPaymentOption("full"), style: {
12100
+ flex: 1,
12101
+ padding: "12px",
12102
+ borderRadius: "var(--bw-border-radius)",
12103
+ border: paymentOption === "full"
12104
+ ? "2px solid var(--bw-highlight-color)"
12105
+ : "1px solid var(--bw-border-color)",
12106
+ backgroundColor: paymentOption === "full"
12107
+ ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
12108
+ : "var(--bw-surface-color)",
12109
+ cursor: "pointer",
11853
12110
  fontFamily: "var(--bw-font-family)",
11854
- }, children: [jsxs("span", { style: { fontWeight: 200 }, children: [watchedParticipants.length > 1 ? watchedParticipants.length : 1, " x "] }), " ", formatCurrency(eventDetails.price)] })] }), upsellsTotal > 0 && (jsxs("div", { style: { marginTop: "8px", paddingTop: "8px", borderTop: "1px dashed var(--bw-border-color)" }, children: [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) => {
11855
- // Count how many participants have this upsell selected
11856
- const countWithUpsell = watchedParticipants.filter((_, idx) => (participantUpsells[idx] || []).includes(upsell.id)).length;
11857
- if (countWithUpsell === 0)
11858
- return null;
11859
- const upsellLineTotal = upsell.price * countWithUpsell;
11860
- return (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", fontSize: "13px" }, children: [jsxs("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+ ", upsell.name, " (", countWithUpsell, "\u00D7)"] }), jsx("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(upsellLineTotal) })] }, upsell.id));
11861
- })] })), appliedVouchers.length > 0 && (jsxs(Fragment, { children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.subtotal") }), jsx("span", { style: {
11862
- fontFamily: "var(--bw-font-family)",
11863
- color: totalDiscount > 0 ? "var(--bw-text-muted)" : "var(--bw-text-muted)",
11864
- textDecoration: totalDiscount > 0 ? "line-through" : "none",
11865
- }, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: {
11866
- color: "var(--bw-success-color)",
11867
- fontFamily: "var(--bw-font-family)",
11868
- fontSize: "14px",
11869
- }, children: t$1("summary.discount", { code: appliedDiscountCode.code }) }), jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsx("span", { style: {
11870
- color: "var(--bw-success-color)",
11871
- fontFamily: "var(--bw-font-family)",
11872
- fontSize: "14px",
11873
- }, children: t$1("summary.giftCard", { code: giftCard.code }) }), jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), jsxs("div", { style: {
11874
- borderTop: "1px solid var(--bw-border-color)",
11875
- paddingTop: "12px",
11876
- }, children: [hasDepositOption && (jsxs("div", { style: {
11877
- display: "flex",
11878
- gap: "8px",
11879
- marginBottom: "16px",
11880
- }, children: [jsxs("button", { type: "button", onClick: () => setPaymentOption("deposit"), style: {
11881
- flex: 1,
11882
- padding: "12px",
11883
- borderRadius: "var(--bw-border-radius)",
11884
- border: paymentOption === "deposit"
11885
- ? "2px solid var(--bw-highlight-color)"
11886
- : "1px solid var(--bw-border-color)",
11887
- backgroundColor: paymentOption === "deposit"
11888
- ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
11889
- : "var(--bw-surface-color)",
11890
- cursor: "pointer",
11891
- fontFamily: "var(--bw-font-family)",
11892
- transition: "all 0.2s ease",
11893
- }, children: [jsx("div", { style: {
11894
- fontSize: "13px",
11895
- color: "var(--bw-text-muted)",
11896
- marginBottom: "4px",
11897
- }, children: t$1("summary.deposit") }), jsx("div", { style: {
11898
- fontSize: "18px",
11899
- fontWeight: 700,
11900
- color: paymentOption === "deposit"
11901
- ? "var(--bw-highlight-color)"
11902
- : "var(--bw-text-color)",
11903
- }, children: formatCurrency(depositAmount) })] }), jsxs("button", { type: "button", onClick: () => setPaymentOption("full"), style: {
11904
- flex: 1,
11905
- padding: "12px",
11906
- borderRadius: "var(--bw-border-radius)",
11907
- border: paymentOption === "full"
11908
- ? "2px solid var(--bw-highlight-color)"
11909
- : "1px solid var(--bw-border-color)",
11910
- backgroundColor: paymentOption === "full"
11911
- ? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
11912
- : "var(--bw-surface-color)",
11913
- cursor: "pointer",
11914
- fontFamily: "var(--bw-font-family)",
11915
- transition: "all 0.2s ease",
11916
- }, children: [jsx("div", { style: {
11917
- fontSize: "13px",
11918
- color: "var(--bw-text-muted)",
11919
- marginBottom: "4px",
11920
- }, children: t$1("summary.payFull") }), jsx("div", { style: {
11921
- fontSize: "18px",
11922
- fontWeight: 700,
11923
- color: paymentOption === "full"
11924
- ? "var(--bw-highlight-color)"
11925
- : "var(--bw-text-color)",
11926
- }, children: formatCurrency(totalAmount) })] })] })), hasDepositOption && paymentOption === "deposit" && (jsxs("div", { style: {
11927
- display: "flex",
11928
- justifyContent: "space-between",
11929
- alignItems: "center",
11930
- fontSize: "14px",
11931
- marginBottom: "8px",
11932
- }, children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.totalAmount") }), jsx("span", { style: {
12111
+ transition: "all 0.2s ease",
12112
+ }, children: [jsx("div", { style: {
12113
+ fontSize: "13px",
11933
12114
  color: "var(--bw-text-muted)",
11934
- fontFamily: "var(--bw-font-family)",
11935
- fontWeight: 500,
11936
- }, children: formatCurrency(totalAmount) })] })), jsxs("div", { style: {
11937
- display: "flex",
11938
- justifyContent: "space-between",
11939
- alignItems: "center",
11940
- fontSize: "18px",
11941
- fontWeight: 600,
11942
- }, children: [jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: hasDepositOption && paymentOption === "deposit"
11943
- ? t$1("summary.payToday")
11944
- : t$1("summary.totalAmount") }), jsx("span", { style: {
11945
- color: "var(--bw-highlight-color)",
11946
- fontFamily: "var(--bw-font-family)",
12115
+ marginBottom: "4px",
12116
+ }, children: t$1("summary.payFull") }), jsx("div", { style: {
12117
+ fontSize: "18px",
11947
12118
  fontWeight: 700,
11948
- }, children: formatCurrency(paymentAmount) })] }), hasDepositOption && paymentOption === "deposit" && (jsx("div", { style: {
11949
- fontSize: "12px",
11950
- color: "var(--bw-text-muted)",
12119
+ color: paymentOption === "full"
12120
+ ? "var(--bw-highlight-color)"
12121
+ : "var(--bw-text-color)",
12122
+ }, children: formatCurrency(totalAmount) })] })] })), jsxs("div", { style: {
12123
+ display: "flex",
12124
+ justifyContent: "space-between",
12125
+ alignItems: "center",
12126
+ fontSize: "18px",
12127
+ fontWeight: 600,
12128
+ }, children: [jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: hasDepositChoice && paymentOption === "deposit"
12129
+ ? t$1("summary.payToday")
12130
+ : t$1("summary.totalAmount") }), jsx("span", { style: {
12131
+ color: "var(--bw-highlight-color)",
11951
12132
  fontFamily: "var(--bw-font-family)",
11952
- marginTop: "8px",
11953
- textAlign: "right",
11954
- }, children: t$1("summary.remainingOnSite", { amount: formatCurrency(totalAmount - depositAmount) }) }))] })] })] }), jsx("div", { ref: paymentSectionRef, children: (stripePromise || systemConfig?.paymentProvider === "mollie") &&
11955
- (() => {
11956
- if (!isReadyForPayment()) {
11957
- const participantsWithNames = watchedParticipants.filter((p) => p.name?.trim()).length;
11958
- const totalParticipantRows = watchedParticipants.length;
11959
- const participantsWithoutNames = totalParticipantRows - participantsWithNames;
11960
- const missing = [];
11961
- if (participantFieldsConfig.name.required) {
11962
- if (participantsWithNames === 0) {
11963
- missing.push(t$1("payment.needParticipant"));
11964
- }
11965
- else if (participantsWithoutNames > 0) {
11966
- missing.push(t$1("payment.needAllNames", { count: totalParticipantRows }));
11967
- }
11968
- }
11969
- if (participantsWithNames > (eventDetails?.availableSpots || 0)) {
11970
- missing.push(t$1("payment.reduceParticipants", { count: eventDetails?.availableSpots || 0 }));
11971
- }
11972
- if (!watchedCustomerName || watchedCustomerName.trim().length < 2 || customerNameError) {
11973
- missing.push(t$1("payment.needValidName"));
11974
- }
11975
- if (!watchedCustomerEmail || watchedCustomerEmail.trim().length === 0 || customerEmailError) {
11976
- missing.push(t$1("payment.needValidEmail"));
11977
- }
11978
- if (!watchedAcceptTerms) {
11979
- missing.push(t$1("payment.needAcceptTerms"));
11980
- }
11981
- const message = missing.length > 0
11982
- ? t$1("payment.missingFields", { fields: missing.join(", ") })
11983
- : t$1("payment.fillRequired");
11984
- return (jsx("div", { style: {
11985
- ...cardStyles$1,
11986
- border: "1px solid var(--bw-warning-color)",
11987
- color: "var(--bw-warning-color)",
12133
+ fontWeight: 700,
12134
+ }, children: formatCurrency(paymentAmount) })] }), hasDepositChoice && paymentOption === "deposit" && (jsx("div", { style: {
12135
+ fontSize: "12px",
12136
+ color: "var(--bw-text-muted)",
11988
12137
  fontFamily: "var(--bw-font-family)",
11989
- textAlign: "center",
11990
- }, children: message }));
11991
- }
11992
- const discountCodeProp = appliedDiscountCode
11993
- ? {
11994
- id: appliedDiscountCode.id,
11995
- code: appliedDiscountCode.code,
11996
- description: appliedDiscountCode.description || undefined,
11997
- type: appliedDiscountCode.discountType || "percentage",
11998
- value: appliedDiscountCode.discountValue || 0,
11999
- discountAmount: appliedDiscountCode.discountAmount,
12000
- newTotal: appliedDiscountCode.newTotal,
12001
- }
12002
- : null;
12003
- if (systemConfig?.paymentProvider === "mollie") {
12004
- return (jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), 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 })] }));
12005
- }
12006
- return (jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), 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() })] }));
12007
- })() })] })] })] }) }));
12138
+ marginTop: "8px",
12139
+ textAlign: "right",
12140
+ }, children: t$1("summary.remainingOnSite", { amount: formatCurrency(totalAmount - depositAmount) }) }))] })] })] }), depositsOnlyBlocked && (jsx("div", { style: cardStyles$1, children: jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.depositNotConfigured") }) })), !hasPaymentProvider && !depositsOnlyBlocked && (jsx("div", { style: cardStyles$1, children: jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.paymentUnavailable") }) })), hasPaymentProvider && !depositsOnlyBlocked && (systemConfig?.paymentProvider === "mollie" ? (jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), 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 })] })) : (jsxs("div", { style: cardStyles$1, children: [jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), 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() })] })))] }))] }) }));
12008
12141
  }
12009
12142
 
12010
12143
  /**
@@ -12852,6 +12985,40 @@ const ImageCarousel = ({ images, eventName }) => {
12852
12985
  } }))] }));
12853
12986
  };
12854
12987
 
12988
+ function PaymentLogosStrip() {
12989
+ const logoHeight = 20;
12990
+ const logoCellStyle = {
12991
+ display: "inline-flex",
12992
+ alignItems: "center",
12993
+ justifyContent: "center",
12994
+ padding: "0px 6px",
12995
+ minHeight: "29px", // +7px from previous 22px
12996
+ borderRadius: "6px",
12997
+ };
12998
+ return (jsxs("div", { style: {
12999
+ padding: "6px 14px 10px 14px",
13000
+ backgroundColor: "color-mix(in srgb, var(--bw-text-color) 100%, var(--bw-surface-color) 18%)",
13001
+ display: "flex",
13002
+ alignItems: "center",
13003
+ justifyContent: "center",
13004
+ borderRadius: "var(--bw-border-radius)",
13005
+ gap: "4px",
13006
+ flexWrap: "wrap",
13007
+ width: "fit-content",
13008
+ margin: "20px auto",
13009
+ }, children: [jsxs("span", { style: logoCellStyle, children: [jsx("span", { style: { color: "#003087", fontSize: "14px", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "Pay" }), jsx("span", { style: { color: "#009cde", fontSize: "14px", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "Pal" })] }), jsx("span", { style: logoCellStyle, children: jsxs("svg", { width: "34", height: logoHeight, viewBox: "0 0 34 20", "aria-label": "Maestro", children: [jsx("circle", { cx: "13", cy: "10", r: "8", fill: "#eb001b" }), jsx("circle", { cx: "21", cy: "10", r: "8", fill: "#00a2e5", fillOpacity: "0.92" })] }) }), jsx("span", { style: logoCellStyle, children: jsx("span", { style: { color: "#1434CB", fontSize: "14px", fontStyle: "italic", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "VISA" }) }), jsx("span", { style: logoCellStyle, children: jsx("span", { style: { color: "purple", fontSize: "14px", fontWeight: 800, fontFamily: "Arial, sans-serif", lineHeight: 1 }, children: "Klarna" }) }), jsx("span", { style: logoCellStyle, children: jsxs("svg", { width: "74", height: logoHeight, viewBox: "0 0 74 20", "aria-label": "Amazon Pay", children: [jsx("text", { x: "0", y: "14", fontSize: "12", fill: "#111827", fontFamily: "Arial, sans-serif", children: "amazon" }), jsx("text", { x: "45", y: "14", fontSize: "12", fill: "#111827", fontFamily: "Arial, sans-serif", children: "pay" }), jsx("path", { d: "M5 15 C17 20, 35 20, 48 15", stroke: "#f59e0b", strokeWidth: "1.6", fill: "none", strokeLinecap: "round" })] }) }), jsxs("span", { style: logoCellStyle, children: [jsx("span", { style: {
13010
+ fontSize: "16px",
13011
+ fontWeight: 800,
13012
+ fontFamily: "Arial, sans-serif",
13013
+ lineHeight: 1,
13014
+ background: "conic-gradient(from 25deg, #4285F4 0 24%, #DB4437 24% 48%, #F4B400 48% 73%, #0F9D58 73% 100%)",
13015
+ WebkitBackgroundClip: "text",
13016
+ backgroundClip: "text",
13017
+ color: "transparent",
13018
+ WebkitTextFillColor: "transparent",
13019
+ }, children: "G" }), jsx("span", { style: { color: "#5f6368", fontSize: "14px", fontWeight: 600, fontFamily: "Arial, sans-serif", marginLeft: "3px", lineHeight: 1 }, children: "Pay" })] }), jsx("span", { style: logoCellStyle, children: jsxs("svg", { width: "60", height: logoHeight, viewBox: "0 0 60 20", "aria-label": "Apple Pay", children: [jsx("text", { x: "0", y: "14.5", fontSize: "14.5", fill: "#111827", fontFamily: "-apple-system, BlinkMacSystemFont, Arial, sans-serif", children: "\uF8FF" }), jsx("text", { x: "14", y: "14.5", fontSize: "14.5", fill: "#111827", fontFamily: "-apple-system, BlinkMacSystemFont, Arial, sans-serif", children: "Pay" })] }) })] }));
13020
+ }
13021
+
12855
13022
  function VoucherPurchaseCard({ config, minEventPrice, fallbackImages = [], onClick, standalone = false, }) {
12856
13023
  const t = useTranslations();
12857
13024
  const [activeSlideIndex, setActiveSlideIndex] = useState(0);
@@ -13971,7 +14138,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
13971
14138
  display: "flex",
13972
14139
  flexDirection: "column",
13973
14140
  justifyContent: "space-between",
13974
- height: "490px",
14141
+ height: "540px",
13975
14142
  }, children: [jsxs("div", { children: [jsx("h2", { className: "event-type-title", style: {
13976
14143
  fontSize: "clamp(1.1rem, 2.5vw, 24px)",
13977
14144
  fontWeight: 700,
@@ -14041,19 +14208,9 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14041
14208
  }) }) })) : (jsx("div", { className: "event-type-desc", style: {
14042
14209
  margin: "10px 0",
14043
14210
  height: "7.5em", // Same height as highlights
14044
- }, children: "\u00A0" })) })] }), jsxs("div", { children: [jsxs("div", { children: [jsx("div", { className: "event-type-price", style: {
14045
- fontWeight: 700,
14046
- color: "var(--bw-text-color)",
14047
- fontFamily: "var(--bw-font-family)",
14048
- textAlign: "right",
14049
- }, children: jsx("span", { children: formatDurationInfo(eventType.durationInfo, t) }) }), jsx("div", { className: "event-type-price", style: {
14050
- fontSize: "clamp(1.72rem, 4vw, 32px)",
14051
- fontWeight: 700,
14052
- color: "var(--bw-text-color)",
14053
- fontFamily: "var(--bw-font-family)",
14054
- textAlign: "right",
14055
- }, children: jsxs("span", { children: [t("common.from"), " ", formatCurrency(eventType.minPrice)] }) })] }), (() => {
14211
+ }, children: "\u00A0" })) })] }), jsxs("div", { children: [(() => {
14056
14212
  const preview = eventType.cardPreview ?? [];
14213
+ const hasMoreDates = eventType.availableInstancesCount > preview.length;
14057
14214
  return (jsxs("div", { style: {
14058
14215
  marginTop: "12px",
14059
14216
  borderTop: "1px solid var(--bw-border-color)",
@@ -14087,8 +14244,33 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14087
14244
  transition: "background 0.15s",
14088
14245
  boxSizing: "border-box",
14089
14246
  }, children: [jsxs("span", { style: { whiteSpace: "nowrap", display: "flex", alignItems: "center", gap: "3px" }, children: [item.isSpecial && (jsx("span", { style: { color: "var(--bw-highlight-color)", fontSize: "11px", lineHeight: 1 }, children: "\u2605" })), formatWeekday(item.startTime, timezone, locale), " ", formatDate(item.startTime, timezone, locale)] }), jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", opacity: 0.75 }, children: item.name }), jsxs("span", { style: { display: "flex", alignItems: "center", gap: "4px", whiteSpace: "nowrap" }, children: [hasDiscount && (jsx("span", { style: { textDecoration: "line-through", opacity: 0.55, fontSize: "11px" }, children: formatCurrency(item.basePrice) })), jsx("span", { style: { fontWeight: 700, color: item.isSpecial ? "var(--bw-highlight-color)" : "var(--bw-text-color)" }, children: formatCurrency(item.price) })] }), item.specialDescription ? (jsx(InfoBadge, { text: item.specialDescription })) : (jsx("span", {}))] }, item.id));
14090
- }) })] }));
14091
- })(), jsxs("div", { style: {
14247
+ }) }), hasMoreDates && (jsx("button", { type: "button", onClick: (e) => {
14248
+ e.stopPropagation();
14249
+ onEventTypeSelect(eventType);
14250
+ }, style: {
14251
+ marginTop: "6px",
14252
+ padding: 0,
14253
+ border: "none",
14254
+ background: "none",
14255
+ color: "var(--bw-highlight-color)",
14256
+ fontFamily: "var(--bw-font-family)",
14257
+ fontSize: "13px",
14258
+ fontWeight: 600,
14259
+ cursor: "pointer",
14260
+ textDecoration: "underline",
14261
+ }, children: t("events.seeMoreDates") }))] }));
14262
+ })(), jsxs("div", { style: { marginBottom: "16px" }, children: [jsx("div", { className: "event-type-price", style: {
14263
+ fontWeight: 700,
14264
+ color: "var(--bw-text-color)",
14265
+ fontFamily: "var(--bw-font-family)",
14266
+ textAlign: "right",
14267
+ }, children: jsx("span", { children: formatDurationInfo(eventType.durationInfo, t) }) }), jsx("div", { className: "event-type-price", style: {
14268
+ fontSize: "clamp(1.72rem, 4vw, 32px)",
14269
+ fontWeight: 700,
14270
+ color: "var(--bw-text-color)",
14271
+ fontFamily: "var(--bw-font-family)",
14272
+ textAlign: "right",
14273
+ }, children: jsxs("span", { children: [t("common.from"), " ", formatCurrency(eventType.minPrice)] }) })] }), jsxs("div", { style: {
14092
14274
  display: "flex",
14093
14275
  justifyContent: "flex-end",
14094
14276
  alignItems: "center",
@@ -14146,7 +14328,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
14146
14328
  fontFamily: "var(--bw-font-family)",
14147
14329
  boxShadow: "var(--bw-shadow-md)",
14148
14330
  }, children: t("events.soldOut") }) }))] }, eventType.id));
14149
- }) }) })), jsx(EventTypeDetailsDialog, { isOpen: detailsDialogOpen, onClose: handleCloseDetails, eventType: selectedEventTypeForDetails, onEventTypeSelect: onEventTypeSelect })] }));
14331
+ }) }) })), jsx(PaymentLogosStrip, {}), jsx(EventTypeDetailsDialog, { isOpen: detailsDialogOpen, onClose: handleCloseDetails, eventType: selectedEventTypeForDetails, onEventTypeSelect: onEventTypeSelect })] }));
14150
14332
  }
14151
14333
 
14152
14334
  const getAllocationBadgeInfo = (availableSpots, maxParticipants, t) => {
@@ -14273,7 +14455,7 @@ const PriceDisplay = ({ price, yearPrices, t }) => {
14273
14455
  boxShadow: displayInfo ? "0 2px 4px rgba(0, 0, 0, 0.2)" : "none",
14274
14456
  }, children: formatCurrency(price) }));
14275
14457
  };
14276
- function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, }) {
14458
+ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, hasUpsellsStep = false, }) {
14277
14459
  const t = useTranslations();
14278
14460
  const { locale } = useLocale();
14279
14461
  const timezone = useTimezone();
@@ -14339,88 +14521,88 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
14339
14521
  const footerNav = (jsx("button", { type: "button", onClick: handleClose, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: t("common.back") }));
14340
14522
  // Show loading state first if we're loading event instances
14341
14523
  if (isLoadingEventInstances) {
14342
- return (jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsx("div", { style: { padding: "24px" }, children: jsx("div", { style: { display: "flex", flexDirection: "column", gap: "20px" }, children: Array.from({ length: 3 }).map((_, idx) => (jsxs("div", { className: "skeleton-shimmer", style: {
14343
- backgroundColor: "var(--bw-surface-color)",
14344
- border: "1px solid var(--bw-border-color)",
14345
- borderRadius: "var(--bw-border-radius)",
14346
- overflow: "hidden",
14347
- }, children: [jsxs("div", { style: {
14348
- display: "flex",
14349
- justifyContent: "space-between",
14350
- alignItems: "center",
14351
- padding: "16px 20px",
14352
- cursor: "pointer",
14353
- borderBottom: "1px solid var(--bw-border-color)",
14354
- }, children: [jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [jsx("div", { style: {
14355
- width: "80px",
14356
- height: "20px",
14357
- backgroundColor: "var(--bw-border-color)",
14358
- borderRadius: "var(--bw-border-radius-small)",
14359
- } }), jsx("div", { style: {
14360
- width: "16px",
14361
- height: "16px",
14362
- backgroundColor: "var(--bw-border-color)",
14363
- borderRadius: "var(--bw-border-radius-small)",
14364
- } })] }), jsx("div", { style: {
14365
- width: "70px",
14366
- height: "16px",
14367
- backgroundColor: "var(--bw-highlight-color)",
14368
- opacity: 0.3,
14369
- borderRadius: "var(--bw-border-radius-small)",
14370
- } })] }), jsx("div", { style: {
14371
- display: "flex",
14372
- flexDirection: "column",
14373
- gap: "12px",
14374
- paddingTop: "12px",
14375
- padding: "12px 20px 20px 20px",
14376
- }, children: Array.from({ length: 2 }).map((_, eventIdx) => (jsxs("div", { style: {
14377
- position: "relative",
14378
- border: "1px solid var(--bw-border-color)",
14379
- backgroundColor: "var(--bw-surface-color)",
14380
- borderRadius: "var(--bw-border-radius)",
14524
+ return (jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsxs("div", { style: { padding: "24px" }, children: [jsx(FlowProgress, { currentStep: "date", hasUpsellsStep: hasUpsellsStep }), jsx("div", { style: { display: "flex", flexDirection: "column", gap: "20px" }, children: Array.from({ length: 3 }).map((_, idx) => (jsxs("div", { className: "skeleton-shimmer", style: {
14525
+ backgroundColor: "var(--bw-surface-color)",
14526
+ border: "1px solid var(--bw-border-color)",
14527
+ borderRadius: "var(--bw-border-radius)",
14528
+ overflow: "hidden",
14529
+ }, children: [jsxs("div", { style: {
14530
+ display: "flex",
14531
+ justifyContent: "space-between",
14532
+ alignItems: "center",
14381
14533
  padding: "16px 20px",
14382
- fontFamily: "var(--bw-font-family)",
14383
- }, children: [jsxs("div", { style: {
14384
- display: "flex",
14385
- justifyContent: "space-between",
14386
- width: "100%",
14387
- alignItems: "flex-start",
14388
- gap: "12px",
14389
- marginBottom: "4px",
14390
- }, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("div", { style: {
14391
- width: "40px",
14392
- height: "40px",
14393
- backgroundColor: "var(--bw-background-color)",
14394
- border: "1px solid var(--bw-border-color)",
14395
- borderTopWidth: "4px",
14396
- borderRadius: "var(--bw-border-radius-small)",
14397
- } }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [jsx("div", { style: {
14398
- width: "80px",
14399
- height: "16px",
14400
- backgroundColor: "var(--bw-border-color)",
14401
- borderRadius: "var(--bw-border-radius)",
14402
- } }), jsx("div", { style: {
14403
- width: "60px",
14404
- height: "14px",
14405
- backgroundColor: "var(--bw-border-color)",
14406
- borderRadius: "var(--bw-border-radius)",
14407
- } })] })] }), jsx("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end" }, children: jsx("div", { style: {
14408
- width: "70px",
14409
- height: "20px",
14410
- backgroundColor: "var(--bw-highlight-color)",
14411
- opacity: 0.3,
14412
- borderRadius: "var(--bw-border-radius)",
14413
- } }) })] }), jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [jsx("div", { style: {
14414
- width: "120px",
14415
- height: "16px",
14534
+ cursor: "pointer",
14535
+ borderBottom: "1px solid var(--bw-border-color)",
14536
+ }, children: [jsxs("div", { style: { display: "flex", alignItems: "center", gap: "12px" }, children: [jsx("div", { style: {
14537
+ width: "80px",
14538
+ height: "20px",
14416
14539
  backgroundColor: "var(--bw-border-color)",
14417
- borderRadius: "var(--bw-border-radius)",
14540
+ borderRadius: "var(--bw-border-radius-small)",
14418
14541
  } }), jsx("div", { style: {
14419
- width: "50px",
14420
- height: "20px",
14542
+ width: "16px",
14543
+ height: "16px",
14421
14544
  backgroundColor: "var(--bw-border-color)",
14422
- borderRadius: "16px",
14423
- } })] })] }, eventIdx))) })] }, idx))) }) }) }));
14545
+ borderRadius: "var(--bw-border-radius-small)",
14546
+ } })] }), jsx("div", { style: {
14547
+ width: "70px",
14548
+ height: "16px",
14549
+ backgroundColor: "var(--bw-highlight-color)",
14550
+ opacity: 0.3,
14551
+ borderRadius: "var(--bw-border-radius-small)",
14552
+ } })] }), jsx("div", { style: {
14553
+ display: "flex",
14554
+ flexDirection: "column",
14555
+ gap: "12px",
14556
+ paddingTop: "12px",
14557
+ padding: "12px 20px 20px 20px",
14558
+ }, children: Array.from({ length: 2 }).map((_, eventIdx) => (jsxs("div", { style: {
14559
+ position: "relative",
14560
+ border: "1px solid var(--bw-border-color)",
14561
+ backgroundColor: "var(--bw-surface-color)",
14562
+ borderRadius: "var(--bw-border-radius)",
14563
+ padding: "16px 20px",
14564
+ fontFamily: "var(--bw-font-family)",
14565
+ }, children: [jsxs("div", { style: {
14566
+ display: "flex",
14567
+ justifyContent: "space-between",
14568
+ width: "100%",
14569
+ alignItems: "flex-start",
14570
+ gap: "12px",
14571
+ marginBottom: "4px",
14572
+ }, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("div", { style: {
14573
+ width: "40px",
14574
+ height: "40px",
14575
+ backgroundColor: "var(--bw-background-color)",
14576
+ border: "1px solid var(--bw-border-color)",
14577
+ borderTopWidth: "4px",
14578
+ borderRadius: "var(--bw-border-radius-small)",
14579
+ } }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "4px" }, children: [jsx("div", { style: {
14580
+ width: "80px",
14581
+ height: "16px",
14582
+ backgroundColor: "var(--bw-border-color)",
14583
+ borderRadius: "var(--bw-border-radius)",
14584
+ } }), jsx("div", { style: {
14585
+ width: "60px",
14586
+ height: "14px",
14587
+ backgroundColor: "var(--bw-border-color)",
14588
+ borderRadius: "var(--bw-border-radius)",
14589
+ } })] })] }), jsx("div", { style: { display: "flex", flexDirection: "column", alignItems: "flex-end" }, children: jsx("div", { style: {
14590
+ width: "70px",
14591
+ height: "20px",
14592
+ backgroundColor: "var(--bw-highlight-color)",
14593
+ opacity: 0.3,
14594
+ borderRadius: "var(--bw-border-radius)",
14595
+ } }) })] }), jsxs("div", { style: { display: "flex", alignItems: "center", gap: "8px", marginBottom: "4px" }, children: [jsx("div", { style: {
14596
+ width: "120px",
14597
+ height: "16px",
14598
+ backgroundColor: "var(--bw-border-color)",
14599
+ borderRadius: "var(--bw-border-radius)",
14600
+ } }), jsx("div", { style: {
14601
+ width: "50px",
14602
+ height: "20px",
14603
+ backgroundColor: "var(--bw-border-color)",
14604
+ borderRadius: "16px",
14605
+ } })] })] }, eventIdx))) })] }, idx))) })] }) }));
14424
14606
  }
14425
14607
  // Show empty state only if not loading and no event instances
14426
14608
  if (eventInstances.length === 0) {
@@ -14439,116 +14621,116 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
14439
14621
  fontFamily: "var(--bw-font-family)",
14440
14622
  }, children: t("instances.noAvailable") }), jsx("p", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t("instances.noAvailableMessage") })] }) }) }));
14441
14623
  }
14442
- return (jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsx("div", { style: { padding: "20px 10px" }, children: jsx("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: monthYearGroups.map(({ key, label, events, minPrice, year }, idx) => {
14443
- const monthPriceDisplayInfo = getMonthPriceDisplayInfo(minPrice);
14444
- return (jsxs(Fragment$1, { children: [idx > 0 && monthYearGroups[idx - 1].year !== year && (jsx("div", { style: { height: "1px", backgroundColor: "var(--bw-border-color)", margin: "4px 0" } })), jsx(Accordion, { title: label, priceInfo: jsx("div", { style: {
14445
- fontSize: "16px",
14446
- fontWeight: 500,
14447
- marginLeft: "auto",
14448
- padding: "4px 8px",
14449
- borderRadius: "var(--bw-border-radius-small)",
14450
- backgroundColor: monthPriceDisplayInfo
14451
- ? monthPriceDisplayInfo.backgroundColor
14452
- : "#14532d",
14453
- color: monthPriceDisplayInfo
14454
- ? monthPriceDisplayInfo.textColor
14455
- : "#4ade80",
14456
- boxShadow: monthPriceDisplayInfo
14457
- ? "0 2px 4px rgba(0, 0, 0, 0.2)"
14458
- : undefined,
14459
- }, children: `${t("common.from")} ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", paddingTop: "12px" }, children: events.map((event) => {
14460
- const availableSpots = event.maxParticipants - event.participantCount;
14461
- const isFullyBooked = availableSpots === 0;
14462
- const startDate = new Date(event.startTime);
14463
- const isPastEvent = today.toISOString() >= startDate.toISOString();
14464
- const isDisabled = isFullyBooked || isPastEvent || !event.bookingOpen;
14465
- return (jsxs("div", { style: {
14466
- position: "relative",
14467
- border: "1px solid var(--bw-border-color)",
14468
- backgroundColor: "var(--bw-surface-color)",
14469
- borderRadius: "var(--bw-border-radius)",
14470
- padding: "16px 10px",
14471
- transition: "all 0.2s ease",
14472
- fontFamily: "var(--bw-font-family)",
14473
- opacity: isDisabled ? 0.3 : 1,
14474
- filter: isDisabled ? "grayscale(40%)" : "none",
14475
- cursor: isDisabled ? "not-allowed" : "pointer",
14476
- }, onClick: () => {
14477
- if (!isDisabled) {
14478
- handleEventInstanceSelect(event);
14479
- }
14480
- }, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsx("div", { style: {
14481
- position: "absolute",
14482
- inset: 0,
14483
- backgroundColor: "rgba(15, 23, 42, 0.8)",
14484
- borderRadius: "var(--bw-border-radius)",
14485
- display: "flex",
14486
- alignItems: "center",
14487
- justifyContent: "center",
14488
- }, children: jsx("div", { style: {
14489
- width: "32px",
14490
- height: "32px",
14491
- color: "var(--bw-highlight-color)",
14492
- opacity: 0.8,
14493
- fontSize: "32px",
14494
- }, children: spinner() }) })), jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants, t: t }), jsxs("div", { style: {
14495
- display: "flex",
14496
- justifyContent: "space-between",
14497
- width: "100%",
14498
- alignItems: "flex-start",
14499
- gap: "12px",
14500
- marginBottom: "4px",
14501
- }, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("div", { style: {
14502
- fontSize: "16px",
14503
- transition: "all 0.2s ease",
14504
- borderRadius: "var(--bw-border-radius-small)",
14505
- borderTop: "4px solid var(--bw-border-color)",
14506
- border: "1px solid var(--bw-border-color)",
14507
- width: "40px",
14508
- height: "40px",
14509
- display: "flex",
14510
- alignItems: "center",
14511
- justifyContent: "center",
14512
- fontWeight: 700,
14513
- color: "var(--bw-text-color)",
14514
- backgroundColor: "var(--bw-background-color)",
14515
- }, children: startDate.getDate() }), jsxs("div", { style: {
14516
- fontSize: "16px",
14517
- color: "var(--bw-text-color)",
14518
- display: "flex",
14519
- flexDirection: "column",
14520
- alignItems: "flex-start",
14521
- justifyContent: "flex-start",
14522
- lineHeight: 1.25,
14523
- }, children: [jsxs("div", { children: [jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.startTime, timezone, locale) }), formatWeekday(event.startTime, timezone, locale) !==
14524
- formatWeekday(event.endTime, timezone, locale) && (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.endTime, timezone, locale) })] }))] }), jsx("div", { children: formatWeekday(event.startTime, timezone, locale) ===
14525
- formatWeekday(event.endTime, timezone, locale) ? (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.startTime, timezone, locale) }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.endTime, timezone, locale) })] })) : (jsxs("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime, timezone, locale), " ", t("instances.oclock")] })) })] }), jsxs("span", { style: {
14526
- fontSize: "12px",
14527
- fontWeight: 400,
14528
- color: "var(--bw-text-muted)",
14529
- marginLeft: "6px",
14530
- backgroundColor: "rgba(0, 0, 0, 0.05)",
14531
- whiteSpace: "nowrap",
14532
- padding: "2px 6px",
14533
- borderRadius: "var(--bw-border-radius-small)",
14534
- }, children: [event.durationDays, " ", event.durationDays > 1 ? t("common.days") : t("common.day")] })] }), jsx("div", { style: {
14535
- textAlign: "right",
14536
- display: "flex",
14537
- flexDirection: "column",
14538
- alignItems: "flex-end",
14539
- }, children: jsx(PriceDisplay, { price: event.price, yearPrices: yearPrices, t: t }) })] }), event.name !== selectedEventType?.name && (jsx("h4", { style: {
14540
- fontSize: "16px",
14541
- fontWeight: 600,
14542
- color: "var(--bw-text-color)",
14543
- lineHeight: 1.25,
14544
- margin: "0 0 2px 0",
14545
- display: "flex",
14546
- alignItems: "center",
14547
- gap: "8px",
14548
- maxWidth: "230px",
14549
- }, children: event.name }))] }, event.id));
14550
- }) }) })] }, key));
14551
- }) }) }) }));
14624
+ return (jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: `${selectedEventType?.name}`, footer: footerNav, children: jsxs("div", { style: { padding: "20px 10px" }, children: [jsx(FlowProgress, { currentStep: "date", hasUpsellsStep: hasUpsellsStep }), jsx("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: monthYearGroups.map(({ key, label, events, minPrice, year }, idx) => {
14625
+ const monthPriceDisplayInfo = getMonthPriceDisplayInfo(minPrice);
14626
+ return (jsxs(Fragment$1, { children: [idx > 0 && monthYearGroups[idx - 1].year !== year && (jsx("div", { style: { height: "1px", backgroundColor: "var(--bw-border-color)", margin: "4px 0" } })), jsx(Accordion, { title: label, priceInfo: jsx("div", { style: {
14627
+ fontSize: "16px",
14628
+ fontWeight: 500,
14629
+ marginLeft: "auto",
14630
+ padding: "4px 8px",
14631
+ borderRadius: "var(--bw-border-radius-small)",
14632
+ backgroundColor: monthPriceDisplayInfo
14633
+ ? monthPriceDisplayInfo.backgroundColor
14634
+ : "#14532d",
14635
+ color: monthPriceDisplayInfo
14636
+ ? monthPriceDisplayInfo.textColor
14637
+ : "#4ade80",
14638
+ boxShadow: monthPriceDisplayInfo
14639
+ ? "0 2px 4px rgba(0, 0, 0, 0.2)"
14640
+ : undefined,
14641
+ }, children: `${t("common.from")} ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", paddingTop: "12px" }, children: events.map((event) => {
14642
+ const availableSpots = event.maxParticipants - event.participantCount;
14643
+ const isFullyBooked = availableSpots === 0;
14644
+ const startDate = new Date(event.startTime);
14645
+ const isPastEvent = today.toISOString() >= startDate.toISOString();
14646
+ const isDisabled = isFullyBooked || isPastEvent || !event.bookingOpen;
14647
+ return (jsxs("div", { style: {
14648
+ position: "relative",
14649
+ border: "1px solid var(--bw-border-color)",
14650
+ backgroundColor: "var(--bw-surface-color)",
14651
+ borderRadius: "var(--bw-border-radius)",
14652
+ padding: "16px 10px",
14653
+ transition: "all 0.2s ease",
14654
+ fontFamily: "var(--bw-font-family)",
14655
+ opacity: isDisabled ? 0.3 : 1,
14656
+ filter: isDisabled ? "grayscale(40%)" : "none",
14657
+ cursor: isDisabled ? "not-allowed" : "pointer",
14658
+ }, onClick: () => {
14659
+ if (!isDisabled) {
14660
+ handleEventInstanceSelect(event);
14661
+ }
14662
+ }, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsx("div", { style: {
14663
+ position: "absolute",
14664
+ inset: 0,
14665
+ backgroundColor: "rgba(15, 23, 42, 0.8)",
14666
+ borderRadius: "var(--bw-border-radius)",
14667
+ display: "flex",
14668
+ alignItems: "center",
14669
+ justifyContent: "center",
14670
+ }, children: jsx("div", { style: {
14671
+ width: "32px",
14672
+ height: "32px",
14673
+ color: "var(--bw-highlight-color)",
14674
+ opacity: 0.8,
14675
+ fontSize: "32px",
14676
+ }, children: spinner() }) })), jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants, t: t }), jsxs("div", { style: {
14677
+ display: "flex",
14678
+ justifyContent: "space-between",
14679
+ width: "100%",
14680
+ alignItems: "flex-start",
14681
+ gap: "12px",
14682
+ marginBottom: "4px",
14683
+ }, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("div", { style: {
14684
+ fontSize: "16px",
14685
+ transition: "all 0.2s ease",
14686
+ borderRadius: "var(--bw-border-radius-small)",
14687
+ borderTop: "4px solid var(--bw-border-color)",
14688
+ border: "1px solid var(--bw-border-color)",
14689
+ width: "40px",
14690
+ height: "40px",
14691
+ display: "flex",
14692
+ alignItems: "center",
14693
+ justifyContent: "center",
14694
+ fontWeight: 700,
14695
+ color: "var(--bw-text-color)",
14696
+ backgroundColor: "var(--bw-background-color)",
14697
+ }, children: startDate.getDate() }), jsxs("div", { style: {
14698
+ fontSize: "16px",
14699
+ color: "var(--bw-text-color)",
14700
+ display: "flex",
14701
+ flexDirection: "column",
14702
+ alignItems: "flex-start",
14703
+ justifyContent: "flex-start",
14704
+ lineHeight: 1.25,
14705
+ }, children: [jsxs("div", { children: [jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.startTime, timezone, locale) }), formatWeekday(event.startTime, timezone, locale) !==
14706
+ formatWeekday(event.endTime, timezone, locale) && (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.endTime, timezone, locale) })] }))] }), jsx("div", { children: formatWeekday(event.startTime, timezone, locale) ===
14707
+ formatWeekday(event.endTime, timezone, locale) ? (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.startTime, timezone, locale) }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.endTime, timezone, locale) })] })) : (jsxs("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime, timezone, locale), " ", t("instances.oclock")] })) })] }), jsxs("span", { style: {
14708
+ fontSize: "12px",
14709
+ fontWeight: 400,
14710
+ color: "var(--bw-text-muted)",
14711
+ marginLeft: "6px",
14712
+ backgroundColor: "rgba(0, 0, 0, 0.05)",
14713
+ whiteSpace: "nowrap",
14714
+ padding: "2px 6px",
14715
+ borderRadius: "var(--bw-border-radius-small)",
14716
+ }, children: [event.durationDays, " ", event.durationDays > 1 ? t("common.days") : t("common.day")] })] }), jsx("div", { style: {
14717
+ textAlign: "right",
14718
+ display: "flex",
14719
+ flexDirection: "column",
14720
+ alignItems: "flex-end",
14721
+ }, children: jsx(PriceDisplay, { price: event.price, yearPrices: yearPrices, t: t }) })] }), event.name !== selectedEventType?.name && (jsx("h4", { style: {
14722
+ fontSize: "16px",
14723
+ fontWeight: 600,
14724
+ color: "var(--bw-text-color)",
14725
+ lineHeight: 1.25,
14726
+ margin: "0 0 2px 0",
14727
+ display: "flex",
14728
+ alignItems: "center",
14729
+ gap: "8px",
14730
+ maxWidth: "230px",
14731
+ }, children: event.name }))] }, event.id));
14732
+ }) }) })] }, key));
14733
+ }) })] }) }));
14552
14734
  }
14553
14735
 
14554
14736
  function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText, showAllButton, isLoadingEventDetails = false, isLoadingShowAll = false, isLoading = false, }) {
@@ -15171,12 +15353,11 @@ function PromoDialog({ config, onClose, onCtaClick }) {
15171
15353
  return createPortal(dialogContent, portalContainer);
15172
15354
  }
15173
15355
 
15174
- // Upsell card styles
15175
15356
  const cardBaseStyles = {
15176
15357
  position: "relative",
15177
15358
  display: "flex",
15178
15359
  flexDirection: "column",
15179
- padding: "16px",
15360
+ padding: "12px",
15180
15361
  backgroundColor: "var(--bw-surface-color)",
15181
15362
  borderWidth: "2px",
15182
15363
  borderStyle: "solid",
@@ -15196,19 +15377,13 @@ const cardDisabledStyles = {
15196
15377
  opacity: 0.6,
15197
15378
  cursor: "not-allowed",
15198
15379
  };
15199
- const checkboxContainerStyles = {
15200
- position: "absolute",
15201
- bottom: "12px",
15202
- left: "12px",
15203
- zIndex: 1,
15204
- };
15205
15380
  const checkboxInnerStyles = {
15206
- width: "24px",
15207
- height: "24px",
15381
+ width: "48px",
15382
+ height: "48px",
15208
15383
  borderWidth: "2px",
15209
15384
  borderStyle: "solid",
15210
15385
  borderColor: "var(--bw-border-color)",
15211
- borderRadius: "6px",
15386
+ borderRadius: "12px",
15212
15387
  display: "flex",
15213
15388
  alignItems: "center",
15214
15389
  justifyContent: "center",
@@ -15220,13 +15395,13 @@ const checkboxSelectedStyles = {
15220
15395
  borderColor: "var(--bw-highlight-color)",
15221
15396
  backgroundColor: "var(--bw-highlight-color)",
15222
15397
  };
15223
- const imageContainerStyles = {
15224
- width: "100%",
15225
- height: "120px",
15226
- marginBottom: "12px",
15398
+ const previewImageContainerStyles = {
15399
+ width: "56px",
15400
+ height: "56px",
15227
15401
  borderRadius: "calc(var(--bw-border-radius) - 4px)",
15228
15402
  overflow: "hidden",
15229
15403
  backgroundColor: "var(--bw-background-color)",
15404
+ flexShrink: 0,
15230
15405
  };
15231
15406
  const imageStyles = {
15232
15407
  width: "100%",
@@ -15241,23 +15416,53 @@ const imagePlaceholderStyles = {
15241
15416
  justifyContent: "center",
15242
15417
  color: "var(--bw-text-muted)",
15243
15418
  };
15244
- const nameStyles = {
15419
+ const previewNameStyles = {
15245
15420
  fontSize: "16px",
15246
15421
  fontWeight: 600,
15247
15422
  color: "var(--bw-text-color)",
15248
- margin: "0 0 6px 0",
15249
- paddingRight: "36px",
15423
+ margin: 0,
15250
15424
  fontFamily: "var(--bw-font-family)",
15251
15425
  };
15426
+ const previewHeaderStyles = {
15427
+ display: "flex",
15428
+ alignItems: "center",
15429
+ gap: "10px",
15430
+ };
15431
+ const previewPriceStyles = {
15432
+ fontSize: "13px",
15433
+ color: "var(--bw-text-muted)",
15434
+ marginTop: "2px",
15435
+ fontFamily: "var(--bw-font-family)",
15436
+ };
15437
+ const headerRightStyles = {
15438
+ marginLeft: "auto",
15439
+ display: "flex",
15440
+ alignItems: "center",
15441
+ gap: "8px",
15442
+ };
15443
+ const chevronStyles = {
15444
+ fontSize: "12px",
15445
+ color: "var(--bw-text-muted)",
15446
+ transition: "transform 0.2s ease",
15447
+ };
15448
+ const expandedContentStyles = {
15449
+ marginTop: "12px",
15450
+ paddingTop: "12px",
15451
+ borderTop: "1px solid var(--bw-border-color)",
15452
+ };
15453
+ const expandedImageContainerStyles = {
15454
+ width: "100%",
15455
+ height: "180px",
15456
+ marginBottom: "12px",
15457
+ borderRadius: "calc(var(--bw-border-radius) - 4px)",
15458
+ overflow: "hidden",
15459
+ backgroundColor: "var(--bw-background-color)",
15460
+ };
15252
15461
  const descriptionStyles = {
15253
15462
  fontSize: "13px",
15254
15463
  color: "var(--bw-text-muted)",
15255
15464
  margin: "0 0 10px 0",
15256
15465
  lineHeight: 1.4,
15257
- display: "-webkit-box",
15258
- WebkitLineClamp: 5,
15259
- WebkitBoxOrient: "vertical",
15260
- overflow: "hidden",
15261
15466
  fontFamily: "var(--bw-font-family)",
15262
15467
  };
15263
15468
  const itemsContainerStyles = {
@@ -15339,6 +15544,8 @@ function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
15339
15544
  const { locale } = useLocale();
15340
15545
  const totalPrice = upsell.price * participantCount;
15341
15546
  const isDisabled = !upsell.available;
15547
+ const [isExpanded, setIsExpanded] = useState(false);
15548
+ const hasSavings = (upsell.savingsPercent ?? 0) > 0;
15342
15549
  const getCardStyles = () => {
15343
15550
  if (isDisabled)
15344
15551
  return cardDisabledStyles;
@@ -15346,16 +15553,22 @@ function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
15346
15553
  return cardSelectedStyles;
15347
15554
  return cardBaseStyles;
15348
15555
  };
15349
- return (jsxs("div", { style: getCardStyles(), onClick: !isDisabled ? onSelect : undefined, role: "checkbox", "aria-checked": isSelected, tabIndex: isDisabled ? -1 : 0, onKeyDown: (e) => {
15556
+ const toggleExpanded = () => {
15557
+ setIsExpanded((current) => !current);
15558
+ };
15559
+ return (jsxs("div", { style: getCardStyles(), onClick: !isDisabled ? toggleExpanded : undefined, role: "button", "aria-expanded": isExpanded, tabIndex: isDisabled ? -1 : 0, onKeyDown: (e) => {
15350
15560
  if (!isDisabled && (e.key === "Enter" || e.key === " ")) {
15351
15561
  e.preventDefault();
15352
- onSelect();
15562
+ toggleExpanded();
15353
15563
  }
15354
- }, children: [jsx("div", { style: checkboxContainerStyles, children: jsx("div", { style: isSelected ? checkboxSelectedStyles : checkboxInnerStyles, children: isSelected && (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", style: { width: "16px", height: "16px" }, children: jsx("polyline", { points: "20 6 9 17 4 12" }) })) }) }), jsx("div", { style: imageContainerStyles, children: upsell.image ? (jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsx("div", { style: imagePlaceholderStyles, children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "40px", height: "40px", opacity: 0.4 }, children: jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), jsxs("div", { style: { flex: 1 }, children: [jsx("h4", { style: nameStyles, children: upsell.name }), upsell.description && (jsx("p", { style: descriptionStyles, children: upsell.description })), upsell.items.length > 0 && (jsx("div", { style: itemsContainerStyles, children: upsell.items.map((item, index) => (jsxs("span", { style: itemStyles, children: [item.type === "product" ? "📦" : "🎫", " ", item.name, item.quantity > 1 && ` (${item.quantity}x)`] }, index))) })), upsell.suggestedEventInstance && (jsxs("div", { style: eventInfoStyles, children: [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", {
15564
+ }, children: [jsxs("div", { style: previewHeaderStyles, children: [jsx("div", { style: previewImageContainerStyles, children: upsell.image ? (jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsx("div", { style: imagePlaceholderStyles, children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "32px", height: "32px", opacity: 0.4 }, children: jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), jsxs("div", { style: { minWidth: 0 }, children: [jsx("h4", { style: previewNameStyles, children: upsell.name }), jsxs("div", { style: previewPriceStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), hasSavings && (jsx("div", { style: { ...previewPriceStyles, color: "var(--bw-highlight-color)" }, children: t("upsells.savePercent", { percent: upsell.savingsPercent ?? 0 }) }))] }), jsxs("div", { style: headerRightStyles, children: [jsx("button", { type: "button", onClick: (event) => {
15565
+ event.stopPropagation();
15566
+ onSelect();
15567
+ }, "aria-label": t("common.extras"), style: { background: "transparent", border: "none", cursor: "pointer", padding: 0 }, disabled: isDisabled, children: jsx("div", { style: isSelected ? checkboxSelectedStyles : checkboxInnerStyles, children: isSelected && (jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", style: { width: "32px", height: "32px" }, children: jsx("polyline", { points: "20 6 9 17 4 12" }) })) }) }), jsx("span", { style: { ...chevronStyles, transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)" }, children: "\u25BC" })] })] }), isExpanded && (jsxs("div", { style: expandedContentStyles, children: [jsx("div", { style: expandedImageContainerStyles, children: upsell.image ? (jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsx("div", { style: imagePlaceholderStyles, children: jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "40px", height: "40px", opacity: 0.4 }, children: jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), upsell.description && (jsx("p", { style: descriptionStyles, children: upsell.description })), upsell.items.length > 0 && (jsx("div", { style: itemsContainerStyles, children: upsell.items.map((item, index) => (jsxs("span", { style: itemStyles, children: [item.type === "product" ? "📦" : "🎫", " ", item.name, item.quantity > 1 && ` (${item.quantity}x)`] }, index))) })), upsell.suggestedEventInstance && (jsxs("div", { style: eventInfoStyles, children: [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", {
15355
15568
  weekday: "short",
15356
15569
  day: "numeric",
15357
15570
  month: "short",
15358
- })] }), jsx("span", { style: { color: "var(--bw-text-muted)" }, children: t("upsells.spotsFree", { count: upsell.suggestedEventInstance.availableSpots }) })] }))] }), jsxs("div", { style: priceContainerStyles, children: [jsxs("span", { style: pricePerPersonStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), participantCount > 1 && (jsxs("span", { style: priceTotalStyles, children: ["= ", formatCurrency(totalPrice)] }))] }), isDisabled && (jsx("div", { style: unavailableOverlayStyles, children: jsx("span", { children: upsell.unavailableReason
15571
+ })] }), jsx("span", { style: { color: "var(--bw-text-muted)" }, children: t("upsells.spotsFree", { count: upsell.suggestedEventInstance.availableSpots }) })] })), jsxs("div", { style: priceContainerStyles, children: [jsxs("span", { style: pricePerPersonStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), participantCount > 1 && (jsxs("span", { style: priceTotalStyles, children: ["= ", formatCurrency(totalPrice)] })), hasSavings && (jsx("span", { style: priceTotalStyles, children: t("upsells.savePercent", { percent: upsell.savingsPercent ?? 0 }) }))] })] })), isDisabled && (jsx("div", { style: unavailableOverlayStyles, children: jsx("span", { children: upsell.unavailableReason
15359
15572
  ? formatUnavailableReason(upsell.unavailableReason, t)
15360
15573
  : t("upsells.notAvailable") }) }))] }));
15361
15574
  }
@@ -15374,20 +15587,9 @@ function UpsellsStep({ upsells, selectedUpsells, participantCount, isLoading, is
15374
15587
  }
15375
15588
  };
15376
15589
  const isSelected = (upsellId) => selectedUpsells.some((s) => s.upsellPackageId === upsellId);
15377
- // Calculate total for selected upsells
15378
- const calculateTotal = () => {
15379
- return selectedUpsells.reduce((total, selection) => {
15380
- const upsell = upsells.find((u) => u.id === selection.upsellPackageId);
15381
- if (upsell) {
15382
- return total + upsell.price * selection.quantity;
15383
- }
15384
- return total;
15385
- }, 0);
15386
- };
15387
- const selectedTotal = calculateTotal();
15388
15590
  const selectedCount = selectedUpsells.length;
15389
15591
  const footerContent = (jsxs(Fragment, { children: [jsx("button", { type: "button", onClick: onBack, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), className: buttonClassName, children: t("common.back") }), jsx("button", { type: "button", onClick: onContinue, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), className: buttonClassName, children: selectedCount === 0 ? t("button.continueWithout") : t("button.continue") })] }));
15390
- return (jsx(Sidebar, { isOpen: isOpen, onClose: onClose, title: t("upsells.title"), footer: footerContent, children: jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", padding: "16px 16px" }, children: [isLoading && (jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "12px", padding: "40px 20px", ...textStyles.muted }, children: [spinner(), jsx("span", { children: t("upsells.loading") })] })), !isLoading && upsells.length === 0 && (jsx("div", { style: { textAlign: "center", padding: "40px 20px", ...textStyles.muted }, children: jsx("p", { children: t("upsells.noExtras") }) })), !isLoading && upsells.length > 0 && (jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", flex: 1, overflowY: "auto", paddingBottom: "16px" }, children: upsells.map((upsell) => (jsx(UpsellCard, { upsell: upsell, isSelected: isSelected(upsell.id), participantCount: participantCount, onSelect: () => selectUpsell(upsell.id) }, upsell.id))) })), selectedCount > 0 && (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: [jsx("span", { style: textStyles.muted, children: selectedCount === 1 ? t("upsells.selected", { count: selectedCount }) : t("upsells.selectedPlural", { count: selectedCount }) }), jsxs("span", { style: { fontWeight: 600, color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+", formatCurrency(selectedTotal)] })] }))] }) }));
15592
+ return (jsx(Sidebar, { isOpen: isOpen, onClose: onClose, title: t("upsells.title"), footer: footerContent, children: jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", padding: "16px 16px" }, children: [jsx(FlowProgress, { currentStep: "upsells", hasUpsellsStep: true }), isLoading && (jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "12px", padding: "40px 20px", ...textStyles.muted }, children: [spinner(), jsx("span", { children: t("upsells.loading") })] })), !isLoading && upsells.length === 0 && (jsx("div", { style: { textAlign: "center", padding: "40px 20px", ...textStyles.muted }, children: jsx("p", { children: t("upsells.noExtras") }) })), !isLoading && upsells.length > 0 && (jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", flex: 1, overflowY: "auto", paddingBottom: "16px" }, children: upsells.map((upsell) => (jsx(UpsellCard, { upsell: upsell, isSelected: isSelected(upsell.id), participantCount: participantCount, onSelect: () => selectUpsell(upsell.id) }, upsell.id))) })), selectedCount > 0 && (jsx("div", { style: { display: "flex", alignItems: "center", marginTop: "16px", paddingBottom: "16px", paddingTop: "16px", borderTop: "1px solid var(--bw-border-color)", fontSize: "14px" }, children: jsx("span", { style: textStyles.muted, children: selectedCount === 1 ? t("upsells.selected", { count: selectedCount }) : t("upsells.selectedPlural", { count: selectedCount }) }) }))] }) }));
15391
15593
  }
15392
15594
 
15393
15595
  /**
@@ -15525,8 +15727,10 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
15525
15727
  // Upsells state
15526
15728
  const [upsells, setUpsells] = useState([]);
15527
15729
  const [selectedUpsells, setSelectedUpsells] = useState([]);
15730
+ const [bookingPersistedState, setBookingPersistedState] = useState(null);
15528
15731
  const [isLoadingUpsells, setIsLoadingUpsells] = useState(false);
15529
15732
  const [tempParticipantCount, setTempParticipantCount] = useState(1); // Used during upsell step
15733
+ const hasUpsellsFlowStep = upsells.length > 0 || currentStep === "upsells";
15530
15734
  // State for upcoming events (next-events view mode)
15531
15735
  const [upcomingEvents, setUpcomingEvents] = useState([]);
15532
15736
  const [showingPreview, setShowingPreview] = useState(true);
@@ -15653,6 +15857,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
15653
15857
  ...(data.mollieProfileId ? { mollieProfileId: data.mollieProfileId } : {}),
15654
15858
  ...(data.mollieTestmode !== undefined ? { mollieTestmode: data.mollieTestmode } : {}),
15655
15859
  roundPricesEnabled: data.roundPricesEnabled ?? true,
15860
+ widgetPaymentMode: data.widgetPaymentMode ?? "all",
15656
15861
  });
15657
15862
  }
15658
15863
  }
@@ -16017,6 +16222,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16017
16222
  mollieProfileId: data.mollieProfileId,
16018
16223
  mollieTestmode: data.mollieTestmode,
16019
16224
  roundPricesEnabled: data.roundPricesEnabled ?? true,
16225
+ widgetPaymentMode: data.widgetPaymentMode ?? "all",
16020
16226
  });
16021
16227
  }
16022
16228
  if (data.stripePublishableKey) {
@@ -16077,6 +16283,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16077
16283
  mollieProfileId: data.mollieProfileId,
16078
16284
  mollieTestmode: data.mollieTestmode,
16079
16285
  roundPricesEnabled: data.roundPricesEnabled ?? true,
16286
+ widgetPaymentMode: data.widgetPaymentMode ?? "all",
16080
16287
  });
16081
16288
  if (!stripePromise && data.stripePublishableKey) {
16082
16289
  const stripeOptions = {
@@ -16179,6 +16386,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16179
16386
  const handleEventInstanceSelect = async (eventInstance) => {
16180
16387
  trackEvent("event_instance_selected", { eventInstanceId: eventInstance.id, eventInstanceName: eventInstance.name });
16181
16388
  setSelectedEventInstance(eventInstance);
16389
+ setBookingPersistedState(null);
16182
16390
  bookingReturnStep.current = "eventInstances";
16183
16391
  // Set default participant count for upsell calculations
16184
16392
  const defaultParticipantCount = 1;
@@ -16232,6 +16440,21 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16232
16440
  setCurrentStep(bookingReturnStep.current);
16233
16441
  setSelectedEventInstance(null);
16234
16442
  setEventDetails(null);
16443
+ setBookingPersistedState(null);
16444
+ };
16445
+ const handleBackFromBooking = () => {
16446
+ if (upsells.length > 0) {
16447
+ setCurrentStep("upsells");
16448
+ return;
16449
+ }
16450
+ if (isDirectInstanceMode) {
16451
+ setCurrentStep("eventTypes");
16452
+ setSidebarOpen(false);
16453
+ setEventDetails(null);
16454
+ setBookingPersistedState(null);
16455
+ return;
16456
+ }
16457
+ handleBackToEventInstances();
16235
16458
  };
16236
16459
  const handleBookingSuccess = (result) => {
16237
16460
  trackEvent("booking_completed", { paymentIntentId: result.paymentIntent?.id });
@@ -16239,6 +16462,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16239
16462
  setSuccessPaymentId(result.paymentIntent.id);
16240
16463
  setSidebarOpen(false);
16241
16464
  setShouldRenderBookingForm(false);
16465
+ setBookingPersistedState(null);
16242
16466
  config.onSuccess?.(result);
16243
16467
  };
16244
16468
  const handleBookingError = (errorMessage) => {
@@ -16307,6 +16531,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16307
16531
  ? (eventTypes.find((et) => et.id === eventTypeId) ?? selectedEventType)
16308
16532
  : selectedEventType;
16309
16533
  if (resolvedEventType && resolvedEventType !== selectedEventType) {
16534
+ trackEvent("event_type_selected", { eventTypeId: resolvedEventType.id, eventTypeName: resolvedEventType.name });
16310
16535
  setSelectedEventType(resolvedEventType);
16311
16536
  }
16312
16537
  // Check if this is coming from a card preview (eventTypeId was provided)
@@ -16360,7 +16585,9 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16360
16585
  }
16361
16586
  : null;
16362
16587
  if (eventInstance) {
16588
+ trackEvent("event_instance_selected", { eventInstanceId: eventInstance.id, eventInstanceName: eventInstance.name });
16363
16589
  setSelectedEventInstance(eventInstance);
16590
+ setBookingPersistedState(null);
16364
16591
  }
16365
16592
  setError(null);
16366
16593
  // Check for upsells before going to booking (same as handleEventInstanceSelect)
@@ -16524,19 +16751,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16524
16751
  }
16525
16752
  // Main view based on view mode
16526
16753
  if (viewMode === "next-events" && showingPreview) {
16527
- return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading }), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: () => {
16528
- setCurrentStep("eventTypes");
16529
- setShowingPreview(true);
16530
- setEventDetails(null);
16531
- }, onBackToEventTypes: () => {
16532
- setCurrentStep("eventTypes");
16533
- setShowingPreview(true);
16534
- setEventDetails(null);
16535
- }, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => {
16536
- setCurrentStep("eventTypes");
16537
- setShowingPreview(true);
16538
- setEventDetails(null);
16539
- }, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16754
+ return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading }), shouldRenderBookingForm && eventDetails && (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 })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16540
16755
  setIsSuccess(false);
16541
16756
  setCurrentStep("eventTypes");
16542
16757
  setShowingPreview(true);
@@ -16546,6 +16761,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16546
16761
  setShouldRenderBookingForm(false);
16547
16762
  setSelectedUpsells([]);
16548
16763
  setUpsells([]);
16764
+ setBookingPersistedState(null);
16549
16765
  const url = new URL(window.location.href);
16550
16766
  url.searchParams.delete("payment_intent");
16551
16767
  url.searchParams.delete("payment_intent_client_secret");
@@ -16556,19 +16772,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16556
16772
  }, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16557
16773
  }
16558
16774
  if (viewMode === "specials" && showingPreview) {
16559
- return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [jsx(SpecialsView, { specials: specials, onEventSelect: handleUpcomingEventSelect, isLoading: isLoadingSpecials, showSavingsAmount: config.specialsSettings?.showSavingsAmount ?? true, showSavingsPercent: config.specialsSettings?.showSavingsPercent ?? false, emptyStateText: config.specialsSettings?.emptyStateText }), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, onBackToEventInstances: () => {
16560
- setCurrentStep("eventTypes");
16561
- setShowingPreview(true);
16562
- setEventDetails(null);
16563
- }, onBackToEventTypes: () => {
16564
- setCurrentStep("eventTypes");
16565
- setShowingPreview(true);
16566
- setEventDetails(null);
16567
- }, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => {
16568
- setCurrentStep("eventTypes");
16569
- setShowingPreview(true);
16570
- setEventDetails(null);
16571
- }, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16775
+ return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [jsx(SpecialsView, { specials: specials, onEventSelect: handleUpcomingEventSelect, isLoading: isLoadingSpecials, showSavingsAmount: config.specialsSettings?.showSavingsAmount ?? true, showSavingsPercent: config.specialsSettings?.showSavingsPercent ?? false, emptyStateText: config.specialsSettings?.emptyStateText }), shouldRenderBookingForm && eventDetails && (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 })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16572
16776
  setIsSuccess(false);
16573
16777
  setCurrentStep("eventTypes");
16574
16778
  setShowingPreview(true);
@@ -16578,6 +16782,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16578
16782
  setShouldRenderBookingForm(false);
16579
16783
  setSelectedUpsells([]);
16580
16784
  setUpsells([]);
16785
+ setBookingPersistedState(null);
16581
16786
  }, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
16582
16787
  }
16583
16788
  if (viewMode === "next-events" && !showingPreview && currentStep === "eventInstances") {
@@ -16587,7 +16792,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16587
16792
  }, isOpen: currentStep === "eventInstances", onClose: () => {
16588
16793
  setShowingPreview(true);
16589
16794
  setCurrentStep("eventTypes");
16590
- }, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16795
+ }, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16591
16796
  setIsSuccess(false);
16592
16797
  setCurrentStep("eventTypes");
16593
16798
  setShowingPreview(true);
@@ -16630,7 +16835,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16630
16835
  setShouldRenderInstanceSelection(true);
16631
16836
  }
16632
16837
  }, children: config.buttonText ||
16633
- (isDirectInstanceMode ? t("button.bookNow") : t("button.selectDate")) }), shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (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 })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16838
+ (isDirectInstanceMode ? t("button.bookNow") : t("button.selectDate")) }), shouldRenderInstanceSelection && (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 && (jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (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 })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
16634
16839
  setIsSuccess(false);
16635
16840
  setCurrentStep("eventTypes");
16636
16841
  setSidebarOpen(false);
@@ -16662,32 +16867,36 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
16662
16867
  // Determine the correct back handlers based on view mode
16663
16868
  const getBackHandlers = () => {
16664
16869
  if (viewMode === "next-events") {
16665
- return {
16666
- onBackToEventInstances: () => {
16667
- setCurrentStep("eventInstances");
16870
+ const backFromBooking = () => {
16871
+ if (upsells.length > 0) {
16872
+ setCurrentStep("upsells");
16668
16873
  setShowingPreview(false);
16669
- setEventDetails(null);
16670
- },
16874
+ return;
16875
+ }
16876
+ setCurrentStep("eventInstances");
16877
+ setShowingPreview(false);
16878
+ setEventDetails(null);
16879
+ setBookingPersistedState(null);
16880
+ };
16881
+ return {
16882
+ onBackToEventInstances: backFromBooking,
16671
16883
  onBackToEventTypes: () => {
16672
16884
  setShowingPreview(true);
16673
16885
  setCurrentStep("eventTypes");
16674
16886
  setEventDetails(null);
16887
+ setBookingPersistedState(null);
16675
16888
  },
16676
- onClose: () => {
16677
- setCurrentStep("eventInstances");
16678
- setShowingPreview(false);
16679
- setEventDetails(null);
16680
- },
16889
+ onClose: backFromBooking,
16681
16890
  };
16682
16891
  }
16683
16892
  return {
16684
- onBackToEventInstances: handleBackToEventInstances,
16893
+ onBackToEventInstances: handleBackFromBooking,
16685
16894
  onBackToEventTypes: handleBackToEventTypes,
16686
- onClose: handleBackToEventInstances,
16895
+ onClose: handleBackFromBooking,
16687
16896
  };
16688
16897
  };
16689
16898
  const backHandlers = getBackHandlers();
16690
- return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (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 })), jsx(BookingSuccessModal, { isOpen: isSuccess && !voucherPurchaseResult, onClose: () => {
16899
+ return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep })), shouldRenderUpsells && (jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (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 })), jsx(BookingSuccessModal, { isOpen: isSuccess && !voucherPurchaseResult, onClose: () => {
16691
16900
  setIsSuccess(false);
16692
16901
  setCurrentStep("eventTypes");
16693
16902
  setSuccessPaymentId(null);