@bigz-app/booking-widget 1.5.1 → 1.5.2
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 +88 -41
- package/dist/booking-widget.js.map +1 -1
- package/dist/components/UniversalBookingWidget.d.ts +3 -105
- package/dist/components/UniversalBookingWidget.d.ts.map +1 -1
- package/dist/components/events/EventInstanceSelection.d.ts +3 -1
- package/dist/components/events/EventInstanceSelection.d.ts.map +1 -1
- package/dist/components/events/EventTypeSelection.d.ts +2 -1
- package/dist/components/events/EventTypeSelection.d.ts.map +1 -1
- package/dist/components/events/NextEventsPreview.d.ts +1 -1
- package/dist/components/events/NextEventsPreview.d.ts.map +1 -1
- package/dist/components/events/SpecialsView.d.ts +1 -1
- package/dist/components/events/SpecialsView.d.ts.map +1 -1
- package/dist/components/events/types.d.ts +42 -0
- package/dist/components/events/types.d.ts.map +1 -0
- package/dist/components/upsells/UpsellCard.d.ts +1 -1
- package/dist/components/upsells/UpsellCard.d.ts.map +1 -1
- package/dist/components/upsells/UpsellsStep.d.ts +2 -44
- package/dist/components/upsells/UpsellsStep.d.ts.map +1 -1
- package/dist/components/upsells/types.d.ts +44 -0
- package/dist/components/upsells/types.d.ts.map +1 -0
- package/dist/components/voucher/VoucherPurchaseForm.d.ts +2 -15
- package/dist/components/voucher/VoucherPurchaseForm.d.ts.map +1 -1
- package/dist/components/voucher/types.d.ts +15 -0
- package/dist/components/voucher/types.d.ts.map +1 -0
- package/dist/config.d.ts +66 -0
- package/dist/config.d.ts.map +1 -0
- 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 +88 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +88 -41
- package/dist/index.esm.js.map +1 -1
- package/dist/styles/StyleProvider.d.ts +1 -1
- package/dist/styles/StyleProvider.d.ts.map +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -741,6 +741,21 @@ const es = {
|
|
|
741
741
|
"instances.bestPrice": "¡¡¡mejor precio!!!",
|
|
742
742
|
"instances.goodPrice": "buen precio",
|
|
743
743
|
"instances.oclock": "",
|
|
744
|
+
// Lista de espera
|
|
745
|
+
"waitlist.joinCta": "Lista de espera",
|
|
746
|
+
"waitlist.title": "Apuntarse a la lista de espera",
|
|
747
|
+
"waitlist.subtitle": "{{name}} está agotado. Deja tus datos y te contactaremos si se libera un lugar.",
|
|
748
|
+
"waitlist.name": "Nombre",
|
|
749
|
+
"waitlist.email": "Correo electrónico",
|
|
750
|
+
"waitlist.phone": "Teléfono (opcional)",
|
|
751
|
+
"waitlist.requiredFields": "Por favor, introduce tu nombre y correo electrónico.",
|
|
752
|
+
"waitlist.join": "Apuntarse",
|
|
753
|
+
"waitlist.submitting": "Apuntando...",
|
|
754
|
+
"waitlist.cancel": "Cancelar",
|
|
755
|
+
"waitlist.submitError": "Algo salió mal. Por favor, inténtalo de nuevo.",
|
|
756
|
+
"waitlist.successTitle": "¡Estás en la lista!",
|
|
757
|
+
"waitlist.successMessage": "Eres el número {{position}} en la lista de espera. Te contactaremos si se libera un lugar.",
|
|
758
|
+
"waitlist.done": "Listo",
|
|
744
759
|
// Next events preview
|
|
745
760
|
"nextEvents.title": "Próximas fechas disponibles",
|
|
746
761
|
"nextEvents.subtitle": "Selecciona una fecha o consulta todas las fechas disponibles",
|
|
@@ -1038,6 +1053,21 @@ const pt = {
|
|
|
1038
1053
|
"instances.bestPrice": "melhor preço !!!",
|
|
1039
1054
|
"instances.goodPrice": "bom preço",
|
|
1040
1055
|
"instances.oclock": "",
|
|
1056
|
+
// Lista de espera
|
|
1057
|
+
"waitlist.joinCta": "Lista de espera",
|
|
1058
|
+
"waitlist.title": "Entrar na lista de espera",
|
|
1059
|
+
"waitlist.subtitle": "{{name}} está esgotado. Deixe os seus dados e entraremos em contacto se surgir uma vaga.",
|
|
1060
|
+
"waitlist.name": "Nome",
|
|
1061
|
+
"waitlist.email": "E-mail",
|
|
1062
|
+
"waitlist.phone": "Telefone (opcional)",
|
|
1063
|
+
"waitlist.requiredFields": "Por favor, introduza o seu nome e e-mail.",
|
|
1064
|
+
"waitlist.join": "Inscrever-se",
|
|
1065
|
+
"waitlist.submitting": "A inscrever...",
|
|
1066
|
+
"waitlist.cancel": "Cancelar",
|
|
1067
|
+
"waitlist.submitError": "Algo correu mal. Por favor, tente novamente.",
|
|
1068
|
+
"waitlist.successTitle": "Está na lista!",
|
|
1069
|
+
"waitlist.successMessage": "É o número {{position}} na lista de espera. Entraremos em contacto se surgir uma vaga.",
|
|
1070
|
+
"waitlist.done": "Concluído",
|
|
1041
1071
|
// Next events preview
|
|
1042
1072
|
"nextEvents.title": "Próximas datas disponíveis",
|
|
1043
1073
|
"nextEvents.subtitle": "Selecione uma data ou veja todas as datas disponíveis",
|
|
@@ -1335,6 +1365,21 @@ const sv = {
|
|
|
1335
1365
|
"instances.bestPrice": "bästa pris !!!",
|
|
1336
1366
|
"instances.goodPrice": "bra pris",
|
|
1337
1367
|
"instances.oclock": "",
|
|
1368
|
+
// Väntelista
|
|
1369
|
+
"waitlist.joinCta": "Ställ dig i kö",
|
|
1370
|
+
"waitlist.title": "Ställ dig i kö",
|
|
1371
|
+
"waitlist.subtitle": "{{name}} är fullbokat. Lämna dina uppgifter så kontaktar vi dig om en plats blir ledig.",
|
|
1372
|
+
"waitlist.name": "Namn",
|
|
1373
|
+
"waitlist.email": "E-post",
|
|
1374
|
+
"waitlist.phone": "Telefon (valfritt)",
|
|
1375
|
+
"waitlist.requiredFields": "Ange ditt namn och din e-postadress.",
|
|
1376
|
+
"waitlist.join": "Ställ dig i kö",
|
|
1377
|
+
"waitlist.submitting": "Anmäler...",
|
|
1378
|
+
"waitlist.cancel": "Avbryt",
|
|
1379
|
+
"waitlist.submitError": "Något gick fel. Försök igen.",
|
|
1380
|
+
"waitlist.successTitle": "Du står i kön!",
|
|
1381
|
+
"waitlist.successMessage": "Du är nummer {{position}} på väntelistan. Vi hör av oss om en plats blir ledig.",
|
|
1382
|
+
"waitlist.done": "Klar",
|
|
1338
1383
|
// Next events preview
|
|
1339
1384
|
"nextEvents.title": "Nästa tillgängliga datum",
|
|
1340
1385
|
"nextEvents.subtitle": "Välj ett datum eller visa alla tillgängliga datum",
|
|
@@ -14412,7 +14457,7 @@ function InfoBadge({ text }) {
|
|
|
14412
14457
|
pointerEvents: "none",
|
|
14413
14458
|
}, children: text }))] }));
|
|
14414
14459
|
}
|
|
14415
|
-
function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview, isLoading = false, skeletonCount = 4, showVoucherAttachment = false, onVoucherClick, }) {
|
|
14460
|
+
function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview, isLoading = false, skeletonCount = 4, showVoucherAttachment = false, onVoucherClick, showImages = true, }) {
|
|
14416
14461
|
const t = useTranslations();
|
|
14417
14462
|
const { locale } = useLocale();
|
|
14418
14463
|
const timezone = useTimezone();
|
|
@@ -14491,6 +14536,18 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14491
14536
|
gridAutoRows: "1fr",
|
|
14492
14537
|
}, children: eventTypes.map((eventType) => {
|
|
14493
14538
|
const isAvailable = eventType.hasAvailableInstances;
|
|
14539
|
+
const hasImage = showImages && eventType.images && eventType.images.length > 0;
|
|
14540
|
+
const availabilityBadge = (jsxRuntime.jsx("div", { style: {
|
|
14541
|
+
padding: "4px 8px",
|
|
14542
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
14543
|
+
fontSize: "12px",
|
|
14544
|
+
fontWeight: 600,
|
|
14545
|
+
color: "#ffffff",
|
|
14546
|
+
fontFamily: "var(--bw-font-family)",
|
|
14547
|
+
backgroundColor: isAvailable
|
|
14548
|
+
? "var(--bw-success-color)"
|
|
14549
|
+
: "var(--bw-error-color)",
|
|
14550
|
+
}, children: isAvailable ? t("events.spotsAvailable") : t("events.soldOut") }));
|
|
14494
14551
|
return (jsxRuntime.jsxs("div", { className: "event-type-card", style: {
|
|
14495
14552
|
position: "relative",
|
|
14496
14553
|
backgroundColor: "var(--bw-surface-color)",
|
|
@@ -14502,17 +14559,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14502
14559
|
fontFamily: "var(--bw-font-family)",
|
|
14503
14560
|
cursor: isAvailable ? "pointer" : "not-allowed",
|
|
14504
14561
|
opacity: isAvailable ? 1 : 0.6,
|
|
14505
|
-
}, onClick: () => isAvailable && onEventTypeSelect(eventType), children: [jsxRuntime.jsx("div", { style: { position: "absolute", top: "16px", right: "16px", zIndex: 10 }, children: jsxRuntime.jsx("div", { style: {
|
|
14506
|
-
padding: "4px 8px",
|
|
14507
|
-
borderRadius: "var(--bw-border-radius-small)",
|
|
14508
|
-
fontSize: "12px",
|
|
14509
|
-
fontWeight: 600,
|
|
14510
|
-
color: "#ffffff",
|
|
14511
|
-
fontFamily: "var(--bw-font-family)",
|
|
14512
|
-
backgroundColor: isAvailable
|
|
14513
|
-
? "var(--bw-success-color)"
|
|
14514
|
-
: "var(--bw-error-color)",
|
|
14515
|
-
}, children: isAvailable ? t("events.spotsAvailable") : t("events.soldOut") }) }), eventType.images && eventType.images.length > 0 && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { style: { position: "absolute", top: "16px", left: "16px", zIndex: 10 }, children: jsxRuntime.jsx("div", { style: {
|
|
14562
|
+
}, onClick: () => isAvailable && onEventTypeSelect(eventType), children: [hasImage && (jsxRuntime.jsx("div", { style: { position: "absolute", top: "16px", right: "16px", zIndex: 10 }, children: availabilityBadge })), hasImage && (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsx("div", { style: { position: "absolute", top: "16px", left: "16px", zIndex: 10 }, children: jsxRuntime.jsx("div", { style: {
|
|
14516
14563
|
fontSize: "13px",
|
|
14517
14564
|
color: "var(--bw-surface-color)",
|
|
14518
14565
|
fontWeight: 600,
|
|
@@ -14526,7 +14573,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14526
14573
|
flexDirection: "column",
|
|
14527
14574
|
justifyContent: "space-between",
|
|
14528
14575
|
height: "540px",
|
|
14529
|
-
}, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("h2", { className: "event-type-title", style: {
|
|
14576
|
+
}, children: [jsxRuntime.jsxs("div", { children: [!hasImage && (jsxRuntime.jsx("div", { style: { display: "flex", justifyContent: "flex-end", margin: "0 0 8px 0" }, children: availabilityBadge })), jsxRuntime.jsx("h2", { className: "event-type-title", style: {
|
|
14530
14577
|
fontSize: "clamp(1.1rem, 2.5vw, 24px)",
|
|
14531
14578
|
fontWeight: 700,
|
|
14532
14579
|
color: "var(--bw-text-color)",
|
|
@@ -14798,16 +14845,16 @@ function WaitlistDialog({ apiBaseUrl, organizationId, eventInstanceId, eventName
|
|
|
14798
14845
|
}
|
|
14799
14846
|
|
|
14800
14847
|
const getAllocationBadgeInfo = (availableSpots, maxParticipants, t) => {
|
|
14801
|
-
|
|
14802
|
-
if (availabilityRatio >= 0.6)
|
|
14803
|
-
return null;
|
|
14804
|
-
if (availabilityRatio === 0) {
|
|
14848
|
+
if (maxParticipants <= 0 || availableSpots <= 0) {
|
|
14805
14849
|
return {
|
|
14806
14850
|
text: t("events.soldOut"),
|
|
14807
14851
|
backgroundColor: "#7f1d1d",
|
|
14808
14852
|
textColor: "#fca5a5",
|
|
14809
14853
|
};
|
|
14810
14854
|
}
|
|
14855
|
+
const availabilityRatio = availableSpots / maxParticipants;
|
|
14856
|
+
if (availabilityRatio >= 0.6)
|
|
14857
|
+
return null;
|
|
14811
14858
|
if (availabilityRatio <= 0.3) {
|
|
14812
14859
|
return {
|
|
14813
14860
|
text: t("instances.almostSoldOut"),
|
|
@@ -14921,7 +14968,7 @@ const PriceDisplay = ({ price, yearPrices, t }) => {
|
|
|
14921
14968
|
boxShadow: displayInfo ? "0 2px 4px rgba(0, 0, 0, 0.2)" : "none",
|
|
14922
14969
|
}, children: formatCurrency(price) }));
|
|
14923
14970
|
};
|
|
14924
|
-
function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, hasUpsellsStep = false, apiBaseUrl, organizationId, }) {
|
|
14971
|
+
function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, hasUpsellsStep = false, apiBaseUrl, organizationId, waitlistEnabled = false, }) {
|
|
14925
14972
|
const t = useTranslations();
|
|
14926
14973
|
const { locale } = useLocale();
|
|
14927
14974
|
const timezone = useTimezone();
|
|
@@ -15106,12 +15153,13 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
|
|
|
15106
15153
|
? "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
15107
15154
|
: undefined,
|
|
15108
15155
|
}, children: `${t("common.from")} ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", paddingTop: "12px" }, children: events.map((event) => {
|
|
15109
|
-
const availableSpots = event.
|
|
15110
|
-
const isFullyBooked = availableSpots === 0;
|
|
15156
|
+
const availableSpots = event.availableSpots;
|
|
15111
15157
|
const startDate = new Date(event.startTime);
|
|
15112
15158
|
const isPastEvent = today.toISOString() >= startDate.toISOString();
|
|
15113
|
-
const
|
|
15114
|
-
const
|
|
15159
|
+
const isUnavailable = availableSpots <= 0 || !event.bookingOpen;
|
|
15160
|
+
const isDisabled = isUnavailable || isPastEvent;
|
|
15161
|
+
const canWaitlist = waitlistEnabled &&
|
|
15162
|
+
isUnavailable &&
|
|
15115
15163
|
!isPastEvent &&
|
|
15116
15164
|
!!apiBaseUrl &&
|
|
15117
15165
|
!!organizationId;
|
|
@@ -15148,7 +15196,7 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
|
|
|
15148
15196
|
color: "var(--bw-highlight-color)",
|
|
15149
15197
|
opacity: 0.8,
|
|
15150
15198
|
fontSize: "32px",
|
|
15151
|
-
}, children: spinner() }) })), jsxRuntime.jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsxRuntime.jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants, t: t }), jsxRuntime.jsxs("div", { style: {
|
|
15199
|
+
}, children: spinner() }) })), jsxRuntime.jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsxRuntime.jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.effectiveMaxParticipants ?? event.maxParticipants, t: t }), jsxRuntime.jsxs("div", { style: {
|
|
15152
15200
|
display: "flex",
|
|
15153
15201
|
justifyContent: "space-between",
|
|
15154
15202
|
width: "100%",
|
|
@@ -15325,18 +15373,19 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
|
|
|
15325
15373
|
margin: "0 auto",
|
|
15326
15374
|
padding: "12px 16px",
|
|
15327
15375
|
fontFamily: "var(--bw-font-family)",
|
|
15328
|
-
}, children: [jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginBottom: "10px" }, children: events
|
|
15329
|
-
|
|
15330
|
-
const isFullyBooked = availableSpots === 0;
|
|
15376
|
+
}, children: [jsxRuntime.jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginBottom: "10px" }, children: events
|
|
15377
|
+
.filter((event) => {
|
|
15331
15378
|
const startDate = new Date(event.startTime);
|
|
15332
15379
|
const isPastEvent = today.toISOString() >= startDate.toISOString();
|
|
15333
|
-
|
|
15334
|
-
|
|
15380
|
+
return !isPastEvent && event.availableSpots > 0 && event.bookingOpen;
|
|
15381
|
+
})
|
|
15382
|
+
.map((event) => {
|
|
15383
|
+
const availableSpots = event.availableSpots;
|
|
15384
|
+
const startDate = new Date(event.startTime);
|
|
15335
15385
|
const allocationBadge = (() => {
|
|
15386
|
+
const availabilityRatio = availableSpots / event.maxParticipants;
|
|
15336
15387
|
if (availabilityRatio >= 0.6)
|
|
15337
15388
|
return null;
|
|
15338
|
-
if (availabilityRatio === 0)
|
|
15339
|
-
return { text: t("events.soldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
|
|
15340
15389
|
if (availabilityRatio <= 0.3)
|
|
15341
15390
|
return { text: t("instances.almostSoldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
|
|
15342
15391
|
return { text: t("instances.popularDate"), backgroundColor: "#b45309", textColor: "#fbbf24" };
|
|
@@ -15350,13 +15399,9 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
|
|
|
15350
15399
|
padding: "16px 10px",
|
|
15351
15400
|
transition: "all 0.2s ease",
|
|
15352
15401
|
fontFamily: "var(--bw-font-family)",
|
|
15353
|
-
|
|
15354
|
-
filter: isDisabled ? "grayscale(40%)" : "none",
|
|
15355
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
15402
|
+
cursor: "pointer",
|
|
15356
15403
|
}, onClick: () => {
|
|
15357
|
-
|
|
15358
|
-
handleEventSelect(event.id);
|
|
15359
|
-
}
|
|
15404
|
+
handleEventSelect(event.id);
|
|
15360
15405
|
}, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsxRuntime.jsx("div", { style: {
|
|
15361
15406
|
position: "absolute",
|
|
15362
15407
|
inset: 0,
|
|
@@ -15611,7 +15656,7 @@ function SpecialsView({ specials, onEventSelect, isLoading = false, showSavingsA
|
|
|
15611
15656
|
alignItems: "center",
|
|
15612
15657
|
backgroundColor: "var(--bw-background-color)",
|
|
15613
15658
|
}, children: [jsxRuntime.jsx("span", { style: { fontSize: "12px", color: "var(--bw-text-muted)" }, children: isFullyBooked
|
|
15614
|
-
? t("
|
|
15659
|
+
? t("events.soldOut")
|
|
15615
15660
|
: t("specials.spotsLeft").replace("{{count}}", String(special.availableSpots)) }), jsxRuntime.jsxs("span", { style: {
|
|
15616
15661
|
fontSize: "13px",
|
|
15617
15662
|
fontWeight: 600,
|
|
@@ -16560,6 +16605,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16560
16605
|
const [isSuccess, setIsSuccess] = React.useState(false);
|
|
16561
16606
|
const [successPaymentId, setSuccessPaymentId] = React.useState(null);
|
|
16562
16607
|
const [systemConfig, setSystemConfig] = React.useState(null);
|
|
16608
|
+
const [waitlistEnabled, setWaitlistEnabled] = React.useState(false);
|
|
16563
16609
|
// When true, loadEventInstances skips the single-instance auto-select (used by handleShowAllEvents)
|
|
16564
16610
|
const skipInstanceAutoSelectRef = React.useRef(false);
|
|
16565
16611
|
// PERFORMANCE OPTIMIZATION: Lazy component loading
|
|
@@ -17053,6 +17099,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17053
17099
|
}
|
|
17054
17100
|
extractGoogleAdsConfig(data);
|
|
17055
17101
|
setEventInstances(data.eventInstances);
|
|
17102
|
+
setWaitlistEnabled(data.waitlistEnabled ?? false);
|
|
17056
17103
|
if (data.paymentProvider) {
|
|
17057
17104
|
setSystemConfig({
|
|
17058
17105
|
paymentProvider: data.paymentProvider,
|
|
@@ -17621,7 +17668,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17621
17668
|
}, isOpen: currentStep === "eventInstances", onClose: () => {
|
|
17622
17669
|
setShowingPreview(true);
|
|
17623
17670
|
setCurrentStep("eventTypes");
|
|
17624
|
-
}, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
17671
|
+
}, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId, waitlistEnabled: waitlistEnabled })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
17625
17672
|
setIsSuccess(false);
|
|
17626
17673
|
setCurrentStep("eventTypes");
|
|
17627
17674
|
setShowingPreview(true);
|
|
@@ -17684,7 +17731,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17684
17731
|
}, children: [isButtonBusy && jsxRuntime.jsx(Spinner, { size: 20, borderColor: "var(--bw-button-text-color, #ffffff)" }), config.buttonText ||
|
|
17685
17732
|
(isDirectInstanceMode || selectedEventType?.bookingMode === "freeform"
|
|
17686
17733
|
? t("button.bookNow")
|
|
17687
|
-
: t("button.viewDates"))] }), shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId })), 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, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), shouldRenderFreeformSelection && selectedEventType?.bookingMode === "freeform" && (jsxRuntime.jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17734
|
+
: t("button.viewDates"))] }), shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId, waitlistEnabled: waitlistEnabled })), 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, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), shouldRenderFreeformSelection && selectedEventType?.bookingMode === "freeform" && (jsxRuntime.jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17688
17735
|
setCurrentStep("eventTypes");
|
|
17689
17736
|
setSidebarOpen(false);
|
|
17690
17737
|
setShouldRenderFreeformSelection(false);
|
|
@@ -17709,7 +17756,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17709
17756
|
}, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsxRuntime.jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
|
|
17710
17757
|
}
|
|
17711
17758
|
// Cards mode (default) - show event type selection with optional voucher card
|
|
17712
|
-
const cardsView = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasEventSelection && (jsxRuntime.jsx(EventTypeSelection, { eventTypes: eventTypes, onEventTypeSelect: handleEventTypeSelect, onInstancePreview: (instanceId, eventTypeId) => void handleUpcomingEventSelect(instanceId, eventTypeId), isLoading: isLoading, skeletonCount: getSkeletonCount(), showVoucherAttachment: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled && !isStandaloneVoucherMode), onVoucherClick: handleVoucherAttachmentClick })), isStandaloneVoucherMode && (jsxRuntime.jsx(VoucherIntegration, { config: config, voucherConfig: voucherConfig, eventTypes: voucherEventTypes, categories: voucherCategories, systemConfig: systemConfig, isFormOpen: false, isLoadingConfig: isLoadingVoucherConfig, preselectedEventTypeId: null, voucherPurchaseResult: null, isSuccess: false, showStandaloneCard: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled), onCardClick: handleVoucherCardClick, onFormClose: handleVoucherFormClose, onSuccess: handleVoucherSuccess, onError: handleVoucherError, onSuccessModalClose: () => { } })), isStandaloneVoucherMode && isLoading && !voucherConfig && (jsxRuntime.jsx("div", { style: { padding: "24px", textAlign: "center" }, children: jsxRuntime.jsx("div", { style: {
|
|
17759
|
+
const cardsView = (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [hasEventSelection && (jsxRuntime.jsx(EventTypeSelection, { eventTypes: eventTypes, onEventTypeSelect: handleEventTypeSelect, onInstancePreview: (instanceId, eventTypeId) => void handleUpcomingEventSelect(instanceId, eventTypeId), isLoading: isLoading, skeletonCount: getSkeletonCount(), showVoucherAttachment: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled && !isStandaloneVoucherMode), onVoucherClick: handleVoucherAttachmentClick, showImages: config.showEventImages !== false })), isStandaloneVoucherMode && (jsxRuntime.jsx(VoucherIntegration, { config: config, voucherConfig: voucherConfig, eventTypes: voucherEventTypes, categories: voucherCategories, systemConfig: systemConfig, isFormOpen: false, isLoadingConfig: isLoadingVoucherConfig, preselectedEventTypeId: null, voucherPurchaseResult: null, isSuccess: false, showStandaloneCard: Boolean(voucherConfig?.enabled && voucherCardIntegrationEnabled), onCardClick: handleVoucherCardClick, onFormClose: handleVoucherFormClose, onSuccess: handleVoucherSuccess, onError: handleVoucherError, onSuccessModalClose: () => { } })), isStandaloneVoucherMode && isLoading && !voucherConfig && (jsxRuntime.jsx("div", { style: { padding: "24px", textAlign: "center" }, children: jsxRuntime.jsx("div", { style: {
|
|
17713
17760
|
display: "inline-block",
|
|
17714
17761
|
width: "32px",
|
|
17715
17762
|
height: "32px",
|
|
@@ -17750,7 +17797,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17750
17797
|
};
|
|
17751
17798
|
};
|
|
17752
17799
|
const backHandlers = getBackHandlers();
|
|
17753
|
-
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId })), 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, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: backHandlers.onClose, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), shouldRenderFreeformSelection && selectedEventType?.bookingMode === "freeform" && (jsxRuntime.jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17800
|
+
return (jsxRuntime.jsxs(StyleProvider, { config: config, children: [jsxRuntime.jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsxRuntime.jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId, waitlistEnabled: waitlistEnabled })), 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, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: backHandlers.onClose, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), shouldRenderFreeformSelection && selectedEventType?.bookingMode === "freeform" && (jsxRuntime.jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17754
17801
|
setCurrentStep("eventTypes");
|
|
17755
17802
|
setShouldRenderFreeformSelection(false);
|
|
17756
17803
|
}, onSuccess: handleBookingSuccess, onError: handleBookingError, systemConfig: systemConfig })), jsxRuntime.jsx(BookingSuccessModal, { isOpen: isSuccess && !voucherPurchaseResult, onClose: () => {
|