@bigz-app/booking-widget 1.1.5 → 1.1.6
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 +47 -17
- package/dist/booking-widget.js.map +1 -1
- package/dist/components/UniversalBookingWidget.d.ts.map +1 -1
- package/dist/components/booking/BookingForm.d.ts +2 -0
- package/dist/components/booking/BookingForm.d.ts.map +1 -1
- package/dist/components/booking/BookingSuccessModal.d.ts.map +1 -1
- package/dist/components/upsells/UpsellCard.d.ts +3 -2
- package/dist/components/upsells/UpsellCard.d.ts.map +1 -1
- package/dist/components/upsells/UpsellsStep.d.ts +4 -1
- package/dist/components/upsells/UpsellsStep.d.ts.map +1 -1
- package/dist/components/upsells/index.d.ts +1 -1
- package/dist/components/upsells/index.d.ts.map +1 -1
- package/dist/i18n/i18n-context.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 +47 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +47 -17
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -334,6 +334,7 @@ const de$1 = {
|
|
|
334
334
|
"success.age": "{{age}} Jahre",
|
|
335
335
|
"success.paymentSummary": "Zahlungsübersicht",
|
|
336
336
|
"success.total": "Gesamtbetrag",
|
|
337
|
+
"success.discount": "Rabatt",
|
|
337
338
|
"success.product": "Produkt",
|
|
338
339
|
"success.contactInfo": "Kontaktdaten",
|
|
339
340
|
"success.name": "Name:",
|
|
@@ -542,6 +543,7 @@ const en = {
|
|
|
542
543
|
"success.age": "{{age}} years",
|
|
543
544
|
"success.paymentSummary": "Payment Summary",
|
|
544
545
|
"success.total": "Total",
|
|
546
|
+
"success.discount": "Discount",
|
|
545
547
|
"success.product": "Product",
|
|
546
548
|
"success.contactInfo": "Contact Information",
|
|
547
549
|
"success.name": "Name:",
|
|
@@ -750,6 +752,7 @@ const es = {
|
|
|
750
752
|
"success.age": "{{age}} años",
|
|
751
753
|
"success.paymentSummary": "Resumen del pago",
|
|
752
754
|
"success.total": "Total",
|
|
755
|
+
"success.discount": "Descuento",
|
|
753
756
|
"success.product": "Producto",
|
|
754
757
|
"success.contactInfo": "Datos de contacto",
|
|
755
758
|
"success.name": "Nombre:",
|
|
@@ -958,6 +961,7 @@ const pt = {
|
|
|
958
961
|
"success.age": "{{age}} anos",
|
|
959
962
|
"success.paymentSummary": "Resumo do pagamento",
|
|
960
963
|
"success.total": "Total",
|
|
964
|
+
"success.discount": "Desconto",
|
|
961
965
|
"success.product": "Produto",
|
|
962
966
|
"success.contactInfo": "Dados de contacto",
|
|
963
967
|
"success.name": "Nome:",
|
|
@@ -1166,6 +1170,7 @@ const sv = {
|
|
|
1166
1170
|
"success.age": "{{age}} år",
|
|
1167
1171
|
"success.paymentSummary": "Betalningssammanfattning",
|
|
1168
1172
|
"success.total": "Totalt",
|
|
1173
|
+
"success.discount": "Rabatt",
|
|
1169
1174
|
"success.product": "Produkt",
|
|
1170
1175
|
"success.contactInfo": "Kontaktuppgifter",
|
|
1171
1176
|
"success.name": "Namn:",
|
|
@@ -1292,7 +1297,7 @@ function persistLocale(locale) {
|
|
|
1292
1297
|
const I18nContext = createContext(null);
|
|
1293
1298
|
function I18nProvider({ configLocale, children }) {
|
|
1294
1299
|
// Priority: configLocale (site owner) > persisted user choice > browser language > "de"
|
|
1295
|
-
// If configLocale is set, the site owner has locked the language
|
|
1300
|
+
// If configLocale is set, the site owner has locked the language - don't restore user choice.
|
|
1296
1301
|
const [overrideLocale, setOverrideLocale] = useState(() => {
|
|
1297
1302
|
if (configLocale)
|
|
1298
1303
|
return null;
|
|
@@ -11001,6 +11006,13 @@ function mergeStyles(...styles) {
|
|
|
11001
11006
|
return Object.assign({}, ...styles.filter(Boolean));
|
|
11002
11007
|
}
|
|
11003
11008
|
|
|
11009
|
+
function getEffectivePrice(upsell, round) {
|
|
11010
|
+
const dp = upsell.discountPercent ?? 0;
|
|
11011
|
+
if (dp <= 0)
|
|
11012
|
+
return upsell.price;
|
|
11013
|
+
const raw = Math.round(upsell.price * (100 - dp) / 100);
|
|
11014
|
+
return round ? Math.floor(raw / 100) * 100 : raw;
|
|
11015
|
+
}
|
|
11004
11016
|
// Local style aliases from shared styles
|
|
11005
11017
|
const cardStyles = cardStyles$1.base;
|
|
11006
11018
|
const sectionHeaderStyles = sectionStyles.header;
|
|
@@ -11011,6 +11023,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11011
11023
|
const t$1 = useTranslations();
|
|
11012
11024
|
const { locale } = useLocale();
|
|
11013
11025
|
const timezone = useTimezone();
|
|
11026
|
+
const roundEnabled = systemConfig?.roundPricesEnabled !== false;
|
|
11014
11027
|
const [appliedVouchers, setAppliedVouchers] = useState([]);
|
|
11015
11028
|
const paymentSectionRef = useRef(null);
|
|
11016
11029
|
// Payment option: "deposit" or "full" - only relevant when deposit is available
|
|
@@ -11081,7 +11094,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11081
11094
|
participantUpsellIds.forEach(upsellId => {
|
|
11082
11095
|
const upsell = upsells.find(u => u.id === upsellId);
|
|
11083
11096
|
if (upsell) {
|
|
11084
|
-
total += upsell
|
|
11097
|
+
total += getEffectivePrice(upsell, roundEnabled);
|
|
11085
11098
|
}
|
|
11086
11099
|
});
|
|
11087
11100
|
}
|
|
@@ -11357,7 +11370,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11357
11370
|
padding: 0,
|
|
11358
11371
|
}, children: "\u00D7" })] }))] }), upsells.length > 0 && (jsx("div", { style: participantUpsellStyles.container, children: upsells.map((upsell) => {
|
|
11359
11372
|
const isSelected = (participantUpsells[index] || []).includes(upsell.id);
|
|
11360
|
-
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
|
|
11373
|
+
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(getEffectivePrice(upsell, roundEnabled)), ")"] })] }, upsell.id));
|
|
11361
11374
|
}) }))] }, index))), watchedParticipants.length < eventDetails.availableSpots ? (jsx("div", { style: {
|
|
11362
11375
|
display: "flex",
|
|
11363
11376
|
flexDirection: "column",
|
|
@@ -11389,7 +11402,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11389
11402
|
const countWithUpsell = watchedParticipants.filter((p, idx) => p.name.trim() && (participantUpsells[idx] || []).includes(upsell.id)).length;
|
|
11390
11403
|
if (countWithUpsell === 0)
|
|
11391
11404
|
return null;
|
|
11392
|
-
const upsellLineTotal = upsell
|
|
11405
|
+
const upsellLineTotal = getEffectivePrice(upsell, roundEnabled) * countWithUpsell;
|
|
11393
11406
|
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));
|
|
11394
11407
|
})] })), 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: {
|
|
11395
11408
|
fontFamily: "var(--bw-font-family)",
|
|
@@ -11514,7 +11527,7 @@ function BookingForm({ config, eventDetails, stripePromise, onSuccess, onError,
|
|
|
11514
11527
|
: t$1("payment.fillRequired");
|
|
11515
11528
|
return (jsx("div", { style: {
|
|
11516
11529
|
...cardStyles,
|
|
11517
|
-
|
|
11530
|
+
border: "1px solid var(--bw-warning-color)",
|
|
11518
11531
|
color: "var(--bw-warning-color)",
|
|
11519
11532
|
fontFamily: "var(--bw-font-family)",
|
|
11520
11533
|
textAlign: "center",
|
|
@@ -11683,6 +11696,7 @@ const BookingSuccessModal = ({ isOpen, onClose, config, onError, paymentIntentId
|
|
|
11683
11696
|
payments: data.payments,
|
|
11684
11697
|
orderItems: data.orderItems,
|
|
11685
11698
|
purchases: data.purchases || [],
|
|
11699
|
+
discount: data.discount || null,
|
|
11686
11700
|
stripePaymentIntent: data.stripePaymentIntent,
|
|
11687
11701
|
});
|
|
11688
11702
|
setEventDetails({
|
|
@@ -11932,7 +11946,7 @@ const BookingSuccessModal = ({ isOpen, onClose, config, onError, paymentIntentId
|
|
|
11932
11946
|
color: "var(--bw-text-color)",
|
|
11933
11947
|
margin: "0",
|
|
11934
11948
|
fontFamily: "var(--bw-font-family)",
|
|
11935
|
-
}, children: t("success.paymentSummary") }) }), jsx("div", { className: "print-only", children: jsx("div", { className: "print-section-title", children: t("success.paymentSummary") }) }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [jsxs("div", { className: "print-hidden", style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-small)" }, children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxs("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)", fontSize: "var(--bw-font-size-small)" }, children: [eventDetails.name, " (", booking.participantCount, "x ", formatCurrency(eventDetails.price), ")"] }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(eventDetails.price * booking.participantCount) })] }), bookingData.purchases && bookingData.purchases.length > 0 && (jsx(Fragment, { children: bookingData.purchases.map((purchase) => (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxs("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)", fontSize: "var(--bw-font-size-small)" }, children: [purchase.product?.name || t("success.product"), " (", purchase.quantity, "x ", formatCurrency(purchase.unitPrice), ")"] }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(purchase.totalPrice) })] }, purchase.id))) })), jsxs("div", { style: {
|
|
11949
|
+
}, children: t("success.paymentSummary") }) }), jsx("div", { className: "print-only", children: jsx("div", { className: "print-section-title", children: t("success.paymentSummary") }) }), jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "8px" }, children: [jsxs("div", { className: "print-hidden", style: { display: "flex", flexDirection: "column", gap: "var(--bw-spacing-small)" }, children: [jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxs("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)", fontSize: "var(--bw-font-size-small)" }, children: [eventDetails.name, " (", booking.participantCount, "x ", formatCurrency(eventDetails.price), ")"] }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(eventDetails.price * booking.participantCount) })] }), bookingData.discount && bookingData.discount.amount > 0 && (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxs("span", { style: { color: "var(--bw-success-color, #10B981)", fontFamily: "var(--bw-font-family)", fontSize: "var(--bw-font-size-small)" }, children: [t("success.discount"), " (", bookingData.discount.code, ")"] }), jsxs("span", { style: { color: "var(--bw-success-color, #10B981)", fontFamily: "var(--bw-font-family)" }, children: ["-", formatCurrency(bookingData.discount.amount)] })] })), bookingData.purchases && bookingData.purchases.length > 0 && (jsx(Fragment, { children: bookingData.purchases.map((purchase) => (jsxs("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "center" }, children: [jsxs("span", { style: { color: "var(--bw-text-muted)", fontFamily: "var(--bw-font-family)", fontSize: "var(--bw-font-size-small)" }, children: [purchase.product?.name || t("success.product"), " (", purchase.quantity, "x ", formatCurrency(purchase.unitPrice), ")"] }), jsx("span", { style: { color: "var(--bw-text-color)", fontFamily: "var(--bw-font-family)" }, children: formatCurrency(purchase.totalPrice) })] }, purchase.id))) })), jsxs("div", { style: {
|
|
11936
11950
|
display: "flex",
|
|
11937
11951
|
justifyContent: "space-between",
|
|
11938
11952
|
alignItems: "center",
|
|
@@ -13411,7 +13425,7 @@ function PromoDialog({ config, onClose, onCtaClick }) {
|
|
|
13411
13425
|
color: "rgba(255, 255, 255, 0.85)",
|
|
13412
13426
|
lineHeight: 1.5,
|
|
13413
13427
|
margin: "0 0 16px 0",
|
|
13414
|
-
}, children: [config.subtitle, config.discountAmount && (jsxs(Fragment, { children: ["
|
|
13428
|
+
}, children: [config.subtitle, config.discountAmount && (jsxs(Fragment, { children: [" - ", jsxs("strong", { style: { color: "white" }, children: [config.discountAmount, " ", t("promo.discount")] })] }))] }), config.discountCode && (jsxs("div", { style: {
|
|
13415
13429
|
marginBottom: "16px",
|
|
13416
13430
|
backgroundColor: "rgba(255,255,255,0.12)",
|
|
13417
13431
|
borderRadius: "12px",
|
|
@@ -13496,7 +13510,9 @@ const cardBaseStyles = {
|
|
|
13496
13510
|
flexDirection: "column",
|
|
13497
13511
|
padding: "16px",
|
|
13498
13512
|
backgroundColor: "var(--bw-surface-color)",
|
|
13499
|
-
|
|
13513
|
+
borderWidth: "2px",
|
|
13514
|
+
borderStyle: "solid",
|
|
13515
|
+
borderColor: "var(--bw-border-color)",
|
|
13500
13516
|
borderRadius: "var(--bw-border-radius)",
|
|
13501
13517
|
cursor: "pointer",
|
|
13502
13518
|
transition: "all 0.2s ease",
|
|
@@ -13521,7 +13537,9 @@ const checkboxContainerStyles = {
|
|
|
13521
13537
|
const checkboxInnerStyles = {
|
|
13522
13538
|
width: "24px",
|
|
13523
13539
|
height: "24px",
|
|
13524
|
-
|
|
13540
|
+
borderWidth: "2px",
|
|
13541
|
+
borderStyle: "solid",
|
|
13542
|
+
borderColor: "var(--bw-border-color)",
|
|
13525
13543
|
borderRadius: "6px",
|
|
13526
13544
|
display: "flex",
|
|
13527
13545
|
alignItems: "center",
|
|
@@ -13647,10 +13665,11 @@ function formatUnavailableReason(reason, t) {
|
|
|
13647
13665
|
return t("upsells.reason.notEnoughSpots", { eventTypeName: reason.eventTypeName });
|
|
13648
13666
|
}
|
|
13649
13667
|
}
|
|
13650
|
-
function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
|
|
13668
|
+
function UpsellCard({ upsell, isSelected, participantCount, onSelect, roundPricesEnabled = true, }) {
|
|
13651
13669
|
const t = useTranslations();
|
|
13652
13670
|
const { locale } = useLocale();
|
|
13653
|
-
const
|
|
13671
|
+
const effectivePrice = getEffectiveUpsellPrice(upsell, roundPricesEnabled);
|
|
13672
|
+
const totalPrice = effectivePrice * participantCount;
|
|
13654
13673
|
const isDisabled = !upsell.available;
|
|
13655
13674
|
const getCardStyles = () => {
|
|
13656
13675
|
if (isDisabled)
|
|
@@ -13668,12 +13687,19 @@ function UpsellCard({ upsell, isSelected, participantCount, onSelect, }) {
|
|
|
13668
13687
|
weekday: "short",
|
|
13669
13688
|
day: "numeric",
|
|
13670
13689
|
month: "short",
|
|
13671
|
-
})] }), 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(
|
|
13690
|
+
})] }), 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(effectivePrice), "/", t("common.perPerson")] }), participantCount > 1 && (jsxs("span", { style: priceTotalStyles, children: ["= ", formatCurrency(totalPrice)] }))] }), isDisabled && (jsx("div", { style: unavailableOverlayStyles, children: jsx("span", { children: upsell.unavailableReason
|
|
13672
13691
|
? formatUnavailableReason(upsell.unavailableReason, t)
|
|
13673
13692
|
: t("upsells.notAvailable") }) }))] }));
|
|
13674
13693
|
}
|
|
13675
13694
|
|
|
13676
|
-
function
|
|
13695
|
+
function getEffectiveUpsellPrice(upsell, round = true) {
|
|
13696
|
+
const dp = upsell.discountPercent ?? 0;
|
|
13697
|
+
if (dp <= 0)
|
|
13698
|
+
return upsell.price;
|
|
13699
|
+
const raw = Math.round(upsell.price * (100 - dp) / 100);
|
|
13700
|
+
return round ? Math.floor(raw / 100) * 100 : raw;
|
|
13701
|
+
}
|
|
13702
|
+
function UpsellsStep({ upsells, selectedUpsells, participantCount, isLoading, isOpen, onClose, onSelect, onContinue, onBack, roundPricesEnabled = true, }) {
|
|
13677
13703
|
const t = useTranslations();
|
|
13678
13704
|
const selectUpsell = (upsellId) => {
|
|
13679
13705
|
const exists = selectedUpsells.find((s) => s.upsellPackageId === upsellId);
|
|
@@ -13692,7 +13718,7 @@ function UpsellsStep({ upsells, selectedUpsells, participantCount, isLoading, is
|
|
|
13692
13718
|
return selectedUpsells.reduce((total, selection) => {
|
|
13693
13719
|
const upsell = upsells.find((u) => u.id === selection.upsellPackageId);
|
|
13694
13720
|
if (upsell) {
|
|
13695
|
-
return total + upsell
|
|
13721
|
+
return total + getEffectiveUpsellPrice(upsell, roundPricesEnabled) * selection.quantity;
|
|
13696
13722
|
}
|
|
13697
13723
|
return total;
|
|
13698
13724
|
}, 0);
|
|
@@ -13700,7 +13726,7 @@ function UpsellsStep({ upsells, selectedUpsells, participantCount, isLoading, is
|
|
|
13700
13726
|
const selectedTotal = calculateTotal();
|
|
13701
13727
|
const selectedCount = selectedUpsells.length;
|
|
13702
13728
|
const footerContent = (jsxs(Fragment, { children: [jsx("button", { type: "button", onClick: onBack, style: mergeStyles(buttonStyles.secondary, buttonStyles.fullWidth), children: t("common.back") }), jsx("button", { type: "button", onClick: onContinue, style: mergeStyles(buttonStyles.primary, buttonStyles.fullWidth), children: selectedCount === 0 ? t("button.continueWithout") : t("button.continue") })] }));
|
|
13703
|
-
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)] })] }))] }) }));
|
|
13729
|
+
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), roundPricesEnabled: roundPricesEnabled }, 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)] })] }))] }) }));
|
|
13704
13730
|
}
|
|
13705
13731
|
|
|
13706
13732
|
// Main widget component
|
|
@@ -13960,6 +13986,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
13960
13986
|
connectedAccountId: data.connectedAccountId,
|
|
13961
13987
|
mollieProfileId: data.mollieProfileId,
|
|
13962
13988
|
mollieTestmode: data.mollieTestmode,
|
|
13989
|
+
roundPricesEnabled: data.roundPricesEnabled ?? true,
|
|
13963
13990
|
});
|
|
13964
13991
|
}
|
|
13965
13992
|
if (data.stripePublishableKey) {
|
|
@@ -14018,6 +14045,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
14018
14045
|
connectedAccountId: data.connectedAccountId,
|
|
14019
14046
|
mollieProfileId: data.mollieProfileId,
|
|
14020
14047
|
mollieTestmode: data.mollieTestmode,
|
|
14048
|
+
roundPricesEnabled: data.roundPricesEnabled ?? true,
|
|
14021
14049
|
});
|
|
14022
14050
|
if (!stripePromise && data.stripePublishableKey) {
|
|
14023
14051
|
const stripeOptions = {
|
|
@@ -14166,6 +14194,8 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
14166
14194
|
const handleBookingSuccess = (result) => {
|
|
14167
14195
|
setIsSuccess(true);
|
|
14168
14196
|
setSuccessPaymentIntentId(result.paymentIntent.id);
|
|
14197
|
+
setSidebarOpen(false);
|
|
14198
|
+
setShouldRenderBookingForm(false);
|
|
14169
14199
|
config.onSuccess?.(result);
|
|
14170
14200
|
};
|
|
14171
14201
|
const handleBookingError = (errorMessage) => {
|
|
@@ -14422,7 +14452,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
14422
14452
|
setShouldRenderInstanceSelection(true);
|
|
14423
14453
|
}
|
|
14424
14454
|
}, children: config.buttonText ||
|
|
14425
|
-
(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: () => {
|
|
14455
|
+
(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, roundPricesEnabled: systemConfig?.roundPricesEnabled !== false })), 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: () => {
|
|
14426
14456
|
setIsSuccess(false);
|
|
14427
14457
|
setCurrentStep("eventTypes");
|
|
14428
14458
|
setSidebarOpen(false);
|
|
@@ -14469,7 +14499,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
14469
14499
|
};
|
|
14470
14500
|
};
|
|
14471
14501
|
const backHandlers = getBackHandlers();
|
|
14472
|
-
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, onClose: () => {
|
|
14502
|
+
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, roundPricesEnabled: systemConfig?.roundPricesEnabled !== false })), 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, onClose: () => {
|
|
14473
14503
|
setIsSuccess(false);
|
|
14474
14504
|
setCurrentStep("eventTypes");
|
|
14475
14505
|
setSuccessPaymentIntentId(null);
|