@bigz-app/booking-widget 1.3.3 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/booking-widget.js +358 -340
- package/dist/booking-widget.js.map +1 -1
- package/dist/components/UniversalBookingWidget.d.ts.map +1 -1
- package/dist/components/booking/BookingForm.d.ts +14 -5
- package/dist/components/booking/BookingForm.d.ts.map +1 -1
- package/dist/components/booking/index.d.ts +1 -1
- package/dist/components/booking/index.d.ts.map +1 -1
- package/dist/components/upsells/UpsellCard.d.ts.map +1 -1
- package/dist/components/upsells/UpsellsStep.d.ts +2 -0
- package/dist/components/upsells/UpsellsStep.d.ts.map +1 -1
- package/dist/i18n/locales/de.d.ts.map +1 -1
- package/dist/i18n/locales/en.d.ts.map +1 -1
- package/dist/i18n/locales/es.d.ts.map +1 -1
- package/dist/i18n/locales/pt.d.ts.map +1 -1
- package/dist/i18n/locales/sv.d.ts.map +1 -1
- package/dist/index.cjs +358 -340
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +358 -340
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -245,6 +245,8 @@ const de$1 = {
|
|
|
245
245
|
"button.depositAndBook": "Anzahlen & buchen",
|
|
246
246
|
"button.continueWithout": "Weiter ohne Extras",
|
|
247
247
|
"button.continue": "Weiter",
|
|
248
|
+
"button.continueToPayment": "Weiter zur Zahlung",
|
|
249
|
+
"button.backToDetails": "Zurück zu den Angaben",
|
|
248
250
|
"button.addExtras": "Extras hinzufügen",
|
|
249
251
|
// Event types
|
|
250
252
|
"events.noEventsAvailable": "Keine Veranstaltungen verfügbar",
|
|
@@ -437,6 +439,8 @@ const de$1 = {
|
|
|
437
439
|
"upsells.noExtras": "Keine Extras für diese Buchung verfügbar.",
|
|
438
440
|
"upsells.selected": "{{count}} Extra ausgewählt",
|
|
439
441
|
"upsells.selectedPlural": "{{count}} Extras ausgewählt",
|
|
442
|
+
"upsells.savePercent": "{{percent}}% sparen",
|
|
443
|
+
"booking.paymentUnavailable": "Online-Zahlung ist für diese Buchung nicht verfügbar. Bitte kontaktiere uns, um die Reservierung abzuschließen.",
|
|
440
444
|
"upsells.spotsFree": "{{count}} Plätze frei",
|
|
441
445
|
"upsells.notAvailable": "Nicht verfügbar",
|
|
442
446
|
"upsells.reason.outOfStock": "{{productName}} ist nicht auf Lager",
|
|
@@ -521,6 +525,8 @@ const en = {
|
|
|
521
525
|
"button.depositAndBook": "Pay deposit & book",
|
|
522
526
|
"button.continueWithout": "Continue without extras",
|
|
523
527
|
"button.continue": "Continue",
|
|
528
|
+
"button.continueToPayment": "Continue to payment",
|
|
529
|
+
"button.backToDetails": "Back to details",
|
|
524
530
|
"button.addExtras": "Add extras",
|
|
525
531
|
// Event types
|
|
526
532
|
"events.noEventsAvailable": "No events available",
|
|
@@ -713,6 +719,8 @@ const en = {
|
|
|
713
719
|
"upsells.noExtras": "No extras available for this booking.",
|
|
714
720
|
"upsells.selected": "{{count}} extra selected",
|
|
715
721
|
"upsells.selectedPlural": "{{count}} extras selected",
|
|
722
|
+
"upsells.savePercent": "Save {{percent}}%",
|
|
723
|
+
"booking.paymentUnavailable": "Online payment is not available for this booking. Please contact us to complete your reservation.",
|
|
716
724
|
"upsells.spotsFree": "{{count}} spots available",
|
|
717
725
|
"upsells.notAvailable": "Not available",
|
|
718
726
|
"upsells.reason.outOfStock": "{{productName}} is out of stock",
|
|
@@ -797,6 +805,8 @@ const es = {
|
|
|
797
805
|
"button.depositAndBook": "Pagar depósito y reservar",
|
|
798
806
|
"button.continueWithout": "Continuar sin extras",
|
|
799
807
|
"button.continue": "Continuar",
|
|
808
|
+
"button.continueToPayment": "Continuar al pago",
|
|
809
|
+
"button.backToDetails": "Volver a los datos",
|
|
800
810
|
"button.addExtras": "Añadir extras",
|
|
801
811
|
// Event types
|
|
802
812
|
"events.noEventsAvailable": "No hay eventos disponibles",
|
|
@@ -989,6 +999,8 @@ const es = {
|
|
|
989
999
|
"upsells.noExtras": "No hay extras disponibles para esta reserva.",
|
|
990
1000
|
"upsells.selected": "{{count}} extra seleccionado",
|
|
991
1001
|
"upsells.selectedPlural": "{{count}} extras seleccionados",
|
|
1002
|
+
"upsells.savePercent": "Ahorra {{percent}}%",
|
|
1003
|
+
"booking.paymentUnavailable": "El pago en línea no está disponible para esta reserva. Contáctanos para completarla.",
|
|
992
1004
|
"upsells.spotsFree": "{{count}} plazas disponibles",
|
|
993
1005
|
"upsells.notAvailable": "No disponible",
|
|
994
1006
|
"upsells.reason.outOfStock": "{{productName}} está agotado",
|
|
@@ -1073,6 +1085,8 @@ const pt = {
|
|
|
1073
1085
|
"button.depositAndBook": "Pagar sinal e reservar",
|
|
1074
1086
|
"button.continueWithout": "Continuar sem extras",
|
|
1075
1087
|
"button.continue": "Continuar",
|
|
1088
|
+
"button.continueToPayment": "Continuar para pagamento",
|
|
1089
|
+
"button.backToDetails": "Voltar aos dados",
|
|
1076
1090
|
"button.addExtras": "Adicionar extras",
|
|
1077
1091
|
// Event types
|
|
1078
1092
|
"events.noEventsAvailable": "Sem eventos disponíveis",
|
|
@@ -1265,6 +1279,8 @@ const pt = {
|
|
|
1265
1279
|
"upsells.noExtras": "Sem extras disponíveis para esta reserva.",
|
|
1266
1280
|
"upsells.selected": "{{count}} extra selecionado",
|
|
1267
1281
|
"upsells.selectedPlural": "{{count}} extras selecionados",
|
|
1282
|
+
"upsells.savePercent": "Poupa {{percent}}%",
|
|
1283
|
+
"booking.paymentUnavailable": "O pagamento online não está disponível para esta reserva. Contacta-nos para concluir a reserva.",
|
|
1268
1284
|
"upsells.spotsFree": "{{count}} lugares disponíveis",
|
|
1269
1285
|
"upsells.notAvailable": "Não disponível",
|
|
1270
1286
|
"upsells.reason.outOfStock": "{{productName}} está esgotado",
|
|
@@ -1349,6 +1365,8 @@ const sv = {
|
|
|
1349
1365
|
"button.depositAndBook": "Betala handpenning & boka",
|
|
1350
1366
|
"button.continueWithout": "Fortsätt utan tillägg",
|
|
1351
1367
|
"button.continue": "Fortsätt",
|
|
1368
|
+
"button.continueToPayment": "Fortsätt till betalning",
|
|
1369
|
+
"button.backToDetails": "Tillbaka till uppgifter",
|
|
1352
1370
|
"button.addExtras": "Lägg till tillägg",
|
|
1353
1371
|
// Event types
|
|
1354
1372
|
"events.noEventsAvailable": "Inga evenemang tillgängliga",
|
|
@@ -1541,6 +1559,8 @@ const sv = {
|
|
|
1541
1559
|
"upsells.noExtras": "Inga tillägg tillgängliga för denna bokning.",
|
|
1542
1560
|
"upsells.selected": "{{count}} tillägg valt",
|
|
1543
1561
|
"upsells.selectedPlural": "{{count}} tillägg valda",
|
|
1562
|
+
"upsells.savePercent": "Spara {{percent}}%",
|
|
1563
|
+
"booking.paymentUnavailable": "Onlinebetalning är inte tillgänglig för denna bokning. Kontakta oss för att slutföra bokningen.",
|
|
1544
1564
|
"upsells.spotsFree": "{{count}} platser lediga",
|
|
1545
1565
|
"upsells.notAvailable": "Inte tillgängligt",
|
|
1546
1566
|
"upsells.reason.outOfStock": "{{productName}} är slut i lager",
|
|
@@ -11473,7 +11493,7 @@ const sectionHeaderStyles$1 = sectionStyles.header;
|
|
|
11473
11493
|
const labelStyles$1 = formStyles.label;
|
|
11474
11494
|
const inputStyles$1 = formStyles.input;
|
|
11475
11495
|
const errorTextStyles$1 = formStyles.error;
|
|
11476
|
-
function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
11496
|
+
function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError, isOpen, onClose, systemConfig, selectedUpsells = [], upsells = [], persistedState = null, onPersistedStateChange, }) {
|
|
11477
11497
|
const t$1 = useTranslations();
|
|
11478
11498
|
const { locale } = useLocale();
|
|
11479
11499
|
const timezone = useTimezone();
|
|
@@ -11485,15 +11505,16 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11485
11505
|
const raw = Math.round((baseAmount * basisPoints) / 10000);
|
|
11486
11506
|
return round ? roundDiscountUp(raw) : raw;
|
|
11487
11507
|
};
|
|
11488
|
-
const [appliedVouchers, setAppliedVouchers] = React.useState([]);
|
|
11489
|
-
const
|
|
11508
|
+
const [appliedVouchers, setAppliedVouchers] = React.useState(() => persistedState?.appliedVouchers ?? []);
|
|
11509
|
+
const [checkoutStep, setCheckoutStep] = React.useState(() => persistedState?.checkoutStep ?? "details");
|
|
11490
11510
|
// Payment option: "deposit" or "full" - only relevant when deposit is available
|
|
11491
|
-
const [paymentOption, setPaymentOption] = React.useState("deposit");
|
|
11511
|
+
const [paymentOption, setPaymentOption] = React.useState(() => persistedState?.paymentOption ?? "deposit");
|
|
11492
11512
|
// Per-participant upsell selections: participantIndex -> array of upsell package IDs
|
|
11493
|
-
const [participantUpsells, setParticipantUpsells] = React.useState({});
|
|
11513
|
+
const [participantUpsells, setParticipantUpsells] = React.useState(() => persistedState?.participantUpsells ?? {});
|
|
11514
|
+
const wasOpenRef = React.useRef(false);
|
|
11494
11515
|
const form = useForm({
|
|
11495
11516
|
resolver: t(createBookingFormSchema(t$1, participantFieldsConfig)),
|
|
11496
|
-
defaultValues: {
|
|
11517
|
+
defaultValues: persistedState?.formData ?? {
|
|
11497
11518
|
customerName: "",
|
|
11498
11519
|
customerEmail: "",
|
|
11499
11520
|
customerPhone: "",
|
|
@@ -11503,6 +11524,28 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11503
11524
|
acceptTerms: false,
|
|
11504
11525
|
},
|
|
11505
11526
|
});
|
|
11527
|
+
const persistState = React.useCallback(() => {
|
|
11528
|
+
onPersistedStateChange?.({
|
|
11529
|
+
formData: form.getValues(),
|
|
11530
|
+
checkoutStep,
|
|
11531
|
+
paymentOption,
|
|
11532
|
+
appliedVouchers,
|
|
11533
|
+
participantUpsells,
|
|
11534
|
+
});
|
|
11535
|
+
}, [onPersistedStateChange, form, checkoutStep, paymentOption, appliedVouchers, participantUpsells]);
|
|
11536
|
+
React.useEffect(() => {
|
|
11537
|
+
if (isOpen && !wasOpenRef.current && persistedState) {
|
|
11538
|
+
form.reset(persistedState.formData);
|
|
11539
|
+
setCheckoutStep(persistedState.checkoutStep);
|
|
11540
|
+
setPaymentOption(persistedState.paymentOption);
|
|
11541
|
+
setAppliedVouchers(persistedState.appliedVouchers);
|
|
11542
|
+
setParticipantUpsells(persistedState.participantUpsells);
|
|
11543
|
+
}
|
|
11544
|
+
if (!isOpen && wasOpenRef.current) {
|
|
11545
|
+
persistState();
|
|
11546
|
+
}
|
|
11547
|
+
wasOpenRef.current = isOpen;
|
|
11548
|
+
}, [isOpen, persistedState, form, persistState]);
|
|
11506
11549
|
const watchedParticipants = form.watch("participants");
|
|
11507
11550
|
const participantCount = watchedParticipants.length;
|
|
11508
11551
|
const watchedCustomerName = form.watch("customerName");
|
|
@@ -11627,6 +11670,18 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11627
11670
|
}), [watchedCustomerName, watchedCustomerEmail, watchedCustomerPhone, watchedParticipants, watchedComment]);
|
|
11628
11671
|
const appliedDiscountCode = appliedVouchers.find((v) => v.type === "discount");
|
|
11629
11672
|
const appliedGiftCards = appliedVouchers.filter((v) => v.type === "giftCard");
|
|
11673
|
+
const discountCodeProp = appliedDiscountCode
|
|
11674
|
+
? {
|
|
11675
|
+
id: appliedDiscountCode.id,
|
|
11676
|
+
code: appliedDiscountCode.code,
|
|
11677
|
+
description: appliedDiscountCode.description || undefined,
|
|
11678
|
+
type: appliedDiscountCode.discountType || "percentage",
|
|
11679
|
+
value: appliedDiscountCode.discountValue || 0,
|
|
11680
|
+
discountAmount: appliedDiscountCode.discountAmount,
|
|
11681
|
+
newTotal: appliedDiscountCode.newTotal,
|
|
11682
|
+
}
|
|
11683
|
+
: null;
|
|
11684
|
+
const hasPaymentProvider = Boolean(stripePromise || systemConfig?.paymentProvider === "mollie");
|
|
11630
11685
|
const handleVoucherValidated = React.useCallback((voucher, _error) => {
|
|
11631
11686
|
if (voucher) {
|
|
11632
11687
|
setAppliedVouchers((prev) => [...prev, voucher]);
|
|
@@ -11738,19 +11793,12 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11738
11793
|
});
|
|
11739
11794
|
}, [config]);
|
|
11740
11795
|
const handleClose = () => {
|
|
11796
|
+
persistState();
|
|
11797
|
+
setCheckoutStep("details");
|
|
11741
11798
|
onClose();
|
|
11742
|
-
if (selectedEventInstance && selectedEventType) {
|
|
11743
|
-
onBackToEventInstances?.();
|
|
11744
|
-
}
|
|
11745
|
-
else if (selectedEventType) {
|
|
11746
|
-
onBackToEventTypes?.();
|
|
11747
|
-
}
|
|
11748
|
-
};
|
|
11749
|
-
const scrollToPayment = () => {
|
|
11750
|
-
paymentSectionRef.current?.scrollIntoView({ behavior: "smooth", block: "start" });
|
|
11751
11799
|
};
|
|
11752
11800
|
// Footer navigation
|
|
11753
|
-
const footerContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: handleClose, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: t$1("common.back") }), jsxRuntime.jsx("button", { type: "button", onClick:
|
|
11801
|
+
const footerContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: checkoutStep === "payment" ? () => setCheckoutStep("details") : handleClose, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: checkoutStep === "payment" ? t$1("button.backToDetails") : t$1("common.back") }), checkoutStep === "details" && (jsxRuntime.jsx("button", { type: "button", onClick: () => setCheckoutStep("payment"), disabled: !isReadyForPayment() || !hasPaymentProvider, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), children: t$1("button.continueToPayment") }))] }));
|
|
11754
11802
|
if (!eventDetails.bookingOpen) {
|
|
11755
11803
|
return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.notPossible"), children: jsxRuntime.jsx("div", { style: {
|
|
11756
11804
|
display: "flex",
|
|
@@ -11767,264 +11815,211 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11767
11815
|
fontFamily: "var(--bw-font-family)",
|
|
11768
11816
|
}, children: t$1("booking.notPossible") }), jsxRuntime.jsx("p", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.notPossibleMessage") })] }) }) }));
|
|
11769
11817
|
}
|
|
11770
|
-
return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.title", { name: eventDetails.name }), footer: footerContent, children: jsxRuntime.jsxs("div", { className: "booking-widget-container", style: { padding: "16px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.eventDetails") }), jsxRuntime.jsxs("div", { style: {
|
|
11771
|
-
|
|
11772
|
-
|
|
11773
|
-
|
|
11774
|
-
|
|
11775
|
-
|
|
11776
|
-
|
|
11777
|
-
|
|
11778
|
-
|
|
11779
|
-
|
|
11780
|
-
|
|
11781
|
-
|
|
11782
|
-
|
|
11783
|
-
|
|
11784
|
-
|
|
11785
|
-
|
|
11786
|
-
|
|
11787
|
-
|
|
11788
|
-
|
|
11789
|
-
|
|
11790
|
-
|
|
11791
|
-
|
|
11792
|
-
|
|
11793
|
-
|
|
11794
|
-
|
|
11795
|
-
|
|
11796
|
-
|
|
11797
|
-
|
|
11818
|
+
return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: handleClose, title: t$1("booking.title", { name: eventDetails.name }), footer: footerContent, children: jsxRuntime.jsxs("div", { className: "booking-widget-container", style: { padding: "16px" }, children: [checkoutStep === "details" && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.eventDetails") }), jsxRuntime.jsxs("div", { style: {
|
|
11819
|
+
display: "grid",
|
|
11820
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
|
|
11821
|
+
gap: "12px",
|
|
11822
|
+
fontSize: "14px",
|
|
11823
|
+
}, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
|
|
11824
|
+
color: "var(--bw-text-muted)",
|
|
11825
|
+
fontFamily: "var(--bw-font-family)",
|
|
11826
|
+
display: "flex",
|
|
11827
|
+
alignItems: "center",
|
|
11828
|
+
gap: "4px",
|
|
11829
|
+
}, children: [jsxRuntime.jsx(IconCalendar, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.date")] }), jsxRuntime.jsxs("span", { style: {
|
|
11830
|
+
color: "var(--bw-text-color)",
|
|
11831
|
+
fontWeight: 500,
|
|
11832
|
+
fontFamily: "var(--bw-font-family)",
|
|
11833
|
+
}, children: [formatEventDate(eventDetails.startTime, timezone, locale), " \u2022 ", formatTime(eventDetails.startTime, timezone, locale)] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
|
|
11834
|
+
color: "var(--bw-text-muted)",
|
|
11835
|
+
fontFamily: "var(--bw-font-family)",
|
|
11836
|
+
display: "flex",
|
|
11837
|
+
alignItems: "center",
|
|
11838
|
+
gap: "4px",
|
|
11839
|
+
}, children: [jsxRuntime.jsx(IconClock, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.duration")] }), jsxRuntime.jsxs("span", { style: {
|
|
11840
|
+
color: "var(--bw-text-color)",
|
|
11841
|
+
fontWeight: 500,
|
|
11842
|
+
fontFamily: "var(--bw-font-family)",
|
|
11843
|
+
}, children: [eventDetails.durationDays, " ", eventDetails.durationDays > 1 ? t$1("common.days") : t$1("common.day")] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [jsxRuntime.jsxs("span", { style: {
|
|
11844
|
+
color: "var(--bw-text-muted)",
|
|
11845
|
+
fontFamily: "var(--bw-font-family)",
|
|
11846
|
+
display: "flex",
|
|
11847
|
+
alignItems: "center",
|
|
11848
|
+
gap: "4px",
|
|
11849
|
+
}, children: [jsxRuntime.jsx(IconMoney, { size: 20, color: "var(--bw-highlight-color)" }), " ", t$1("booking.price")] }), jsxRuntime.jsxs("span", { style: {
|
|
11850
|
+
color: "var(--bw-text-color)",
|
|
11851
|
+
fontWeight: 500,
|
|
11852
|
+
fontFamily: "var(--bw-font-family)",
|
|
11853
|
+
}, children: [formatCurrency(eventDetails.price), " ", t$1("common.perPerson")] })] })] })] }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: sectionHeaderStyles$1, children: t$1("booking.contactInfo") }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "16px" }, children: [jsxRuntime.jsxs("div", { style: {
|
|
11854
|
+
display: "grid",
|
|
11855
|
+
gridTemplateColumns: "repeat(auto-fit, minmax(200px, 1fr))",
|
|
11856
|
+
gap: "16px",
|
|
11857
|
+
}, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerName", style: labelStyles$1, children: t$1("booking.name") }), jsxRuntime.jsx("input", { id: "customerName", ...form.register("customerName"), type: "text", style: inputStyles$1, placeholder: t$1("booking.namePlaceholder") }), customerNameError && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: customerNameError.message }))] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerEmail", style: labelStyles$1, children: t$1("booking.email") }), jsxRuntime.jsx("input", { id: "customerEmail", ...form.register("customerEmail"), type: "email", style: inputStyles$1, placeholder: t$1("booking.emailPlaceholder") }), customerEmailError && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: customerEmailError.message }))] })] }), jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { htmlFor: "customerPhone", style: labelStyles$1, children: t$1("booking.phone") }), jsxRuntime.jsx("input", { id: "customerPhone", ...form.register("customerPhone"), type: "tel", style: inputStyles$1, placeholder: t$1("booking.phonePlaceholder") })] }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", border: "1px solid var(--bw-border-color)", padding: "16px", borderRadius: "var(--bw-border-radius)" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsxRuntime.jsx("input", { id: "acceptTerms", ...form.register("acceptTerms"), type: "checkbox", style: formStyles.checkbox }), jsxRuntime.jsxs("label", { htmlFor: "acceptTerms", style: {
|
|
11858
|
+
fontSize: "14px",
|
|
11859
|
+
color: "var(--bw-text-muted)",
|
|
11860
|
+
fontFamily: "var(--bw-font-family)",
|
|
11861
|
+
maxWidth: "calc(100% - 32px)",
|
|
11862
|
+
overflowWrap: "break-word",
|
|
11863
|
+
cursor: "pointer",
|
|
11864
|
+
}, children: [t$1("booking.acceptTerms"), " ", jsxRuntime.jsx("a", { href: eventDetails.agbUrl || "/terms", style: { color: "var(--bw-highlight-color)", textDecoration: "none" }, target: "_blank", rel: "noopener noreferrer", children: t$1("booking.terms") }), "*"] })] }), form.formState.errors.acceptTerms && (jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, marginTop: "8px" }, children: form.formState.errors.acceptTerms.message }))] })] })] }), jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("div", { style: {
|
|
11798
11865
|
display: "flex",
|
|
11866
|
+
justifyContent: "space-between",
|
|
11799
11867
|
alignItems: "center",
|
|
11800
|
-
|
|
11801
|
-
}, children:
|
|
11802
|
-
|
|
11803
|
-
|
|
11804
|
-
|
|
11805
|
-
|
|
11806
|
-
|
|
11807
|
-
|
|
11808
|
-
|
|
11809
|
-
|
|
11868
|
+
marginBottom: "16px",
|
|
11869
|
+
}, children: jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: 0 }, children: t$1("booking.participants") }) }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "16px" }, children: [watchedParticipants.map((_, index) => (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", gap: "12px", alignItems: "center" }, children: [participantFieldsConfig.name.enabled && (jsxRuntime.jsxs("div", { style: { flex: 1 }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-name-${index}`, style: labelStyles$1, children: t$1("booking.participantName") }), jsxRuntime.jsx("input", { id: `participant-name-${index}`, ...form.register(`participants.${index}.name`), type: "text", style: inputStyles$1, placeholder: t$1("booking.participantNamePlaceholder") }), form.formState.errors.participants?.[index]?.name && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.name?.message }))] })), participantFieldsConfig.age.enabled && (jsxRuntime.jsxs("div", { style: { width: "80px" }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-age-${index}`, style: labelStyles$1, children: t$1("booking.participantAge") }), jsxRuntime.jsx("input", { id: `participant-age-${index}`, ...form.register(`participants.${index}.age`, {
|
|
11870
|
+
setValueAs: (value) => {
|
|
11871
|
+
if (value === "" || value === null || value === undefined) {
|
|
11872
|
+
return undefined;
|
|
11873
|
+
}
|
|
11874
|
+
const num = Number(value);
|
|
11875
|
+
return Number.isNaN(num) ? undefined : num;
|
|
11876
|
+
},
|
|
11877
|
+
}), type: "number", min: "0", max: "120", style: inputStyles$1, placeholder: "25" })] })), watchedParticipants.length > 1 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { style: { ...labelStyles$1, visibility: "hidden" }, children: "\u00A0" }), jsxRuntime.jsx("button", { type: "button", onClick: () => removeParticipant(index), style: {
|
|
11878
|
+
color: "var(--bw-error-color)",
|
|
11879
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
11880
|
+
border: "1px solid var(--bw-border-color)",
|
|
11881
|
+
borderRadius: "50%",
|
|
11882
|
+
width: "36px",
|
|
11883
|
+
height: "36px",
|
|
11884
|
+
display: "flex",
|
|
11885
|
+
alignItems: "center",
|
|
11886
|
+
justifyContent: "center",
|
|
11887
|
+
cursor: "pointer",
|
|
11888
|
+
transition: "all 0.2s ease",
|
|
11889
|
+
fontSize: "24px",
|
|
11890
|
+
fontWeight: 700,
|
|
11891
|
+
fontFamily: "var(--bw-font-family)",
|
|
11892
|
+
padding: 0,
|
|
11893
|
+
}, children: "\u00D7" })] }))] }), participantFieldsConfig.level.enabled && (jsxRuntime.jsxs("div", { style: { minWidth: "140px" }, children: [jsxRuntime.jsx("label", { htmlFor: `participant-level-${index}`, style: labelStyles$1, children: t$1("booking.participantLevel") }), jsxRuntime.jsxs("select", { id: `participant-level-${index}`, ...form.register(`participants.${index}.level`), style: inputStyles$1, children: [jsxRuntime.jsx("option", { value: "", children: t$1("booking.participantLevelPlaceholder") }), participantLevelOptions.map((level) => (jsxRuntime.jsx("option", { value: level, children: t$1(`level.${level}`) }, level)))] }), form.formState.errors.participants?.[index]?.level && (jsxRuntime.jsx("p", { style: errorTextStyles$1, children: form.formState.errors.participants[index]?.level?.message }))] })), upsells.length > 0 && (jsxRuntime.jsx("div", { style: participantUpsellStyles.container, children: upsells.map((upsell) => {
|
|
11894
|
+
const isSelected = (participantUpsells[index] || []).includes(upsell.id);
|
|
11895
|
+
return (jsxRuntime.jsxs("label", { htmlFor: `upsell-${index}-${upsell.id}`, style: isSelected ? participantUpsellStyles.labelSelected : participantUpsellStyles.label, children: [jsxRuntime.jsx("input", { id: `upsell-${index}-${upsell.id}`, type: "checkbox", style: participantUpsellStyles.checkbox, checked: isSelected, onChange: () => toggleParticipantUpsell(index, upsell.id) }), jsxRuntime.jsx("span", { style: { fontWeight: 500 }, children: upsell.name }), jsxRuntime.jsxs("span", { style: { fontSize: "12px", opacity: 0.8 }, children: ["(+", formatCurrency(upsell.price), ")"] })] }, upsell.id));
|
|
11896
|
+
}) }))] }, index))), watchedParticipants.length < eventDetails.availableSpots ? (jsxRuntime.jsx("div", { style: {
|
|
11897
|
+
display: "flex",
|
|
11898
|
+
flexDirection: "column",
|
|
11899
|
+
alignItems: "center",
|
|
11900
|
+
marginTop: "12px",
|
|
11901
|
+
}, children: jsxRuntime.jsx("button", { type: "button", onClick: addParticipant, style: {
|
|
11902
|
+
color: "#ffffff",
|
|
11903
|
+
fontSize: "14px",
|
|
11904
|
+
fontWeight: 600,
|
|
11905
|
+
padding: "8px 16px",
|
|
11906
|
+
borderRadius: "var(--bw-border-radius)",
|
|
11907
|
+
backgroundColor: "var(--bw-highlight-color)",
|
|
11908
|
+
border: "1px solid var(--bw-highlight-color)",
|
|
11909
|
+
cursor: "pointer",
|
|
11910
|
+
transition: "all 0.2s ease",
|
|
11911
|
+
marginBottom: "4px",
|
|
11912
|
+
fontFamily: "var(--bw-font-family)",
|
|
11913
|
+
boxShadow: "0 2px 8px 0 var(--bw-highlight-color)",
|
|
11914
|
+
}, children: t$1("booking.addParticipant", { number: watchedParticipants.length + 1 }) }) })) : (jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.maxSpotsReached", { count: eventDetails.availableSpots }) }))] })] }), jsxRuntime.jsx(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("label", { htmlFor: "booking-comment", style: labelStyles$1, children: t$1("booking.comment") }), jsxRuntime.jsx("textarea", { id: "booking-comment", ...form.register("comment"), placeholder: t$1("booking.commentPlaceholder"), rows: 3, style: {
|
|
11915
|
+
...inputStyles$1,
|
|
11916
|
+
resize: "vertical",
|
|
11917
|
+
minHeight: "80px",
|
|
11918
|
+
} })] })] })] })), checkoutStep === "payment" && (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: "16px" }, children: t$1("summary.title") }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "12px" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.price") }), jsxRuntime.jsxs("div", { style: {
|
|
11919
|
+
color: "var(--bw-text-color)",
|
|
11920
|
+
fontWeight: 500,
|
|
11921
|
+
fontFamily: "var(--bw-font-family)",
|
|
11922
|
+
}, children: [jsxRuntime.jsxs("span", { style: { fontWeight: 200 }, children: [watchedParticipants.length > 1 ? watchedParticipants.length : 1, " x "] }), " ", formatCurrency(eventDetails.price)] })] }), upsellsTotal > 0 && (jsxRuntime.jsxs("div", { style: { marginTop: "8px", paddingTop: "8px", borderTop: "1px dashed var(--bw-border-color)" }, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)", fontSize: "13px", display: "block", marginBottom: "4px" }, children: [t$1("common.extras"), ":"] }), upsells.map((upsell) => {
|
|
11923
|
+
// Count how many participants have this upsell selected
|
|
11924
|
+
const countWithUpsell = watchedParticipants.filter((_, idx) => (participantUpsells[idx] || []).includes(upsell.id)).length;
|
|
11925
|
+
if (countWithUpsell === 0)
|
|
11926
|
+
return null;
|
|
11927
|
+
const upsellLineTotal = upsell.price * countWithUpsell;
|
|
11928
|
+
return (jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "2px", fontSize: "13px" }, children: jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+ ", upsell.name, " (", countWithUpsell, "\u00D7)"] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(upsellLineTotal) })] }) }, upsell.id));
|
|
11929
|
+
})] })), appliedVouchers.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.subtotal") }), jsxRuntime.jsx("span", { style: {
|
|
11930
|
+
fontFamily: "var(--bw-font-family)",
|
|
11931
|
+
color: totalDiscount > 0 ? "var(--bw-text-muted)" : "var(--bw-text-muted)",
|
|
11932
|
+
textDecoration: totalDiscount > 0 ? "line-through" : "none",
|
|
11933
|
+
}, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
|
|
11934
|
+
color: "var(--bw-success-color)",
|
|
11935
|
+
fontFamily: "var(--bw-font-family)",
|
|
11810
11936
|
fontSize: "14px",
|
|
11937
|
+
}, children: t$1("summary.discount", { code: appliedDiscountCode.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
|
|
11938
|
+
color: "var(--bw-success-color)",
|
|
11939
|
+
fontFamily: "var(--bw-font-family)",
|
|
11940
|
+
fontSize: "14px",
|
|
11941
|
+
}, children: t$1("summary.giftCard", { code: giftCard.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), jsxRuntime.jsxs("div", { style: {
|
|
11942
|
+
borderTop: "1px solid var(--bw-border-color)",
|
|
11943
|
+
paddingTop: "12px",
|
|
11944
|
+
}, children: [hasDepositOption && (jsxRuntime.jsxs("div", { style: {
|
|
11945
|
+
display: "flex",
|
|
11946
|
+
justifyContent: "space-between",
|
|
11947
|
+
alignItems: "center",
|
|
11948
|
+
fontSize: "14px",
|
|
11949
|
+
marginBottom: "12px",
|
|
11950
|
+
}, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
|
|
11811
11951
|
color: "var(--bw-text-muted)",
|
|
11812
11952
|
fontFamily: "var(--bw-font-family)",
|
|
11813
|
-
|
|
11814
|
-
|
|
11953
|
+
fontWeight: 500,
|
|
11954
|
+
}, children: formatCurrency(totalAmount) })] })), hasDepositOption && (jsxRuntime.jsxs("div", { style: {
|
|
11955
|
+
display: "flex",
|
|
11956
|
+
gap: "8px",
|
|
11957
|
+
marginBottom: "16px",
|
|
11958
|
+
}, children: [jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("deposit"), style: {
|
|
11959
|
+
flex: 1,
|
|
11960
|
+
padding: "12px",
|
|
11961
|
+
borderRadius: "var(--bw-border-radius)",
|
|
11962
|
+
border: paymentOption === "deposit"
|
|
11963
|
+
? "2px solid var(--bw-highlight-color)"
|
|
11964
|
+
: "1px solid var(--bw-border-color)",
|
|
11965
|
+
backgroundColor: paymentOption === "deposit"
|
|
11966
|
+
? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
|
|
11967
|
+
: "var(--bw-surface-color)",
|
|
11815
11968
|
cursor: "pointer",
|
|
11816
|
-
|
|
11817
|
-
|
|
11818
|
-
|
|
11819
|
-
|
|
11820
|
-
|
|
11821
|
-
|
|
11822
|
-
|
|
11823
|
-
|
|
11824
|
-
return undefined;
|
|
11825
|
-
}
|
|
11826
|
-
const num = Number(value);
|
|
11827
|
-
return Number.isNaN(num) ? undefined : num;
|
|
11828
|
-
},
|
|
11829
|
-
}), type: "number", min: "0", max: "120", style: inputStyles$1, placeholder: "25" })] })), watchedParticipants.length > 1 && (jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("label", { style: { ...labelStyles$1, visibility: "hidden" }, children: "\u00A0" }), jsxRuntime.jsx("button", { type: "button", onClick: () => removeParticipant(index), style: {
|
|
11830
|
-
color: "var(--bw-error-color)",
|
|
11831
|
-
backgroundColor: "var(--bw-surface-color)",
|
|
11832
|
-
border: "1px solid var(--bw-border-color)",
|
|
11833
|
-
borderRadius: "50%",
|
|
11834
|
-
width: "36px",
|
|
11835
|
-
height: "36px",
|
|
11836
|
-
display: "flex",
|
|
11837
|
-
alignItems: "center",
|
|
11838
|
-
justifyContent: "center",
|
|
11839
|
-
cursor: "pointer",
|
|
11840
|
-
transition: "all 0.2s ease",
|
|
11841
|
-
fontSize: "24px",
|
|
11969
|
+
fontFamily: "var(--bw-font-family)",
|
|
11970
|
+
transition: "all 0.2s ease",
|
|
11971
|
+
}, children: [jsxRuntime.jsx("div", { style: {
|
|
11972
|
+
fontSize: "13px",
|
|
11973
|
+
color: "var(--bw-text-muted)",
|
|
11974
|
+
marginBottom: "4px",
|
|
11975
|
+
}, children: t$1("summary.deposit") }), jsxRuntime.jsx("div", { style: {
|
|
11976
|
+
fontSize: "18px",
|
|
11842
11977
|
fontWeight: 700,
|
|
11843
|
-
|
|
11844
|
-
|
|
11845
|
-
|
|
11846
|
-
|
|
11847
|
-
|
|
11848
|
-
|
|
11849
|
-
|
|
11850
|
-
|
|
11851
|
-
|
|
11852
|
-
|
|
11853
|
-
|
|
11854
|
-
|
|
11855
|
-
|
|
11856
|
-
|
|
11857
|
-
padding: "8px 16px",
|
|
11858
|
-
borderRadius: "var(--bw-border-radius)",
|
|
11859
|
-
backgroundColor: "var(--bw-highlight-color)",
|
|
11860
|
-
border: "1px solid var(--bw-highlight-color)",
|
|
11861
|
-
cursor: "pointer",
|
|
11862
|
-
transition: "all 0.2s ease",
|
|
11863
|
-
marginBottom: "4px",
|
|
11864
|
-
fontFamily: "var(--bw-font-family)",
|
|
11865
|
-
boxShadow: "0 2px 8px 0 var(--bw-highlight-color)",
|
|
11866
|
-
}, children: t$1("booking.addParticipant", { number: watchedParticipants.length + 1 }) }) })) : (jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.maxSpotsReached", { count: eventDetails.availableSpots }) }))] })] }), jsxRuntime.jsx(VoucherInput, { config: config, orderValue: baseTotal, eventInstanceId: eventDetails?.id, customerEmail: watchedCustomerEmail, onVoucherValidated: handleVoucherValidated, appliedVouchers: appliedVouchers, onRemoveVoucher: handleRemoveVoucher, disabled: !eventDetails }), jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("label", { htmlFor: "booking-comment", style: labelStyles$1, children: t$1("booking.comment") }), jsxRuntime.jsx("textarea", { id: "booking-comment", ...form.register("comment"), placeholder: t$1("booking.commentPlaceholder"), rows: 3, style: {
|
|
11867
|
-
...inputStyles$1,
|
|
11868
|
-
resize: "vertical",
|
|
11869
|
-
minHeight: "80px",
|
|
11870
|
-
} })] }), jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "24px" }, children: [jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1, marginBottom: "16px" }, children: t$1("summary.title") }), jsxRuntime.jsxs("div", { style: { marginTop: "10px", display: "flex", flexDirection: "column", gap: "12px" }, children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("booking.price") }), jsxRuntime.jsxs("div", { style: {
|
|
11871
|
-
color: "var(--bw-text-color)",
|
|
11872
|
-
fontWeight: 500,
|
|
11978
|
+
color: paymentOption === "deposit"
|
|
11979
|
+
? "var(--bw-highlight-color)"
|
|
11980
|
+
: "var(--bw-text-color)",
|
|
11981
|
+
}, children: formatCurrency(depositAmount) })] }), jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("full"), style: {
|
|
11982
|
+
flex: 1,
|
|
11983
|
+
padding: "12px",
|
|
11984
|
+
borderRadius: "var(--bw-border-radius)",
|
|
11985
|
+
border: paymentOption === "full"
|
|
11986
|
+
? "2px solid var(--bw-highlight-color)"
|
|
11987
|
+
: "1px solid var(--bw-border-color)",
|
|
11988
|
+
backgroundColor: paymentOption === "full"
|
|
11989
|
+
? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
|
|
11990
|
+
: "var(--bw-surface-color)",
|
|
11991
|
+
cursor: "pointer",
|
|
11873
11992
|
fontFamily: "var(--bw-font-family)",
|
|
11874
|
-
|
|
11875
|
-
|
|
11876
|
-
|
|
11877
|
-
if (countWithUpsell === 0)
|
|
11878
|
-
return null;
|
|
11879
|
-
const upsellLineTotal = upsell.price * countWithUpsell;
|
|
11880
|
-
return (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center", fontSize: "13px" }, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: ["+ ", upsell.name, " (", countWithUpsell, "\u00D7)"] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-highlight-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(upsellLineTotal) })] }, upsell.id));
|
|
11881
|
-
})] })), appliedVouchers.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.subtotal") }), jsxRuntime.jsx("span", { style: {
|
|
11882
|
-
fontFamily: "var(--bw-font-family)",
|
|
11883
|
-
color: totalDiscount > 0 ? "var(--bw-text-muted)" : "var(--bw-text-muted)",
|
|
11884
|
-
textDecoration: totalDiscount > 0 ? "line-through" : "none",
|
|
11885
|
-
}, children: formatCurrency(baseTotal) })] }), appliedDiscountCode && (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
|
|
11886
|
-
color: "var(--bw-success-color)",
|
|
11887
|
-
fontFamily: "var(--bw-font-family)",
|
|
11888
|
-
fontSize: "14px",
|
|
11889
|
-
}, children: t$1("summary.discount", { code: appliedDiscountCode.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(appliedDiscountCode.discountAmount)] })] })), appliedGiftCards.map((giftCard) => (jsxRuntime.jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxRuntime.jsx("span", { style: {
|
|
11890
|
-
color: "var(--bw-success-color)",
|
|
11891
|
-
fontFamily: "var(--bw-font-family)",
|
|
11892
|
-
fontSize: "14px",
|
|
11893
|
-
}, children: t$1("summary.giftCard", { code: giftCard.code }) }), jsxRuntime.jsxs("span", { style: { color: "var(--bw-success-color)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(giftCard.balanceToUse || giftCard.discountAmount)] })] }, giftCard.code)))] })), jsxRuntime.jsxs("div", { style: {
|
|
11894
|
-
borderTop: "1px solid var(--bw-border-color)",
|
|
11895
|
-
paddingTop: "12px",
|
|
11896
|
-
}, children: [hasDepositOption && (jsxRuntime.jsxs("div", { style: {
|
|
11897
|
-
display: "flex",
|
|
11898
|
-
gap: "8px",
|
|
11899
|
-
marginBottom: "16px",
|
|
11900
|
-
}, children: [jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("deposit"), style: {
|
|
11901
|
-
flex: 1,
|
|
11902
|
-
padding: "12px",
|
|
11903
|
-
borderRadius: "var(--bw-border-radius)",
|
|
11904
|
-
border: paymentOption === "deposit"
|
|
11905
|
-
? "2px solid var(--bw-highlight-color)"
|
|
11906
|
-
: "1px solid var(--bw-border-color)",
|
|
11907
|
-
backgroundColor: paymentOption === "deposit"
|
|
11908
|
-
? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
|
|
11909
|
-
: "var(--bw-surface-color)",
|
|
11910
|
-
cursor: "pointer",
|
|
11911
|
-
fontFamily: "var(--bw-font-family)",
|
|
11912
|
-
transition: "all 0.2s ease",
|
|
11913
|
-
}, children: [jsxRuntime.jsx("div", { style: {
|
|
11914
|
-
fontSize: "13px",
|
|
11915
|
-
color: "var(--bw-text-muted)",
|
|
11916
|
-
marginBottom: "4px",
|
|
11917
|
-
}, children: t$1("summary.deposit") }), jsxRuntime.jsx("div", { style: {
|
|
11918
|
-
fontSize: "18px",
|
|
11919
|
-
fontWeight: 700,
|
|
11920
|
-
color: paymentOption === "deposit"
|
|
11921
|
-
? "var(--bw-highlight-color)"
|
|
11922
|
-
: "var(--bw-text-color)",
|
|
11923
|
-
}, children: formatCurrency(depositAmount) })] }), jsxRuntime.jsxs("button", { type: "button", onClick: () => setPaymentOption("full"), style: {
|
|
11924
|
-
flex: 1,
|
|
11925
|
-
padding: "12px",
|
|
11926
|
-
borderRadius: "var(--bw-border-radius)",
|
|
11927
|
-
border: paymentOption === "full"
|
|
11928
|
-
? "2px solid var(--bw-highlight-color)"
|
|
11929
|
-
: "1px solid var(--bw-border-color)",
|
|
11930
|
-
backgroundColor: paymentOption === "full"
|
|
11931
|
-
? "rgba(var(--bw-highlight-color-rgb, 0, 177, 170), 0.1)"
|
|
11932
|
-
: "var(--bw-surface-color)",
|
|
11933
|
-
cursor: "pointer",
|
|
11934
|
-
fontFamily: "var(--bw-font-family)",
|
|
11935
|
-
transition: "all 0.2s ease",
|
|
11936
|
-
}, children: [jsxRuntime.jsx("div", { style: {
|
|
11937
|
-
fontSize: "13px",
|
|
11938
|
-
color: "var(--bw-text-muted)",
|
|
11939
|
-
marginBottom: "4px",
|
|
11940
|
-
}, children: t$1("summary.payFull") }), jsxRuntime.jsx("div", { style: {
|
|
11941
|
-
fontSize: "18px",
|
|
11942
|
-
fontWeight: 700,
|
|
11943
|
-
color: paymentOption === "full"
|
|
11944
|
-
? "var(--bw-highlight-color)"
|
|
11945
|
-
: "var(--bw-text-color)",
|
|
11946
|
-
}, children: formatCurrency(totalAmount) })] })] })), hasDepositOption && paymentOption === "deposit" && (jsxRuntime.jsxs("div", { style: {
|
|
11947
|
-
display: "flex",
|
|
11948
|
-
justifyContent: "space-between",
|
|
11949
|
-
alignItems: "center",
|
|
11950
|
-
fontSize: "14px",
|
|
11951
|
-
marginBottom: "8px",
|
|
11952
|
-
}, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)" }, children: t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
|
|
11993
|
+
transition: "all 0.2s ease",
|
|
11994
|
+
}, children: [jsxRuntime.jsx("div", { style: {
|
|
11995
|
+
fontSize: "13px",
|
|
11953
11996
|
color: "var(--bw-text-muted)",
|
|
11954
|
-
|
|
11955
|
-
|
|
11956
|
-
|
|
11957
|
-
display: "flex",
|
|
11958
|
-
justifyContent: "space-between",
|
|
11959
|
-
alignItems: "center",
|
|
11960
|
-
fontSize: "18px",
|
|
11961
|
-
fontWeight: 600,
|
|
11962
|
-
}, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: hasDepositOption && paymentOption === "deposit"
|
|
11963
|
-
? t$1("summary.payToday")
|
|
11964
|
-
: t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
|
|
11965
|
-
color: "var(--bw-highlight-color)",
|
|
11966
|
-
fontFamily: "var(--bw-font-family)",
|
|
11997
|
+
marginBottom: "4px",
|
|
11998
|
+
}, children: t$1("summary.payFull") }), jsxRuntime.jsx("div", { style: {
|
|
11999
|
+
fontSize: "18px",
|
|
11967
12000
|
fontWeight: 700,
|
|
11968
|
-
|
|
11969
|
-
|
|
11970
|
-
|
|
12001
|
+
color: paymentOption === "full"
|
|
12002
|
+
? "var(--bw-highlight-color)"
|
|
12003
|
+
: "var(--bw-text-color)",
|
|
12004
|
+
}, children: formatCurrency(totalAmount) })] })] })), jsxRuntime.jsxs("div", { style: {
|
|
12005
|
+
display: "flex",
|
|
12006
|
+
justifyContent: "space-between",
|
|
12007
|
+
alignItems: "center",
|
|
12008
|
+
fontSize: "18px",
|
|
12009
|
+
fontWeight: 600,
|
|
12010
|
+
}, children: [jsxRuntime.jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: hasDepositOption && paymentOption === "deposit"
|
|
12011
|
+
? t$1("summary.payToday")
|
|
12012
|
+
: t$1("summary.totalAmount") }), jsxRuntime.jsx("span", { style: {
|
|
12013
|
+
color: "var(--bw-highlight-color)",
|
|
11971
12014
|
fontFamily: "var(--bw-font-family)",
|
|
11972
|
-
|
|
11973
|
-
|
|
11974
|
-
|
|
11975
|
-
|
|
11976
|
-
if (!isReadyForPayment()) {
|
|
11977
|
-
const participantsWithNames = watchedParticipants.filter((p) => p.name?.trim()).length;
|
|
11978
|
-
const totalParticipantRows = watchedParticipants.length;
|
|
11979
|
-
const participantsWithoutNames = totalParticipantRows - participantsWithNames;
|
|
11980
|
-
const missing = [];
|
|
11981
|
-
if (participantFieldsConfig.name.required) {
|
|
11982
|
-
if (participantsWithNames === 0) {
|
|
11983
|
-
missing.push(t$1("payment.needParticipant"));
|
|
11984
|
-
}
|
|
11985
|
-
else if (participantsWithoutNames > 0) {
|
|
11986
|
-
missing.push(t$1("payment.needAllNames", { count: totalParticipantRows }));
|
|
11987
|
-
}
|
|
11988
|
-
}
|
|
11989
|
-
if (participantsWithNames > (eventDetails?.availableSpots || 0)) {
|
|
11990
|
-
missing.push(t$1("payment.reduceParticipants", { count: eventDetails?.availableSpots || 0 }));
|
|
11991
|
-
}
|
|
11992
|
-
if (!watchedCustomerName || watchedCustomerName.trim().length < 2 || customerNameError) {
|
|
11993
|
-
missing.push(t$1("payment.needValidName"));
|
|
11994
|
-
}
|
|
11995
|
-
if (!watchedCustomerEmail || watchedCustomerEmail.trim().length === 0 || customerEmailError) {
|
|
11996
|
-
missing.push(t$1("payment.needValidEmail"));
|
|
11997
|
-
}
|
|
11998
|
-
if (!watchedAcceptTerms) {
|
|
11999
|
-
missing.push(t$1("payment.needAcceptTerms"));
|
|
12000
|
-
}
|
|
12001
|
-
const message = missing.length > 0
|
|
12002
|
-
? t$1("payment.missingFields", { fields: missing.join(", ") })
|
|
12003
|
-
: t$1("payment.fillRequired");
|
|
12004
|
-
return (jsxRuntime.jsx("div", { style: {
|
|
12005
|
-
...cardStyles$1,
|
|
12006
|
-
border: "1px solid var(--bw-warning-color)",
|
|
12007
|
-
color: "var(--bw-warning-color)",
|
|
12015
|
+
fontWeight: 700,
|
|
12016
|
+
}, children: formatCurrency(paymentAmount) })] }), hasDepositOption && paymentOption === "deposit" && (jsxRuntime.jsx("div", { style: {
|
|
12017
|
+
fontSize: "12px",
|
|
12018
|
+
color: "var(--bw-text-muted)",
|
|
12008
12019
|
fontFamily: "var(--bw-font-family)",
|
|
12009
|
-
|
|
12010
|
-
|
|
12011
|
-
|
|
12012
|
-
const discountCodeProp = appliedDiscountCode
|
|
12013
|
-
? {
|
|
12014
|
-
id: appliedDiscountCode.id,
|
|
12015
|
-
code: appliedDiscountCode.code,
|
|
12016
|
-
description: appliedDiscountCode.description || undefined,
|
|
12017
|
-
type: appliedDiscountCode.discountType || "percentage",
|
|
12018
|
-
value: appliedDiscountCode.discountValue || 0,
|
|
12019
|
-
discountAmount: appliedDiscountCode.discountAmount,
|
|
12020
|
-
newTotal: appliedDiscountCode.newTotal,
|
|
12021
|
-
}
|
|
12022
|
-
: null;
|
|
12023
|
-
if (systemConfig?.paymentProvider === "mollie") {
|
|
12024
|
-
return (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(MolliePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, upsellSelections: aggregatedUpsellSelections(), mollieProfileId: systemConfig?.mollieProfileId, mollieTestmode: systemConfig?.mollieTestmode })] }));
|
|
12025
|
-
}
|
|
12026
|
-
return (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(StripePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, systemConfig: systemConfig ?? null, stripePromise: stripePromise, stripeAppearance: stripeAppearance, upsellSelections: aggregatedUpsellSelections() })] }));
|
|
12027
|
-
})() })] })] })] }) }));
|
|
12020
|
+
marginTop: "8px",
|
|
12021
|
+
textAlign: "right",
|
|
12022
|
+
}, children: t$1("summary.remainingOnSite", { amount: formatCurrency(totalAmount - depositAmount) }) }))] })] })] }), !hasPaymentProvider && (jsxRuntime.jsx("div", { style: cardStyles$1, children: jsxRuntime.jsx("p", { style: { ...errorTextStyles$1, margin: 0 }, children: t$1("booking.paymentUnavailable") }) })), hasPaymentProvider && (systemConfig?.paymentProvider === "mollie" ? (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(MolliePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, upsellSelections: aggregatedUpsellSelections(), mollieProfileId: systemConfig?.mollieProfileId, mollieTestmode: systemConfig?.mollieTestmode })] })) : (jsxRuntime.jsxs("div", { style: cardStyles$1, children: [jsxRuntime.jsx("h2", { style: { ...sectionHeaderStyles$1 }, children: t$1("summary.payment") }), jsxRuntime.jsx(StripePaymentForm, { config: config, eventDetails: eventDetails, formData: paymentFormData, totalAmount: paymentAmount, discountCode: discountCodeProp, giftCards: appliedGiftCards, onSuccess: onSuccess, onError: onError, systemConfig: systemConfig ?? null, stripePromise: stripePromise, stripeAppearance: stripeAppearance, upsellSelections: aggregatedUpsellSelections() })] })))] }))] }) }));
|
|
12028
12023
|
}
|
|
12029
12024
|
|
|
12030
12025
|
/**
|
|
@@ -15191,12 +15186,11 @@ function PromoDialog({ config, onClose, onCtaClick }) {
|
|
|
15191
15186
|
return ReactDOM.createPortal(dialogContent, portalContainer);
|
|
15192
15187
|
}
|
|
15193
15188
|
|
|
15194
|
-
// Upsell card styles
|
|
15195
15189
|
const cardBaseStyles = {
|
|
15196
15190
|
position: "relative",
|
|
15197
15191
|
display: "flex",
|
|
15198
15192
|
flexDirection: "column",
|
|
15199
|
-
padding: "
|
|
15193
|
+
padding: "12px",
|
|
15200
15194
|
backgroundColor: "var(--bw-surface-color)",
|
|
15201
15195
|
borderWidth: "2px",
|
|
15202
15196
|
borderStyle: "solid",
|
|
@@ -15216,19 +15210,13 @@ const cardDisabledStyles = {
|
|
|
15216
15210
|
opacity: 0.6,
|
|
15217
15211
|
cursor: "not-allowed",
|
|
15218
15212
|
};
|
|
15219
|
-
const checkboxContainerStyles = {
|
|
15220
|
-
position: "absolute",
|
|
15221
|
-
bottom: "12px",
|
|
15222
|
-
left: "12px",
|
|
15223
|
-
zIndex: 1,
|
|
15224
|
-
};
|
|
15225
15213
|
const checkboxInnerStyles = {
|
|
15226
|
-
width: "
|
|
15227
|
-
height: "
|
|
15214
|
+
width: "48px",
|
|
15215
|
+
height: "48px",
|
|
15228
15216
|
borderWidth: "2px",
|
|
15229
15217
|
borderStyle: "solid",
|
|
15230
15218
|
borderColor: "var(--bw-border-color)",
|
|
15231
|
-
borderRadius: "
|
|
15219
|
+
borderRadius: "12px",
|
|
15232
15220
|
display: "flex",
|
|
15233
15221
|
alignItems: "center",
|
|
15234
15222
|
justifyContent: "center",
|
|
@@ -15240,13 +15228,13 @@ const checkboxSelectedStyles = {
|
|
|
15240
15228
|
borderColor: "var(--bw-highlight-color)",
|
|
15241
15229
|
backgroundColor: "var(--bw-highlight-color)",
|
|
15242
15230
|
};
|
|
15243
|
-
const
|
|
15244
|
-
width: "
|
|
15245
|
-
height: "
|
|
15246
|
-
marginBottom: "12px",
|
|
15231
|
+
const previewImageContainerStyles = {
|
|
15232
|
+
width: "56px",
|
|
15233
|
+
height: "56px",
|
|
15247
15234
|
borderRadius: "calc(var(--bw-border-radius) - 4px)",
|
|
15248
15235
|
overflow: "hidden",
|
|
15249
15236
|
backgroundColor: "var(--bw-background-color)",
|
|
15237
|
+
flexShrink: 0,
|
|
15250
15238
|
};
|
|
15251
15239
|
const imageStyles = {
|
|
15252
15240
|
width: "100%",
|
|
@@ -15261,23 +15249,53 @@ const imagePlaceholderStyles = {
|
|
|
15261
15249
|
justifyContent: "center",
|
|
15262
15250
|
color: "var(--bw-text-muted)",
|
|
15263
15251
|
};
|
|
15264
|
-
const
|
|
15252
|
+
const previewNameStyles = {
|
|
15265
15253
|
fontSize: "16px",
|
|
15266
15254
|
fontWeight: 600,
|
|
15267
15255
|
color: "var(--bw-text-color)",
|
|
15268
|
-
margin:
|
|
15269
|
-
|
|
15256
|
+
margin: 0,
|
|
15257
|
+
fontFamily: "var(--bw-font-family)",
|
|
15258
|
+
};
|
|
15259
|
+
const previewHeaderStyles = {
|
|
15260
|
+
display: "flex",
|
|
15261
|
+
alignItems: "center",
|
|
15262
|
+
gap: "10px",
|
|
15263
|
+
};
|
|
15264
|
+
const previewPriceStyles = {
|
|
15265
|
+
fontSize: "13px",
|
|
15266
|
+
color: "var(--bw-text-muted)",
|
|
15267
|
+
marginTop: "2px",
|
|
15270
15268
|
fontFamily: "var(--bw-font-family)",
|
|
15271
15269
|
};
|
|
15270
|
+
const headerRightStyles = {
|
|
15271
|
+
marginLeft: "auto",
|
|
15272
|
+
display: "flex",
|
|
15273
|
+
alignItems: "center",
|
|
15274
|
+
gap: "8px",
|
|
15275
|
+
};
|
|
15276
|
+
const chevronStyles = {
|
|
15277
|
+
fontSize: "12px",
|
|
15278
|
+
color: "var(--bw-text-muted)",
|
|
15279
|
+
transition: "transform 0.2s ease",
|
|
15280
|
+
};
|
|
15281
|
+
const expandedContentStyles = {
|
|
15282
|
+
marginTop: "12px",
|
|
15283
|
+
paddingTop: "12px",
|
|
15284
|
+
borderTop: "1px solid var(--bw-border-color)",
|
|
15285
|
+
};
|
|
15286
|
+
const expandedImageContainerStyles = {
|
|
15287
|
+
width: "100%",
|
|
15288
|
+
height: "180px",
|
|
15289
|
+
marginBottom: "12px",
|
|
15290
|
+
borderRadius: "calc(var(--bw-border-radius) - 4px)",
|
|
15291
|
+
overflow: "hidden",
|
|
15292
|
+
backgroundColor: "var(--bw-background-color)",
|
|
15293
|
+
};
|
|
15272
15294
|
const descriptionStyles = {
|
|
15273
15295
|
fontSize: "13px",
|
|
15274
15296
|
color: "var(--bw-text-muted)",
|
|
15275
15297
|
margin: "0 0 10px 0",
|
|
15276
15298
|
lineHeight: 1.4,
|
|
15277
|
-
display: "-webkit-box",
|
|
15278
|
-
WebkitLineClamp: 5,
|
|
15279
|
-
WebkitBoxOrient: "vertical",
|
|
15280
|
-
overflow: "hidden",
|
|
15281
15299
|
fontFamily: "var(--bw-font-family)",
|
|
15282
15300
|
};
|
|
15283
15301
|
const itemsContainerStyles = {
|
|
@@ -15359,6 +15377,8 @@ function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
|
|
|
15359
15377
|
const { locale } = useLocale();
|
|
15360
15378
|
const totalPrice = upsell.price * participantCount;
|
|
15361
15379
|
const isDisabled = !upsell.available;
|
|
15380
|
+
const [isExpanded, setIsExpanded] = React.useState(false);
|
|
15381
|
+
const hasSavings = (upsell.savingsPercent ?? 0) > 0;
|
|
15362
15382
|
const getCardStyles = () => {
|
|
15363
15383
|
if (isDisabled)
|
|
15364
15384
|
return cardDisabledStyles;
|
|
@@ -15366,16 +15386,22 @@ function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
|
|
|
15366
15386
|
return cardSelectedStyles;
|
|
15367
15387
|
return cardBaseStyles;
|
|
15368
15388
|
};
|
|
15369
|
-
|
|
15389
|
+
const toggleExpanded = () => {
|
|
15390
|
+
setIsExpanded((current) => !current);
|
|
15391
|
+
};
|
|
15392
|
+
return (jsxRuntime.jsxs("div", { style: getCardStyles(), onClick: !isDisabled ? toggleExpanded : undefined, role: "button", "aria-expanded": isExpanded, tabIndex: isDisabled ? -1 : 0, onKeyDown: (e) => {
|
|
15370
15393
|
if (!isDisabled && (e.key === "Enter" || e.key === " ")) {
|
|
15371
15394
|
e.preventDefault();
|
|
15372
|
-
|
|
15395
|
+
toggleExpanded();
|
|
15373
15396
|
}
|
|
15374
|
-
}, children: [jsxRuntime.
|
|
15397
|
+
}, children: [jsxRuntime.jsxs("div", { style: previewHeaderStyles, children: [jsxRuntime.jsx("div", { style: previewImageContainerStyles, children: upsell.image ? (jsxRuntime.jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsxRuntime.jsx("div", { style: imagePlaceholderStyles, children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "32px", height: "32px", opacity: 0.4 }, children: jsxRuntime.jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), jsxRuntime.jsxs("div", { style: { minWidth: 0 }, children: [jsxRuntime.jsx("h4", { style: previewNameStyles, children: upsell.name }), jsxRuntime.jsxs("div", { style: previewPriceStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), hasSavings && (jsxRuntime.jsx("div", { style: { ...previewPriceStyles, color: "var(--bw-highlight-color)" }, children: t("upsells.savePercent", { percent: upsell.savingsPercent ?? 0 }) }))] }), jsxRuntime.jsxs("div", { style: headerRightStyles, children: [jsxRuntime.jsx("button", { type: "button", onClick: (event) => {
|
|
15398
|
+
event.stopPropagation();
|
|
15399
|
+
onSelect();
|
|
15400
|
+
}, "aria-label": t("common.extras"), style: { background: "transparent", border: "none", cursor: "pointer", padding: 0 }, disabled: isDisabled, children: jsxRuntime.jsx("div", { style: isSelected ? checkboxSelectedStyles : checkboxInnerStyles, children: isSelected && (jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "white", strokeWidth: "3", strokeLinecap: "round", strokeLinejoin: "round", style: { width: "32px", height: "32px" }, children: jsxRuntime.jsx("polyline", { points: "20 6 9 17 4 12" }) })) }) }), jsxRuntime.jsx("span", { style: { ...chevronStyles, transform: isExpanded ? "rotate(180deg)" : "rotate(0deg)" }, children: "\u25BC" })] })] }), isExpanded && (jsxRuntime.jsxs("div", { style: expandedContentStyles, children: [jsxRuntime.jsx("div", { style: expandedImageContainerStyles, children: upsell.image ? (jsxRuntime.jsx("img", { src: upsell.image, alt: upsell.name, style: imageStyles })) : (jsxRuntime.jsx("div", { style: imagePlaceholderStyles, children: jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", style: { width: "40px", height: "40px", opacity: 0.4 }, children: jsxRuntime.jsx("path", { d: "M20 7l-8-4-8 4m16 0l-8 4m8-4v10l-8 4m0-10L4 7m8 4v10M4 7v10l8 4" }) }) })) }), upsell.description && (jsxRuntime.jsx("p", { style: descriptionStyles, children: upsell.description })), upsell.items.length > 0 && (jsxRuntime.jsx("div", { style: itemsContainerStyles, children: upsell.items.map((item, index) => (jsxRuntime.jsxs("span", { style: itemStyles, children: [item.type === "product" ? "📦" : "🎫", " ", item.name, item.quantity > 1 && ` (${item.quantity}x)`] }, index))) })), upsell.suggestedEventInstance && (jsxRuntime.jsxs("div", { style: eventInfoStyles, children: [jsxRuntime.jsxs("span", { style: { color: "var(--bw-text-color)", fontWeight: 500 }, children: ["\uD83D\uDCC5 ", new Date(upsell.suggestedEventInstance.date).toLocaleDateString(locale === "de" ? "de-DE" : locale === "en" ? "en-US" : locale === "es" ? "es-ES" : locale === "sv" ? "sv-SE" : "pt-PT", {
|
|
15375
15401
|
weekday: "short",
|
|
15376
15402
|
day: "numeric",
|
|
15377
15403
|
month: "short",
|
|
15378
|
-
})] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)" }, children: t("upsells.spotsFree", { count: upsell.suggestedEventInstance.availableSpots }) })] }))
|
|
15404
|
+
})] }), jsxRuntime.jsx("span", { style: { color: "var(--bw-text-muted)" }, children: t("upsells.spotsFree", { count: upsell.suggestedEventInstance.availableSpots }) })] })), jsxRuntime.jsxs("div", { style: priceContainerStyles, children: [jsxRuntime.jsxs("span", { style: pricePerPersonStyles, children: [formatCurrency(upsell.price), "/", t("common.perPerson")] }), participantCount > 1 && (jsxRuntime.jsxs("span", { style: priceTotalStyles, children: ["= ", formatCurrency(totalPrice)] })), hasSavings && (jsxRuntime.jsx("span", { style: priceTotalStyles, children: t("upsells.savePercent", { percent: upsell.savingsPercent ?? 0 }) }))] })] })), isDisabled && (jsxRuntime.jsx("div", { style: unavailableOverlayStyles, children: jsxRuntime.jsx("span", { children: upsell.unavailableReason
|
|
15379
15405
|
? formatUnavailableReason(upsell.unavailableReason, t)
|
|
15380
15406
|
: t("upsells.notAvailable") }) }))] }));
|
|
15381
15407
|
}
|
|
@@ -15394,20 +15420,9 @@ function UpsellsStep({ upsells, selectedUpsells, participantCount, isLoading, is
|
|
|
15394
15420
|
}
|
|
15395
15421
|
};
|
|
15396
15422
|
const isSelected = (upsellId) => selectedUpsells.some((s) => s.upsellPackageId === upsellId);
|
|
15397
|
-
// Calculate total for selected upsells
|
|
15398
|
-
const calculateTotal = () => {
|
|
15399
|
-
return selectedUpsells.reduce((total, selection) => {
|
|
15400
|
-
const upsell = upsells.find((u) => u.id === selection.upsellPackageId);
|
|
15401
|
-
if (upsell) {
|
|
15402
|
-
return total + upsell.price * selection.quantity;
|
|
15403
|
-
}
|
|
15404
|
-
return total;
|
|
15405
|
-
}, 0);
|
|
15406
|
-
};
|
|
15407
|
-
const selectedTotal = calculateTotal();
|
|
15408
15423
|
const selectedCount = selectedUpsells.length;
|
|
15409
15424
|
const footerContent = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("button", { type: "button", onClick: onBack, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), className: buttonClassName, children: t("common.back") }), jsxRuntime.jsx("button", { type: "button", onClick: onContinue, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), className: buttonClassName, children: selectedCount === 0 ? t("button.continueWithout") : t("button.continue") })] }));
|
|
15410
|
-
return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: onClose, title: t("upsells.title"), footer: footerContent, children: jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", padding: "16px 16px" }, children: [isLoading && (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "12px", padding: "40px 20px", ...textStyles.muted }, children: [spinner(), jsxRuntime.jsx("span", { children: t("upsells.loading") })] })), !isLoading && upsells.length === 0 && (jsxRuntime.jsx("div", { style: { textAlign: "center", padding: "40px 20px", ...textStyles.muted }, children: jsxRuntime.jsx("p", { children: t("upsells.noExtras") }) })), !isLoading && upsells.length > 0 && (jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", flex: 1, overflowY: "auto", paddingBottom: "16px" }, children: upsells.map((upsell) => (jsxRuntime.jsx(UpsellCard, { upsell: upsell, isSelected: isSelected(upsell.id), participantCount: participantCount, onSelect: () => selectUpsell(upsell.id) }, upsell.id))) })), selectedCount > 0 && (jsxRuntime.
|
|
15425
|
+
return (jsxRuntime.jsx(Sidebar, { isOpen: isOpen, onClose: onClose, title: t("upsells.title"), footer: footerContent, children: jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", padding: "16px 16px" }, children: [isLoading && (jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "12px", padding: "40px 20px", ...textStyles.muted }, children: [spinner(), jsxRuntime.jsx("span", { children: t("upsells.loading") })] })), !isLoading && upsells.length === 0 && (jsxRuntime.jsx("div", { style: { textAlign: "center", padding: "40px 20px", ...textStyles.muted }, children: jsxRuntime.jsx("p", { children: t("upsells.noExtras") }) })), !isLoading && upsells.length > 0 && (jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", flex: 1, overflowY: "auto", paddingBottom: "16px" }, children: upsells.map((upsell) => (jsxRuntime.jsx(UpsellCard, { upsell: upsell, isSelected: isSelected(upsell.id), participantCount: participantCount, onSelect: () => selectUpsell(upsell.id) }, upsell.id))) })), selectedCount > 0 && (jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", marginTop: "16px", paddingBottom: "16px", paddingTop: "16px", borderTop: "1px solid var(--bw-border-color)", fontSize: "14px" }, children: jsxRuntime.jsx("span", { style: textStyles.muted, children: selectedCount === 1 ? t("upsells.selected", { count: selectedCount }) : t("upsells.selectedPlural", { count: selectedCount }) }) }))] }) }));
|
|
15411
15426
|
}
|
|
15412
15427
|
|
|
15413
15428
|
/**
|
|
@@ -15545,6 +15560,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
15545
15560
|
// Upsells state
|
|
15546
15561
|
const [upsells, setUpsells] = React.useState([]);
|
|
15547
15562
|
const [selectedUpsells, setSelectedUpsells] = React.useState([]);
|
|
15563
|
+
const [bookingPersistedState, setBookingPersistedState] = React.useState(null);
|
|
15548
15564
|
const [isLoadingUpsells, setIsLoadingUpsells] = React.useState(false);
|
|
15549
15565
|
const [tempParticipantCount, setTempParticipantCount] = React.useState(1); // Used during upsell step
|
|
15550
15566
|
// State for upcoming events (next-events view mode)
|
|
@@ -16199,6 +16215,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16199
16215
|
const handleEventInstanceSelect = async (eventInstance) => {
|
|
16200
16216
|
trackEvent("event_instance_selected", { eventInstanceId: eventInstance.id, eventInstanceName: eventInstance.name });
|
|
16201
16217
|
setSelectedEventInstance(eventInstance);
|
|
16218
|
+
setBookingPersistedState(null);
|
|
16202
16219
|
bookingReturnStep.current = "eventInstances";
|
|
16203
16220
|
// Set default participant count for upsell calculations
|
|
16204
16221
|
const defaultParticipantCount = 1;
|
|
@@ -16252,6 +16269,21 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16252
16269
|
setCurrentStep(bookingReturnStep.current);
|
|
16253
16270
|
setSelectedEventInstance(null);
|
|
16254
16271
|
setEventDetails(null);
|
|
16272
|
+
setBookingPersistedState(null);
|
|
16273
|
+
};
|
|
16274
|
+
const handleBackFromBooking = () => {
|
|
16275
|
+
if (upsells.length > 0) {
|
|
16276
|
+
setCurrentStep("upsells");
|
|
16277
|
+
return;
|
|
16278
|
+
}
|
|
16279
|
+
if (isDirectInstanceMode) {
|
|
16280
|
+
setCurrentStep("eventTypes");
|
|
16281
|
+
setSidebarOpen(false);
|
|
16282
|
+
setEventDetails(null);
|
|
16283
|
+
setBookingPersistedState(null);
|
|
16284
|
+
return;
|
|
16285
|
+
}
|
|
16286
|
+
handleBackToEventInstances();
|
|
16255
16287
|
};
|
|
16256
16288
|
const handleBookingSuccess = (result) => {
|
|
16257
16289
|
trackEvent("booking_completed", { paymentIntentId: result.paymentIntent?.id });
|
|
@@ -16259,6 +16291,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16259
16291
|
setSuccessPaymentId(result.paymentIntent.id);
|
|
16260
16292
|
setSidebarOpen(false);
|
|
16261
16293
|
setShouldRenderBookingForm(false);
|
|
16294
|
+
setBookingPersistedState(null);
|
|
16262
16295
|
config.onSuccess?.(result);
|
|
16263
16296
|
};
|
|
16264
16297
|
const handleBookingError = (errorMessage) => {
|
|
@@ -16327,6 +16360,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16327
16360
|
? (eventTypes.find((et) => et.id === eventTypeId) ?? selectedEventType)
|
|
16328
16361
|
: selectedEventType;
|
|
16329
16362
|
if (resolvedEventType && resolvedEventType !== selectedEventType) {
|
|
16363
|
+
trackEvent("event_type_selected", { eventTypeId: resolvedEventType.id, eventTypeName: resolvedEventType.name });
|
|
16330
16364
|
setSelectedEventType(resolvedEventType);
|
|
16331
16365
|
}
|
|
16332
16366
|
// Check if this is coming from a card preview (eventTypeId was provided)
|
|
@@ -16380,7 +16414,9 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16380
16414
|
}
|
|
16381
16415
|
: null;
|
|
16382
16416
|
if (eventInstance) {
|
|
16417
|
+
trackEvent("event_instance_selected", { eventInstanceId: eventInstance.id, eventInstanceName: eventInstance.name });
|
|
16383
16418
|
setSelectedEventInstance(eventInstance);
|
|
16419
|
+
setBookingPersistedState(null);
|
|
16384
16420
|
}
|
|
16385
16421
|
setError(null);
|
|
16386
16422
|
// Check for upsells before going to booking (same as handleEventInstanceSelect)
|
|
@@ -16544,19 +16580,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16544
16580
|
}
|
|
16545
16581
|
// Main view based on view mode
|
|
16546
16582
|
if (viewMode === "next-events" && showingPreview) {
|
|
16547
|
-
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError,
|
|
16548
|
-
setCurrentStep("eventTypes");
|
|
16549
|
-
setShowingPreview(true);
|
|
16550
|
-
setEventDetails(null);
|
|
16551
|
-
}, onBackToEventTypes: () => {
|
|
16552
|
-
setCurrentStep("eventTypes");
|
|
16553
|
-
setShowingPreview(true);
|
|
16554
|
-
setEventDetails(null);
|
|
16555
|
-
}, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => {
|
|
16556
|
-
setCurrentStep("eventTypes");
|
|
16557
|
-
setShowingPreview(true);
|
|
16558
|
-
setEventDetails(null);
|
|
16559
|
-
}, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
16583
|
+
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(NextEventsPreview, { events: upcomingEvents, onEventSelect: handleUpcomingEventSelect, onShowAll: handleShowAllEvents, showAllButtonText: nextEventsSettings.showAllButtonText, showAllButton: nextEventsSettings.showAllButton, isLoadingEventDetails: isLoadingEventDetails, isLoadingShowAll: isLoadingShowAll, isLoading: isLoading }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
16560
16584
|
setIsSuccess(false);
|
|
16561
16585
|
setCurrentStep("eventTypes");
|
|
16562
16586
|
setShowingPreview(true);
|
|
@@ -16566,6 +16590,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16566
16590
|
setShouldRenderBookingForm(false);
|
|
16567
16591
|
setSelectedUpsells([]);
|
|
16568
16592
|
setUpsells([]);
|
|
16593
|
+
setBookingPersistedState(null);
|
|
16569
16594
|
const url = new URL(window.location.href);
|
|
16570
16595
|
url.searchParams.delete("payment_intent");
|
|
16571
16596
|
url.searchParams.delete("payment_intent_client_secret");
|
|
@@ -16576,19 +16601,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16576
16601
|
}, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsxRuntime.jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
|
|
16577
16602
|
}
|
|
16578
16603
|
if (viewMode === "specials" && showingPreview) {
|
|
16579
|
-
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(SpecialsView, { specials: specials, onEventSelect: handleUpcomingEventSelect, isLoading: isLoadingSpecials, showSavingsAmount: config.specialsSettings?.showSavingsAmount ?? true, showSavingsPercent: config.specialsSettings?.showSavingsPercent ?? false, emptyStateText: config.specialsSettings?.emptyStateText }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError,
|
|
16580
|
-
setCurrentStep("eventTypes");
|
|
16581
|
-
setShowingPreview(true);
|
|
16582
|
-
setEventDetails(null);
|
|
16583
|
-
}, onBackToEventTypes: () => {
|
|
16584
|
-
setCurrentStep("eventTypes");
|
|
16585
|
-
setShowingPreview(true);
|
|
16586
|
-
setEventDetails(null);
|
|
16587
|
-
}, selectedEventType: selectedEventType, selectedEventInstance: selectedEventInstance, isOpen: currentStep === "booking" && !!eventDetails, onClose: () => {
|
|
16588
|
-
setCurrentStep("eventTypes");
|
|
16589
|
-
setShowingPreview(true);
|
|
16590
|
-
setEventDetails(null);
|
|
16591
|
-
}, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
16604
|
+
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [jsxRuntime.jsx(SpecialsView, { specials: specials, onEventSelect: handleUpcomingEventSelect, isLoading: isLoadingSpecials, showSavingsAmount: config.specialsSettings?.showSavingsAmount ?? true, showSavingsPercent: config.specialsSettings?.showSavingsPercent ?? false, emptyStateText: config.specialsSettings?.emptyStateText }), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
16592
16605
|
setIsSuccess(false);
|
|
16593
16606
|
setCurrentStep("eventTypes");
|
|
16594
16607
|
setShowingPreview(true);
|
|
@@ -16598,6 +16611,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16598
16611
|
setShouldRenderBookingForm(false);
|
|
16599
16612
|
setSelectedUpsells([]);
|
|
16600
16613
|
setUpsells([]);
|
|
16614
|
+
setBookingPersistedState(null);
|
|
16601
16615
|
}, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsxRuntime.jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
|
|
16602
16616
|
}
|
|
16603
16617
|
if (viewMode === "next-events" && !showingPreview && currentStep === "eventInstances") {
|
|
@@ -16650,7 +16664,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16650
16664
|
setShouldRenderInstanceSelection(true);
|
|
16651
16665
|
}
|
|
16652
16666
|
}, children: config.buttonText ||
|
|
16653
|
-
(isDirectInstanceMode ? t("button.bookNow") : t("button.selectDate")) }), shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError,
|
|
16667
|
+
(isDirectInstanceMode ? t("button.bookNow") : t("button.selectDate")) }), shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
16654
16668
|
setIsSuccess(false);
|
|
16655
16669
|
setCurrentStep("eventTypes");
|
|
16656
16670
|
setSidebarOpen(false);
|
|
@@ -16682,32 +16696,36 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16682
16696
|
// Determine the correct back handlers based on view mode
|
|
16683
16697
|
const getBackHandlers = () => {
|
|
16684
16698
|
if (viewMode === "next-events") {
|
|
16685
|
-
|
|
16686
|
-
|
|
16687
|
-
setCurrentStep("
|
|
16699
|
+
const backFromBooking = () => {
|
|
16700
|
+
if (upsells.length > 0) {
|
|
16701
|
+
setCurrentStep("upsells");
|
|
16688
16702
|
setShowingPreview(false);
|
|
16689
|
-
|
|
16690
|
-
}
|
|
16703
|
+
return;
|
|
16704
|
+
}
|
|
16705
|
+
setCurrentStep("eventInstances");
|
|
16706
|
+
setShowingPreview(false);
|
|
16707
|
+
setEventDetails(null);
|
|
16708
|
+
setBookingPersistedState(null);
|
|
16709
|
+
};
|
|
16710
|
+
return {
|
|
16711
|
+
onBackToEventInstances: backFromBooking,
|
|
16691
16712
|
onBackToEventTypes: () => {
|
|
16692
16713
|
setShowingPreview(true);
|
|
16693
16714
|
setCurrentStep("eventTypes");
|
|
16694
16715
|
setEventDetails(null);
|
|
16716
|
+
setBookingPersistedState(null);
|
|
16695
16717
|
},
|
|
16696
|
-
onClose:
|
|
16697
|
-
setCurrentStep("eventInstances");
|
|
16698
|
-
setShowingPreview(false);
|
|
16699
|
-
setEventDetails(null);
|
|
16700
|
-
},
|
|
16718
|
+
onClose: backFromBooking,
|
|
16701
16719
|
};
|
|
16702
16720
|
}
|
|
16703
16721
|
return {
|
|
16704
|
-
onBackToEventInstances:
|
|
16722
|
+
onBackToEventInstances: handleBackFromBooking,
|
|
16705
16723
|
onBackToEventTypes: handleBackToEventTypes,
|
|
16706
|
-
onClose:
|
|
16724
|
+
onClose: handleBackFromBooking,
|
|
16707
16725
|
};
|
|
16708
16726
|
};
|
|
16709
16727
|
const backHandlers = getBackHandlers();
|
|
16710
|
-
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError,
|
|
16728
|
+
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails })), shouldRenderUpsells && (jsxRuntime.jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsxRuntime.jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: backHandlers.onClose, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess && !voucherPurchaseResult, onClose: () => {
|
|
16711
16729
|
setIsSuccess(false);
|
|
16712
16730
|
setCurrentStep("eventTypes");
|
|
16713
16731
|
setSuccessPaymentId(null);
|