@bigz-app/booking-widget 1.4.2 → 1.4.3
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 +119 -70
- package/dist/booking-widget.js.map +1 -1
- package/dist/components/UniversalBookingWidget.d.ts.map +1 -1
- package/dist/components/events/EventTypeSelection.d.ts.map +1 -1
- package/dist/components/events/NextEventsPreview.d.ts.map +1 -1
- package/dist/index.cjs +119 -70
- package/dist/index.cjs.map +1 -1
- package/dist/index.esm.js +119 -70
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
package/dist/index.esm.js
CHANGED
|
@@ -14132,7 +14132,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14132
14132
|
padding: "2px 8px",
|
|
14133
14133
|
borderRadius: "var(--bw-border-radius)",
|
|
14134
14134
|
fontFamily: "var(--bw-font-family)",
|
|
14135
|
-
}, children: eventType.category.name }) }), jsx("div", { className: "event-type-img", style: { position: "relative", width: "100%", height: "300px" }, children: jsx(ImageCarousel, { images: eventType.images, eventName: eventType.name }) }), jsxs("div", { className: "event-type-content", style: {
|
|
14135
|
+
}, children: eventType.category.name }) }), eventType.images && eventType.images.length > 0 && (jsx("div", { className: "event-type-img", style: { position: "relative", width: "100%", height: "300px" }, children: jsx(ImageCarousel, { images: eventType.images, eventName: eventType.name }) })), jsxs("div", { className: "event-type-content", style: {
|
|
14136
14136
|
padding: "12px 18px",
|
|
14137
14137
|
display: "flex",
|
|
14138
14138
|
flexDirection: "column",
|
|
@@ -14275,8 +14275,7 @@ function EventTypeSelection({ eventTypes, onEventTypeSelect, onInstancePreview,
|
|
|
14275
14275
|
alignItems: "center",
|
|
14276
14276
|
marginTop: "10px",
|
|
14277
14277
|
gap: "12px",
|
|
14278
|
-
}, children: [
|
|
14279
|
-
(eventType.highlights && eventType.highlights.length > 0)) && (jsx("button", { onClick: (e) => {
|
|
14278
|
+
}, children: [eventType.description && (jsx("button", { onClick: (e) => {
|
|
14280
14279
|
e.stopPropagation();
|
|
14281
14280
|
handleShowDetails(eventType);
|
|
14282
14281
|
}, style: {
|
|
@@ -14840,55 +14839,44 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
|
|
|
14840
14839
|
gap: "8px",
|
|
14841
14840
|
}, children: [jsx("span", { style: { fontSize: "16px" }, children: "\uD83D\uDD04" }), t("common.reload")] })] }) }));
|
|
14842
14841
|
}
|
|
14842
|
+
const today = new Date();
|
|
14843
14843
|
return (jsxs("div", { style: {
|
|
14844
14844
|
maxWidth: "500px",
|
|
14845
14845
|
margin: "0 auto",
|
|
14846
14846
|
padding: "12px 16px",
|
|
14847
14847
|
fontFamily: "var(--bw-font-family)",
|
|
14848
|
-
}, children: [jsx("div", { style: { display: "flex", flexDirection: "column", gap: "
|
|
14848
|
+
}, children: [jsx("div", { style: { display: "flex", flexDirection: "column", gap: "12px", marginBottom: "10px" }, children: events.map((event) => {
|
|
14849
14849
|
const availableSpots = event.maxParticipants - event.participantCount;
|
|
14850
14850
|
const isFullyBooked = availableSpots === 0;
|
|
14851
14851
|
const startDate = new Date(event.startTime);
|
|
14852
|
-
const today = new Date();
|
|
14853
14852
|
const isPastEvent = today.toISOString() >= startDate.toISOString();
|
|
14854
|
-
const isFullAvailability = availableSpots / event.maxParticipants >= 0.8;
|
|
14855
|
-
const isHighAvailability = availableSpots / event.maxParticipants >= 0.5;
|
|
14856
|
-
const isMediumAvailability = availableSpots / event.maxParticipants >= 0.3;
|
|
14857
|
-
const isLowAvailability = availableSpots / event.maxParticipants >= 0.15;
|
|
14858
|
-
const getAvailabilityColor = () => {
|
|
14859
|
-
if (isFullAvailability)
|
|
14860
|
-
return "var(--bw-success-color)";
|
|
14861
|
-
if (isHighAvailability)
|
|
14862
|
-
return "var(--bw-warning-color)";
|
|
14863
|
-
if (isMediumAvailability)
|
|
14864
|
-
return "var(--bw-availability-medium-color, #f97316)";
|
|
14865
|
-
if (isLowAvailability)
|
|
14866
|
-
return "var(--bw-availability-low-color, #8b5cf6)";
|
|
14867
|
-
return "var(--bw-highlight-color)";
|
|
14868
|
-
};
|
|
14869
14853
|
const isDisabled = isFullyBooked || isPastEvent || !event.bookingOpen;
|
|
14854
|
+
const availabilityRatio = availableSpots / event.maxParticipants;
|
|
14855
|
+
const allocationBadge = (() => {
|
|
14856
|
+
if (availabilityRatio >= 0.6)
|
|
14857
|
+
return null;
|
|
14858
|
+
if (availabilityRatio === 0)
|
|
14859
|
+
return { text: t("events.soldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
|
|
14860
|
+
if (availabilityRatio <= 0.3)
|
|
14861
|
+
return { text: t("instances.almostSoldOut"), backgroundColor: "#7f1d1d", textColor: "#fca5a5" };
|
|
14862
|
+
return { text: t("instances.popularDate"), backgroundColor: "#b45309", textColor: "#fbbf24" };
|
|
14863
|
+
})();
|
|
14864
|
+
const sameDay = formatWeekday(event.startTime, timezone, locale) === formatWeekday(event.endTime, timezone, locale);
|
|
14870
14865
|
return (jsxs("div", { style: {
|
|
14871
14866
|
position: "relative",
|
|
14872
|
-
|
|
14873
|
-
|
|
14867
|
+
border: "1px solid var(--bw-border-color)",
|
|
14868
|
+
backgroundColor: "var(--bw-surface-color)",
|
|
14869
|
+
borderRadius: "var(--bw-border-radius)",
|
|
14870
|
+
padding: "16px 10px",
|
|
14874
14871
|
transition: "all 0.2s ease",
|
|
14875
|
-
border: "1px solid transparent",
|
|
14876
14872
|
fontFamily: "var(--bw-font-family)",
|
|
14877
14873
|
opacity: isDisabled ? 0.3 : 1,
|
|
14878
|
-
filter: isDisabled ? "grayscale(
|
|
14874
|
+
filter: isDisabled ? "grayscale(40%)" : "none",
|
|
14879
14875
|
cursor: isDisabled ? "not-allowed" : "pointer",
|
|
14880
14876
|
}, onClick: () => {
|
|
14881
14877
|
if (!isDisabled) {
|
|
14882
14878
|
handleEventSelect(event.id);
|
|
14883
14879
|
}
|
|
14884
|
-
}, onMouseEnter: (hoverEvent) => {
|
|
14885
|
-
if (!isDisabled) {
|
|
14886
|
-
hoverEvent.currentTarget.style.backgroundColor = "var(--bw-surface-color)";
|
|
14887
|
-
hoverEvent.currentTarget.style.borderColor = getAvailabilityColor();
|
|
14888
|
-
}
|
|
14889
|
-
}, onMouseLeave: (hoverEvent) => {
|
|
14890
|
-
hoverEvent.currentTarget.style.backgroundColor = "transparent";
|
|
14891
|
-
hoverEvent.currentTarget.style.borderColor = "transparent";
|
|
14892
14880
|
}, children: [selectedEventInstanceId === event.id && isLoadingEventDetails && (jsx("div", { style: {
|
|
14893
14881
|
position: "absolute",
|
|
14894
14882
|
inset: 0,
|
|
@@ -14897,37 +14885,71 @@ function NextEventsPreview({ events, onEventSelect, onShowAll, showAllButtonText
|
|
|
14897
14885
|
justifyContent: "center",
|
|
14898
14886
|
backgroundColor: "rgba(15, 23, 42, 0.8)",
|
|
14899
14887
|
borderRadius: "var(--bw-border-radius)",
|
|
14900
|
-
}, children: jsx("div", { style: {
|
|
14901
|
-
|
|
14902
|
-
|
|
14903
|
-
|
|
14904
|
-
|
|
14905
|
-
|
|
14906
|
-
|
|
14907
|
-
|
|
14908
|
-
|
|
14909
|
-
|
|
14910
|
-
|
|
14911
|
-
|
|
14888
|
+
}, children: jsx("div", { style: { width: "32px", height: "32px", color: "var(--bw-highlight-color)", opacity: 0.8, fontSize: "32px" }, children: "\u27F3" }) })), jsx("div", { style: {
|
|
14889
|
+
display: "flex",
|
|
14890
|
+
marginLeft: "auto",
|
|
14891
|
+
marginTop: "-20px",
|
|
14892
|
+
marginBottom: "4px",
|
|
14893
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
14894
|
+
fontFamily: "var(--bw-font-family)",
|
|
14895
|
+
zIndex: 50,
|
|
14896
|
+
whiteSpace: "nowrap",
|
|
14897
|
+
width: "fit-content",
|
|
14898
|
+
fontSize: "11px",
|
|
14899
|
+
fontWeight: 700,
|
|
14900
|
+
padding: "2px 8px",
|
|
14901
|
+
backgroundColor: allocationBadge?.backgroundColor || "transparent",
|
|
14902
|
+
color: allocationBadge?.textColor || "transparent",
|
|
14903
|
+
}, children: allocationBadge?.text || " - " }), jsxs("div", { style: {
|
|
14904
|
+
display: "flex",
|
|
14905
|
+
justifyContent: "space-between",
|
|
14912
14906
|
width: "100%",
|
|
14913
|
-
|
|
14914
|
-
|
|
14915
|
-
|
|
14916
|
-
|
|
14917
|
-
|
|
14918
|
-
|
|
14919
|
-
|
|
14920
|
-
|
|
14921
|
-
|
|
14922
|
-
|
|
14923
|
-
|
|
14924
|
-
|
|
14925
|
-
|
|
14926
|
-
|
|
14927
|
-
|
|
14928
|
-
|
|
14929
|
-
|
|
14930
|
-
|
|
14907
|
+
alignItems: "flex-start",
|
|
14908
|
+
gap: "12px",
|
|
14909
|
+
marginBottom: "4px",
|
|
14910
|
+
}, children: [jsxs("div", { style: { display: "flex", alignItems: "flex-start", gap: "12px" }, children: [jsx("div", { style: {
|
|
14911
|
+
fontSize: "16px",
|
|
14912
|
+
transition: "all 0.2s ease",
|
|
14913
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
14914
|
+
borderTop: "4px solid var(--bw-border-color)",
|
|
14915
|
+
border: "1px solid var(--bw-border-color)",
|
|
14916
|
+
width: "40px",
|
|
14917
|
+
height: "40px",
|
|
14918
|
+
display: "flex",
|
|
14919
|
+
alignItems: "center",
|
|
14920
|
+
justifyContent: "center",
|
|
14921
|
+
fontWeight: 700,
|
|
14922
|
+
color: "var(--bw-text-color)",
|
|
14923
|
+
backgroundColor: "var(--bw-background-color)",
|
|
14924
|
+
}, children: startDate.getDate() }), jsxs("div", { style: {
|
|
14925
|
+
fontSize: "16px",
|
|
14926
|
+
color: "var(--bw-text-color)",
|
|
14927
|
+
display: "flex",
|
|
14928
|
+
flexDirection: "column",
|
|
14929
|
+
alignItems: "flex-start",
|
|
14930
|
+
justifyContent: "flex-start",
|
|
14931
|
+
lineHeight: 1.25,
|
|
14932
|
+
}, children: [jsxs("div", { children: [jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.startTime, timezone, locale) }), !sameDay && (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { fontWeight: 600, marginBottom: "2px", textTransform: "capitalize" }, children: formatWeekday(event.endTime, timezone, locale) })] }))] }), jsx("div", { children: sameDay ? (jsxs(Fragment, { children: [jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.startTime, timezone, locale) }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: " - " }), jsx("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: formatTime(event.endTime, timezone, locale) })] })) : (jsxs("span", { style: { color: "var(--bw-text-muted)", fontSize: "14px" }, children: [formatTime(event.startTime, timezone, locale), " ", t("instances.oclock")] })) })] }), jsxs("span", { style: {
|
|
14933
|
+
fontSize: "12px",
|
|
14934
|
+
fontWeight: 400,
|
|
14935
|
+
color: "var(--bw-text-muted)",
|
|
14936
|
+
marginLeft: "6px",
|
|
14937
|
+
backgroundColor: "rgba(0, 0, 0, 0.05)",
|
|
14938
|
+
whiteSpace: "nowrap",
|
|
14939
|
+
padding: "2px 6px",
|
|
14940
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
14941
|
+
}, children: [event.durationDays, " ", event.durationDays > 1 ? t("common.days") : t("common.day")] })] }), jsxs("div", { style: { textAlign: "right", display: "flex", flexDirection: "column", alignItems: "flex-end", gap: "4px" }, children: [jsx("span", { style: {
|
|
14942
|
+
display: "inline-flex",
|
|
14943
|
+
alignItems: "center",
|
|
14944
|
+
fontSize: "16px",
|
|
14945
|
+
fontWeight: 600,
|
|
14946
|
+
padding: "2px 8px",
|
|
14947
|
+
borderRadius: "var(--bw-border-radius-small)",
|
|
14948
|
+
fontFamily: "var(--bw-font-family)",
|
|
14949
|
+
backgroundColor: "var(--bw-background-color)",
|
|
14950
|
+
color: "var(--bw-text-color)",
|
|
14951
|
+
border: "1px solid var(--bw-border-color)",
|
|
14952
|
+
}, children: event.price !== null ? formatCurrency(event.price) : t("nextEvents.priceOnRequest") }), event.notes && jsx(InfoBadge, { text: event.notes })] })] })] }, event.id));
|
|
14931
14953
|
}) }), showAllButton && (jsx("div", { style: { textAlign: "center" }, children: jsx("button", { type: "button", disabled: isLoadingShowAll, style: {
|
|
14932
14954
|
display: "inline-flex",
|
|
14933
14955
|
alignItems: "center",
|
|
@@ -15748,6 +15770,8 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
15748
15770
|
const [isSuccess, setIsSuccess] = useState(false);
|
|
15749
15771
|
const [successPaymentId, setSuccessPaymentId] = useState(null);
|
|
15750
15772
|
const [systemConfig, setSystemConfig] = useState(null);
|
|
15773
|
+
// When true, loadEventInstances skips the single-instance auto-select (used by handleShowAllEvents)
|
|
15774
|
+
const skipInstanceAutoSelectRef = useRef(false);
|
|
15751
15775
|
// PERFORMANCE OPTIMIZATION: Lazy component loading
|
|
15752
15776
|
const [shouldRenderInstanceSelection, setShouldRenderInstanceSelection] = useState(false);
|
|
15753
15777
|
const [shouldRenderUpsells, setShouldRenderUpsells] = useState(false);
|
|
@@ -16243,7 +16267,7 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16243
16267
|
}
|
|
16244
16268
|
setStripePromise(loadStripe(data.stripePublishableKey, stripeOptions));
|
|
16245
16269
|
}
|
|
16246
|
-
if (data.eventInstances.length === 1) {
|
|
16270
|
+
if (!skipInstanceAutoSelectRef.current && data.eventInstances.length === 1) {
|
|
16247
16271
|
setSelectedEventInstance(data.eventInstances[0]);
|
|
16248
16272
|
setCurrentStep("booking");
|
|
16249
16273
|
await loadEventDetails(data.eventInstances[0].id);
|
|
@@ -16638,12 +16662,30 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16638
16662
|
const handleShowAllEvents = async () => {
|
|
16639
16663
|
setIsLoadingShowAll(true);
|
|
16640
16664
|
try {
|
|
16641
|
-
if (isSingleEventTypeMode
|
|
16665
|
+
if (isSingleEventTypeMode) {
|
|
16666
|
+
// Lock in the correct render branch before any async work so no
|
|
16667
|
+
// intermediate state can accidentally show the cards view.
|
|
16642
16668
|
setShouldRenderInstanceSelection(true);
|
|
16643
|
-
setIsLoadingEventInstances(true);
|
|
16644
|
-
await loadEventInstances(selectedEventType.id);
|
|
16645
16669
|
setCurrentStep("eventInstances");
|
|
16646
16670
|
setShowingPreview(false);
|
|
16671
|
+
setIsLoadingEventInstances(true);
|
|
16672
|
+
// Suppress the single-instance auto-select inside loadEventInstances
|
|
16673
|
+
// so it doesn't override currentStep to "booking" mid-flight.
|
|
16674
|
+
skipInstanceAutoSelectRef.current = true;
|
|
16675
|
+
try {
|
|
16676
|
+
if (selectedEventType) {
|
|
16677
|
+
await loadEventInstances(selectedEventType.id);
|
|
16678
|
+
}
|
|
16679
|
+
else {
|
|
16680
|
+
// next-events mode skips event type loading on init.
|
|
16681
|
+
// loadEventTypes sets selectedEventType (for the sidebar title)
|
|
16682
|
+
// and internally calls loadEventInstances (auto-select suppressed).
|
|
16683
|
+
await loadEventTypes();
|
|
16684
|
+
}
|
|
16685
|
+
}
|
|
16686
|
+
finally {
|
|
16687
|
+
skipInstanceAutoSelectRef.current = false;
|
|
16688
|
+
}
|
|
16647
16689
|
setIsLoadingEventInstances(false);
|
|
16648
16690
|
}
|
|
16649
16691
|
else {
|
|
@@ -16806,12 +16848,17 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16806
16848
|
}, config: config, googleAdsConfig: googleAdsConfig, onError: setError, paymentIntentId: successPaymentId })] }), showPromoDialog && config.promo && (jsx(PromoDialog, { config: config.promo, onClose: handlePromoDialogClose, onCtaClick: handlePromoCtaClick }))] }));
|
|
16807
16849
|
}
|
|
16808
16850
|
if (viewMode === "button" && (isSingleEventTypeMode || isDirectInstanceMode)) {
|
|
16851
|
+
const isButtonBusy = (isDirectInstanceMode && isLoadingEventDetails) ||
|
|
16852
|
+
(!isDirectInstanceMode && (isLoadingEventInstances || (shouldRenderInstanceSelection && !sidebarOpen)));
|
|
16809
16853
|
return (jsxs(StyleProvider, { config: config, children: [jsxs("div", { ref: setWidgetContainerRef, style: {
|
|
16810
16854
|
display: "flex",
|
|
16811
16855
|
justifyContent: "center",
|
|
16812
16856
|
alignItems: "center",
|
|
16813
16857
|
minHeight: "120px",
|
|
16814
|
-
}, children: [
|
|
16858
|
+
}, children: [jsxs("button", { type: "button", disabled: isButtonBusy, style: {
|
|
16859
|
+
display: "inline-flex",
|
|
16860
|
+
alignItems: "center",
|
|
16861
|
+
gap: "10px",
|
|
16815
16862
|
backgroundColor: "var(--bw-highlight-color)",
|
|
16816
16863
|
color: "white",
|
|
16817
16864
|
padding: "16px 32px",
|
|
@@ -16821,7 +16868,9 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16821
16868
|
fontWeight: 600,
|
|
16822
16869
|
fontFamily: "var(--bw-font-family)",
|
|
16823
16870
|
boxShadow: "var(--bw-shadow-md)",
|
|
16824
|
-
cursor: "pointer",
|
|
16871
|
+
cursor: isButtonBusy ? "default" : "pointer",
|
|
16872
|
+
opacity: isButtonBusy ? 0.85 : 1,
|
|
16873
|
+
transition: "opacity 0.2s ease",
|
|
16825
16874
|
}, onClick: () => {
|
|
16826
16875
|
if (isDirectInstanceMode) {
|
|
16827
16876
|
setCurrentStep("booking");
|
|
@@ -16832,8 +16881,8 @@ function UniversalBookingWidgetInner({ config: baseConfig, onWidgetLanguage, onT
|
|
|
16832
16881
|
setSidebarOpen(true);
|
|
16833
16882
|
setShouldRenderInstanceSelection(true);
|
|
16834
16883
|
}
|
|
16835
|
-
}, children: config.buttonText ||
|
|
16836
|
-
|
|
16884
|
+
}, children: [isButtonBusy && jsx(Spinner, { size: 20, borderColor: "white" }), config.buttonText ||
|
|
16885
|
+
(isDirectInstanceMode ? t("button.bookNow") : 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 })), shouldRenderUpsells && (jsx(UpsellsStep, { upsells: upsells, selectedUpsells: selectedUpsells, participantCount: tempParticipantCount, isLoading: isLoadingUpsells, isOpen: currentStep === "upsells", onClose: () => setCurrentStep("eventInstances"), onSelect: handleUpsellsSelect, onContinue: handleUpsellsContinue, onBack: handleUpsellsBack })), shouldRenderBookingForm && eventDetails && (jsx(BookingForm, { config: config, eventDetails: eventDetails, stripePromise: stripePromise, onSuccess: handleBookingSuccess, onError: handleBookingError, isOpen: currentStep === "booking" && !!eventDetails, onClose: handleBackFromBooking, systemConfig: systemConfig, selectedUpsells: selectedUpsells, upsells: upsells, persistedState: bookingPersistedState, onPersistedStateChange: setBookingPersistedState })), jsx(BookingSuccessModal, { isOpen: isSuccess, onClose: () => {
|
|
16837
16886
|
setIsSuccess(false);
|
|
16838
16887
|
setCurrentStep("eventTypes");
|
|
16839
16888
|
setSidebarOpen(false);
|