@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.esm.js
CHANGED
|
@@ -721,6 +721,21 @@ const es = {
|
|
|
721
721
|
"instances.bestPrice": "¡¡¡mejor precio!!!",
|
|
722
722
|
"instances.goodPrice": "buen precio",
|
|
723
723
|
"instances.oclock": "",
|
|
724
|
+
// Lista de espera
|
|
725
|
+
"waitlist.joinCta": "Lista de espera",
|
|
726
|
+
"waitlist.title": "Apuntarse a la lista de espera",
|
|
727
|
+
"waitlist.subtitle": "{{name}} está agotado. Deja tus datos y te contactaremos si se libera un lugar.",
|
|
728
|
+
"waitlist.name": "Nombre",
|
|
729
|
+
"waitlist.email": "Correo electrónico",
|
|
730
|
+
"waitlist.phone": "Teléfono (opcional)",
|
|
731
|
+
"waitlist.requiredFields": "Por favor, introduce tu nombre y correo electrónico.",
|
|
732
|
+
"waitlist.join": "Apuntarse",
|
|
733
|
+
"waitlist.submitting": "Apuntando...",
|
|
734
|
+
"waitlist.cancel": "Cancelar",
|
|
735
|
+
"waitlist.submitError": "Algo salió mal. Por favor, inténtalo de nuevo.",
|
|
736
|
+
"waitlist.successTitle": "¡Estás en la lista!",
|
|
737
|
+
"waitlist.successMessage": "Eres el número {{position}} en la lista de espera. Te contactaremos si se libera un lugar.",
|
|
738
|
+
"waitlist.done": "Listo",
|
|
724
739
|
// Next events preview
|
|
725
740
|
"nextEvents.title": "Próximas fechas disponibles",
|
|
726
741
|
"nextEvents.subtitle": "Selecciona una fecha o consulta todas las fechas disponibles",
|
|
@@ -1018,6 +1033,21 @@ const pt = {
|
|
|
1018
1033
|
"instances.bestPrice": "melhor preço !!!",
|
|
1019
1034
|
"instances.goodPrice": "bom preço",
|
|
1020
1035
|
"instances.oclock": "",
|
|
1036
|
+
// Lista de espera
|
|
1037
|
+
"waitlist.joinCta": "Lista de espera",
|
|
1038
|
+
"waitlist.title": "Entrar na lista de espera",
|
|
1039
|
+
"waitlist.subtitle": "{{name}} está esgotado. Deixe os seus dados e entraremos em contacto se surgir uma vaga.",
|
|
1040
|
+
"waitlist.name": "Nome",
|
|
1041
|
+
"waitlist.email": "E-mail",
|
|
1042
|
+
"waitlist.phone": "Telefone (opcional)",
|
|
1043
|
+
"waitlist.requiredFields": "Por favor, introduza o seu nome e e-mail.",
|
|
1044
|
+
"waitlist.join": "Inscrever-se",
|
|
1045
|
+
"waitlist.submitting": "A inscrever...",
|
|
1046
|
+
"waitlist.cancel": "Cancelar",
|
|
1047
|
+
"waitlist.submitError": "Algo correu mal. Por favor, tente novamente.",
|
|
1048
|
+
"waitlist.successTitle": "Está na lista!",
|
|
1049
|
+
"waitlist.successMessage": "É o número {{position}} na lista de espera. Entraremos em contacto se surgir uma vaga.",
|
|
1050
|
+
"waitlist.done": "Concluído",
|
|
1021
1051
|
// Next events preview
|
|
1022
1052
|
"nextEvents.title": "Próximas datas disponíveis",
|
|
1023
1053
|
"nextEvents.subtitle": "Selecione uma data ou veja todas as datas disponíveis",
|
|
@@ -1315,6 +1345,21 @@ const sv = {
|
|
|
1315
1345
|
"instances.bestPrice": "bästa pris !!!",
|
|
1316
1346
|
"instances.goodPrice": "bra pris",
|
|
1317
1347
|
"instances.oclock": "",
|
|
1348
|
+
// Väntelista
|
|
1349
|
+
"waitlist.joinCta": "Ställ dig i kö",
|
|
1350
|
+
"waitlist.title": "Ställ dig i kö",
|
|
1351
|
+
"waitlist.subtitle": "{{name}} är fullbokat. Lämna dina uppgifter så kontaktar vi dig om en plats blir ledig.",
|
|
1352
|
+
"waitlist.name": "Namn",
|
|
1353
|
+
"waitlist.email": "E-post",
|
|
1354
|
+
"waitlist.phone": "Telefon (valfritt)",
|
|
1355
|
+
"waitlist.requiredFields": "Ange ditt namn och din e-postadress.",
|
|
1356
|
+
"waitlist.join": "Ställ dig i kö",
|
|
1357
|
+
"waitlist.submitting": "Anmäler...",
|
|
1358
|
+
"waitlist.cancel": "Avbryt",
|
|
1359
|
+
"waitlist.submitError": "Något gick fel. Försök igen.",
|
|
1360
|
+
"waitlist.successTitle": "Du står i kön!",
|
|
1361
|
+
"waitlist.successMessage": "Du är nummer {{position}} på väntelistan. Vi hör av oss om en plats blir ledig.",
|
|
1362
|
+
"waitlist.done": "Klar",
|
|
1318
1363
|
// Next events preview
|
|
1319
1364
|
"nextEvents.title": "Nästa tillgängliga datum",
|
|
1320
1365
|
"nextEvents.subtitle": "Välj ett datum eller visa alla tillgängliga datum",
|
|
@@ -14392,7 +14437,7 @@ function InfoBadge({ text }) {
|
|
|
14392
14437
|
pointerEvents: "none",
|
|
14393
14438
|
}, children: text }))] }));
|
|
14394
14439
|
}
|
|
14395
|
-
function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview, isLoading = false, skeletonCount = 4, showVoucherAttachment = false, onVoucherClick, }) {
|
|
14440
|
+
function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview, isLoading = false, skeletonCount = 4, showVoucherAttachment = false, onVoucherClick, showImages = true, }) {
|
|
14396
14441
|
const t = useTranslations();
|
|
14397
14442
|
const { locale } = useLocale();
|
|
14398
14443
|
const timezone = useTimezone();
|
|
@@ -14471,6 +14516,18 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14471
14516
|
gridAutoRows: "1fr",
|
|
14472
14517
|
}, children: eventTypes.map((eventType) => {
|
|
14473
14518
|
const isAvailable = eventType.hasAvailableInstances;
|
|
14519
|
+
const hasImage = showImages && eventType.images && eventType.images.length > 0;
|
|
14520
|
+
const availabilityBadge = (jsx("div", { style: {
|
|
14521
|
+
padding: "4px 8px",
|
|
14522
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
14523
|
+
fontSize: "12px",
|
|
14524
|
+
fontWeight: 600,
|
|
14525
|
+
color: "#ffffff",
|
|
14526
|
+
fontFamily: "var(--bw-font-family)",
|
|
14527
|
+
backgroundColor: isAvailable
|
|
14528
|
+
? "var(--bw-success-color)"
|
|
14529
|
+
: "var(--bw-error-color)",
|
|
14530
|
+
}, children: isAvailable ? t("events.spotsAvailable") : t("events.soldOut") }));
|
|
14474
14531
|
return (jsxs("div", { className: "event-type-card", style: {
|
|
14475
14532
|
position: "relative",
|
|
14476
14533
|
backgroundColor: "var(--bw-surface-color)",
|
|
@@ -14482,17 +14539,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14482
14539
|
fontFamily: "var(--bw-font-family)",
|
|
14483
14540
|
cursor: isAvailable ? "pointer" : "not-allowed",
|
|
14484
14541
|
opacity: isAvailable ? 1 : 0.6,
|
|
14485
|
-
}, onClick: () => isAvailable && onEventTypeSelect(eventType), children: [jsx("div", { style: { position: "absolute", top: "16px", right: "16px", zIndex: 10 }, children: jsx("div", { style: {
|
|
14486
|
-
padding: "4px 8px",
|
|
14487
|
-
borderRadius: "var(--bw-border-radius-small)",
|
|
14488
|
-
fontSize: "12px",
|
|
14489
|
-
fontWeight: 600,
|
|
14490
|
-
color: "#ffffff",
|
|
14491
|
-
fontFamily: "var(--bw-font-family)",
|
|
14492
|
-
backgroundColor: isAvailable
|
|
14493
|
-
? "var(--bw-success-color)"
|
|
14494
|
-
: "var(--bw-error-color)",
|
|
14495
|
-
}, children: isAvailable ? t("events.spotsAvailable") : t("events.soldOut") }) }), eventType.images && eventType.images.length > 0 && (jsxs(Fragment, { children: [jsx("div", { style: { position: "absolute", top: "16px", left: "16px", zIndex: 10 }, children: jsx("div", { style: {
|
|
14542
|
+
}, onClick: () => isAvailable && onEventTypeSelect(eventType), children: [hasImage && (jsx("div", { style: { position: "absolute", top: "16px", right: "16px", zIndex: 10 }, children: availabilityBadge })), hasImage && (jsxs(Fragment, { children: [jsx("div", { style: { position: "absolute", top: "16px", left: "16px", zIndex: 10 }, children: jsx("div", { style: {
|
|
14496
14543
|
fontSize: "13px",
|
|
14497
14544
|
color: "var(--bw-surface-color)",
|
|
14498
14545
|
fontWeight: 600,
|
|
@@ -14506,7 +14553,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14506
14553
|
flexDirection: "column",
|
|
14507
14554
|
justifyContent: "space-between",
|
|
14508
14555
|
height: "540px",
|
|
14509
|
-
}, children: [jsxs("div", { children: [jsx("h2", { className: "event-type-title", style: {
|
|
14556
|
+
}, children: [jsxs("div", { children: [!hasImage && (jsx("div", { style: { display: "flex", justifyContent: "flex-end", margin: "0 0 8px 0" }, children: availabilityBadge })), jsx("h2", { className: "event-type-title", style: {
|
|
14510
14557
|
fontSize: "clamp(1.1rem, 2.5vw, 24px)",
|
|
14511
14558
|
fontWeight: 700,
|
|
14512
14559
|
color: "var(--bw-text-color)",
|
|
@@ -14778,16 +14825,16 @@ function WaitlistDialog({ apiBaseUrl, organizationId, eventInstanceId, eventName
|
|
|
14778
14825
|
}
|
|
14779
14826
|
|
|
14780
14827
|
const getAllocationBadgeInfo = (availableSpots, maxParticipants, t) => {
|
|
14781
|
-
|
|
14782
|
-
if (availabilityRatio >= 0.6)
|
|
14783
|
-
return null;
|
|
14784
|
-
if (availabilityRatio === 0) {
|
|
14828
|
+
if (maxParticipants <= 0 || availableSpots <= 0) {
|
|
14785
14829
|
return {
|
|
14786
14830
|
text: t("events.soldOut"),
|
|
14787
14831
|
backgroundColor: "#7f1d1d",
|
|
14788
14832
|
textColor: "#fca5a5",
|
|
14789
14833
|
};
|
|
14790
14834
|
}
|
|
14835
|
+
const availabilityRatio = availableSpots / maxParticipants;
|
|
14836
|
+
if (availabilityRatio >= 0.6)
|
|
14837
|
+
return null;
|
|
14791
14838
|
if (availabilityRatio <= 0.3) {
|
|
14792
14839
|
return {
|
|
14793
14840
|
text: t("instances.almostSoldOut"),
|
|
@@ -14901,7 +14948,7 @@ const PriceDisplay = ({ price, yearPrices, t }) => {
|
|
|
14901
14948
|
boxShadow: displayInfo ? "0 2px 4px rgba(0, 0, 0, 0.2)" : "none",
|
|
14902
14949
|
}, children: formatCurrency(price) }));
|
|
14903
14950
|
};
|
|
14904
|
-
function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, hasUpsellsStep = false, apiBaseUrl, organizationId, }) {
|
|
14951
|
+
function EventInstanceSelection({ eventInstances, selectedEventType, onEventInstanceSelect, onBackToEventTypes, isOpen, onClose, isLoadingEventInstances = false, isLoadingEventDetails = false, hasUpsellsStep = false, apiBaseUrl, organizationId, waitlistEnabled = false, }) {
|
|
14905
14952
|
const t = useTranslations();
|
|
14906
14953
|
const { locale } = useLocale();
|
|
14907
14954
|
const timezone = useTimezone();
|
|
@@ -15086,12 +15133,13 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
|
|
|
15086
15133
|
? "0 2px 4px rgba(0, 0, 0, 0.2)"
|
|
15087
15134
|
: undefined,
|
|
15088
15135
|
}, children: `${t("common.from")} ${formatCurrency(minPrice)}` }), isOpen: openGroups.has(key), onToggle: () => toggleGroup(key), children: jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", paddingTop: "12px" }, children: events.map((event) => {
|
|
15089
|
-
const availableSpots = event.
|
|
15090
|
-
const isFullyBooked = availableSpots === 0;
|
|
15136
|
+
const availableSpots = event.availableSpots;
|
|
15091
15137
|
const startDate = new Date(event.startTime);
|
|
15092
15138
|
const isPastEvent = today.toISOString() >= startDate.toISOString();
|
|
15093
|
-
const
|
|
15094
|
-
const
|
|
15139
|
+
const isUnavailable = availableSpots <= 0 || !event.bookingOpen;
|
|
15140
|
+
const isDisabled = isUnavailable || isPastEvent;
|
|
15141
|
+
const canWaitlist = waitlistEnabled &&
|
|
15142
|
+
isUnavailable &&
|
|
15095
15143
|
!isPastEvent &&
|
|
15096
15144
|
!!apiBaseUrl &&
|
|
15097
15145
|
!!organizationId;
|
|
@@ -15128,7 +15176,7 @@ function EventInstanceSelection({ eventInstances, selectedEventType, onEventInst
|
|
|
15128
15176
|
color: "var(--bw-highlight-color)",
|
|
15129
15177
|
opacity: 0.8,
|
|
15130
15178
|
fontSize: "32px",
|
|
15131
|
-
}, children: spinner() }) })), jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.maxParticipants, t: t }), jsxs("div", { style: {
|
|
15179
|
+
}, children: spinner() }) })), jsx(SpecialPriceBadge, { price: event.price, yearPrices: yearPrices, t: t }), jsx(AllocationBadge, { availableSpots: availableSpots, maxParticipants: event.effectiveMaxParticipants ?? event.maxParticipants, t: t }), jsxs("div", { style: {
|
|
15132
15180
|
display: "flex",
|
|
15133
15181
|
justifyContent: "space-between",
|
|
15134
15182
|
width: "100%",
|
|
@@ -15305,18 +15353,19 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
|
|
|
15305
15353
|
margin: "0 auto",
|
|
15306
15354
|
padding: "12px 16px",
|
|
15307
15355
|
fontFamily: "var(--bw-font-family)",
|
|
15308
|
-
}, children: [jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginBottom: "10px" }, children: events
|
|
15309
|
-
|
|
15310
|
-
const isFullyBooked = availableSpots === 0;
|
|
15356
|
+
}, children: [jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginBottom: "10px" }, children: events
|
|
15357
|
+
.filter((event) => {
|
|
15311
15358
|
const startDate = new Date(event.startTime);
|
|
15312
15359
|
const isPastEvent = today.toISOString() >= startDate.toISOString();
|
|
15313
|
-
|
|
15314
|
-
|
|
15360
|
+
return !isPastEvent && event.availableSpots > 0 && event.bookingOpen;
|
|
15361
|
+
})
|
|
15362
|
+
.map((event) => {
|
|
15363
|
+
const availableSpots = event.availableSpots;
|
|
15364
|
+
const startDate = new Date(event.startTime);
|
|
15315
15365
|
const allocationBadge = (() => {
|
|
15366
|
+
const availabilityRatio = availableSpots / event.maxParticipants;
|
|
15316
15367
|
if (availabilityRatio >= 0.6)
|
|
15317
15368
|
return null;
|
|
15318
|
-
if (availabilityRatio === 0)
|
|
15319
|
-
return { text: t("events.soldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
|
|
15320
15369
|
if (availabilityRatio <= 0.3)
|
|
15321
15370
|
return { text: t("instances.almostSoldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
|
|
15322
15371
|
return { text: t("instances.popularDate"), backgroundColor: "#b45309", textColor: "#fbbf24" };
|
|
@@ -15330,13 +15379,9 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
|
|
|
15330
15379
|
padding: "16px 10px",
|
|
15331
15380
|
transition: "all 0.2s ease",
|
|
15332
15381
|
fontFamily: "var(--bw-font-family)",
|
|
15333
|
-
|
|
15334
|
-
filter: isDisabled ? "grayscale(40%)" : "none",
|
|
15335
|
-
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
15382
|
+
cursor: "pointer",
|
|
15336
15383
|
}, onClick: () => {
|
|
15337
|
-
|
|
15338
|
-
handleEventSelect(event.id);
|
|
15339
|
-
}
|
|
15384
|
+
handleEventSelect(event.id);
|
|
15340
15385
|
}, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsx("div", { style: {
|
|
15341
15386
|
position: "absolute",
|
|
15342
15387
|
inset: 0,
|
|
@@ -15591,7 +15636,7 @@ function SpecialsView({ specials, onEventSelect, isLoading = false, showSavingsA
|
|
|
15591
15636
|
alignItems: "center",
|
|
15592
15637
|
backgroundColor: "var(--bw-background-color)",
|
|
15593
15638
|
}, children: [jsx("span", { style: { fontSize: "12px", color: "var(--bw-text-muted)" }, children: isFullyBooked
|
|
15594
|
-
? t("
|
|
15639
|
+
? t("events.soldOut")
|
|
15595
15640
|
: t("specials.spotsLeft").replace("{{count}}", String(special.availableSpots)) }), jsxs("span", { style: {
|
|
15596
15641
|
fontSize: "13px",
|
|
15597
15642
|
fontWeight: 600,
|
|
@@ -16540,6 +16585,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16540
16585
|
const [isSuccess, setIsSuccess] = useState(false);
|
|
16541
16586
|
const [successPaymentId, setSuccessPaymentId] = useState(null);
|
|
16542
16587
|
const [systemConfig, setSystemConfig] = useState(null);
|
|
16588
|
+
const [waitlistEnabled, setWaitlistEnabled] = useState(false);
|
|
16543
16589
|
// When true, loadEventInstances skips the single-instance auto-select (used by handleShowAllEvents)
|
|
16544
16590
|
const skipInstanceAutoSelectRef = useRef(false);
|
|
16545
16591
|
// PERFORMANCE OPTIMIZATION: Lazy component loading
|
|
@@ -17033,6 +17079,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17033
17079
|
}
|
|
17034
17080
|
extractGoogleAdsConfig(data);
|
|
17035
17081
|
setEventInstances(data.eventInstances);
|
|
17082
|
+
setWaitlistEnabled(data.waitlistEnabled ?? false);
|
|
17036
17083
|
if (data.paymentProvider) {
|
|
17037
17084
|
setSystemConfig({
|
|
17038
17085
|
paymentProvider: data.paymentProvider,
|
|
@@ -17601,7 +17648,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17601
17648
|
}, isOpen: currentStep === "eventInstances", onClose: () => {
|
|
17602
17649
|
setShowingPreview(true);
|
|
17603
17650
|
setCurrentStep("eventTypes");
|
|
17604
|
-
}, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
17651
|
+
}, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId, waitlistEnabled: waitlistEnabled })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
17605
17652
|
setIsSuccess(false);
|
|
17606
17653
|
setCurrentStep("eventTypes");
|
|
17607
17654
|
setShowingPreview(true);
|
|
@@ -17664,7 +17711,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17664
17711
|
}, children: [isButtonBusy && jsx(Spinner, { size: 20, borderColor: "var(--bw-button-text-color, #ffffff)" }), config.buttonText ||
|
|
17665
17712
|
(isDirectInstanceMode || selectedEventType?.bookingMode === "freeform"
|
|
17666
17713
|
? t("button.bookNow")
|
|
17667
|
-
: t("button.viewDates"))] }), shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId })), 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, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), shouldRenderFreeformSelection && selectedEventType?.bookingMode === "freeform" && (jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17714
|
+
: t("button.viewDates"))] }), shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: () => setSidebarOpen(false), isOpen: sidebarOpen && currentStep === "eventInstances", onClose: () => setSidebarOpen(false), isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId, waitlistEnabled: waitlistEnabled })), 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, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), shouldRenderFreeformSelection && selectedEventType?.bookingMode === "freeform" && (jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17668
17715
|
setCurrentStep("eventTypes");
|
|
17669
17716
|
setSidebarOpen(false);
|
|
17670
17717
|
setShouldRenderFreeformSelection(false);
|
|
@@ -17689,7 +17736,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17689
17736
|
}, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
|
|
17690
17737
|
}
|
|
17691
17738
|
// Cards mode (default) - show event type selection with optional voucher card
|
|
17692
|
-
const cardsView = (jsxs(Fragment, { children: [hasEventSelection && (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 && (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 && (jsx("div", { style: { padding: "24px", textAlign: "center" }, children: jsx("div", { style: {
|
|
17739
|
+
const cardsView = (jsxs(Fragment, { children: [hasEventSelection && (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 && (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 && (jsx("div", { style: { padding: "24px", textAlign: "center" }, children: jsx("div", { style: {
|
|
17693
17740
|
display: "inline-block",
|
|
17694
17741
|
width: "32px",
|
|
17695
17742
|
height: "32px",
|
|
@@ -17730,7 +17777,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
17730
17777
|
};
|
|
17731
17778
|
};
|
|
17732
17779
|
const backHandlers = getBackHandlers();
|
|
17733
|
-
return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId })), 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, 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" && (jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17780
|
+
return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, children: [cardsView, shouldRenderInstanceSelection && (jsx(EventInstanceSelection, { eventInstances: eventInstances, selectedEventType: selectedEventType, onEventInstanceSelect: handleEventInstanceSelect, onBackToEventTypes: handleBackToEventTypes, isOpen: currentStep === "eventInstances", onClose: handleBackToEventTypes, isLoadingEventInstances: isLoadingEventInstances, isLoadingEventDetails: isLoadingEventDetails, hasUpsellsStep: hasUpsellsFlowStep, apiBaseUrl: config.apiBaseUrl, organizationId: config.organizationId, waitlistEnabled: waitlistEnabled })), 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, 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" && (jsx(FreeformSelection, { config: config, eventType: selectedEventType, isOpen: currentStep === "freeform", onClose: () => {
|
|
17734
17781
|
setCurrentStep("eventTypes");
|
|
17735
17782
|
setShouldRenderFreeformSelection(false);
|
|
17736
17783
|
}, onSuccess: handleBookingSuccess, onError: handleBookingError, systemConfig: systemConfig })), jsx(BookingSuccessModal, { isOpen: isSuccess && !voucherPurchaseResult, onClose: () => {
|