@resira/ui 0.4.0 → 0.4.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/README.md +238 -238
- package/dist/index.cjs +257 -33
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +37 -6
- package/dist/index.d.ts +37 -6
- package/dist/index.js +257 -34
- package/dist/index.js.map +1 -1
- package/dist/styles.css +2879 -2809
- package/package.json +59 -59
package/dist/index.d.cts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Product, WeightedBaseUrl, Resira, RefundRule, TimeSlotAvailability, DurationPrice, PublicResource, ValidatePromoCodeResponse, Reservation, AvailabilityParams, Availability, Dish, PaymentIntentResponse, CreatePaymentIntentRequest, CreateReservationRequest } from '@resira/sdk';
|
|
4
|
-
export { ConfirmPaymentRequest, ConfirmPaymentResponse, CreatePaymentIntentRequest, Dish, DishListResponse, DishModel, DishResponse, PaymentIntentResponse, PricingModel, Product, ProductListResponse, PublicResource, ResourceListResponse } from '@resira/sdk';
|
|
3
|
+
import { Product, WeightedBaseUrl, Resira, RefundRule, TimeSlotAvailability, DurationPrice, PublicResource, ValidatePromoCodeResponse, Reservation, AvailabilityParams, Availability, CheckoutSession, Dish, PaymentIntentResponse, CreatePaymentIntentRequest, CreateReservationRequest } from '@resira/sdk';
|
|
4
|
+
export { CheckoutConfig, CheckoutSession, CheckoutSessionResponse, ConfirmPaymentRequest, ConfirmPaymentResponse, CreateCheckoutSessionRequest, CreateCheckoutSessionResponse, CreatePaymentIntentRequest, Dish, DishListResponse, DishModel, DishResponse, PaymentIntentResponse, PricingModel, Product, ProductListResponse, ProductVariant, PublicResource, ResourceListResponse } from '@resira/sdk';
|
|
5
5
|
|
|
6
6
|
type ResiraDomain = "rental" | "restaurant" | "watersport" | "service";
|
|
7
7
|
/** Layout direction for the product/service selector. */
|
|
@@ -320,6 +320,8 @@ interface ResiraProviderProps {
|
|
|
320
320
|
domain: ResiraDomain;
|
|
321
321
|
/** Configuration overrides. */
|
|
322
322
|
config?: ResiraProviderConfig;
|
|
323
|
+
/** Checkout session token. When provided, skips service selection and opens directly into checkout. */
|
|
324
|
+
checkoutSessionToken?: string;
|
|
323
325
|
/** Callback when the modal/widget should close. */
|
|
324
326
|
onClose?: () => void;
|
|
325
327
|
/** Child components. */
|
|
@@ -392,9 +394,11 @@ interface ResiraContextValue {
|
|
|
392
394
|
}) => void;
|
|
393
395
|
/** Called when an error occurs during the booking flow. */
|
|
394
396
|
onError?: (code: string, message: string) => void;
|
|
397
|
+
/** Checkout session token — when provided, the widget skips to checkout. */
|
|
398
|
+
checkoutSessionToken?: string;
|
|
395
399
|
}
|
|
396
400
|
/** Steps in the booking flow. */
|
|
397
|
-
type BookingStep = "resource" | "availability" | "details" | "terms" | "payment" | "confirmation";
|
|
401
|
+
type BookingStep = "resource" | "availability" | "details" | "terms" | "payment" | "confirmation" | "checkout";
|
|
398
402
|
/** Selection state from the availability step. */
|
|
399
403
|
interface BookingSelection {
|
|
400
404
|
/** Selected start date (YYYY-MM-DD). */
|
|
@@ -438,7 +442,7 @@ declare function useResira(): ResiraContextValue;
|
|
|
438
442
|
* </ResiraProvider>
|
|
439
443
|
* ```
|
|
440
444
|
*/
|
|
441
|
-
declare function ResiraProvider({ apiKey, resourceId, domain, config, onClose, children, }: ResiraProviderProps): react_jsx_runtime.JSX.Element;
|
|
445
|
+
declare function ResiraProvider({ apiKey, resourceId, domain, config, checkoutSessionToken, onClose, children, }: ResiraProviderProps): react_jsx_runtime.JSX.Element;
|
|
442
446
|
|
|
443
447
|
declare function ResiraBookingWidget(): react_jsx_runtime.JSX.Element;
|
|
444
448
|
|
|
@@ -451,6 +455,8 @@ interface BookingModalProps {
|
|
|
451
455
|
resourceId?: string;
|
|
452
456
|
/** Configuration overrides. */
|
|
453
457
|
config?: ResiraProviderConfig;
|
|
458
|
+
/** Checkout session token. When provided, skips to checkout. */
|
|
459
|
+
checkoutSessionToken?: string;
|
|
454
460
|
/** Custom trigger button — if omitted, uses the default "Book Now" button. */
|
|
455
461
|
trigger?: React.ReactNode;
|
|
456
462
|
/** Custom button label. @default "Book Now" */
|
|
@@ -460,7 +466,7 @@ interface BookingModalProps {
|
|
|
460
466
|
/** Custom button style. */
|
|
461
467
|
buttonStyle?: React.CSSProperties;
|
|
462
468
|
}
|
|
463
|
-
declare function BookingModal({ apiKey, domain, resourceId, config, trigger, buttonLabel, buttonClassName, buttonStyle, }: BookingModalProps): react_jsx_runtime.JSX.Element;
|
|
469
|
+
declare function BookingModal({ apiKey, domain, resourceId, config, checkoutSessionToken, trigger, buttonLabel, buttonClassName, buttonStyle, }: BookingModalProps): react_jsx_runtime.JSX.Element;
|
|
464
470
|
|
|
465
471
|
interface BookingCalendarProps {
|
|
466
472
|
/** Set of blocked/unavailable dates (YYYY-MM-DD). */
|
|
@@ -759,6 +765,31 @@ interface UseDishesReturn {
|
|
|
759
765
|
* ```
|
|
760
766
|
*/
|
|
761
767
|
declare function useDishes(enabled?: boolean): UseDishesReturn;
|
|
768
|
+
/** Checkout session error codes for UX branching. */
|
|
769
|
+
type CheckoutSessionErrorCode = "not_found" | "consumed" | "expired" | "unknown";
|
|
770
|
+
interface UseCheckoutSessionReturn {
|
|
771
|
+
/** The hydrated checkout session. */
|
|
772
|
+
session: CheckoutSession | null;
|
|
773
|
+
/** Whether the session is loading. */
|
|
774
|
+
loading: boolean;
|
|
775
|
+
/** Error message if loading failed. */
|
|
776
|
+
error: string | null;
|
|
777
|
+
/** Structured error code for UX branching. */
|
|
778
|
+
errorCode: CheckoutSessionErrorCode | null;
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Fetch and hydrate a checkout session by token.
|
|
782
|
+
*
|
|
783
|
+
* Handles the three error cases from the API:
|
|
784
|
+
* - 404 → "Invalid booking link"
|
|
785
|
+
* - "already consumed" → "This booking was already completed"
|
|
786
|
+
* - "expired" → "Session expired"
|
|
787
|
+
*
|
|
788
|
+
* ```tsx
|
|
789
|
+
* const { session, loading, error, errorCode } = useCheckoutSession("cs_ab12cd34...");
|
|
790
|
+
* ```
|
|
791
|
+
*/
|
|
792
|
+
declare function useCheckoutSession(token: string | undefined): UseCheckoutSessionReturn;
|
|
762
793
|
|
|
763
794
|
/** Default theme values. */
|
|
764
795
|
declare const DEFAULT_THEME: Required<ResiraTheme>;
|
|
@@ -798,4 +829,4 @@ declare function TagIcon({ size, className }: IconProps): react_jsx_runtime.JSX.
|
|
|
798
829
|
declare function CubeIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
|
|
799
830
|
declare function ViewfinderIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
|
|
800
831
|
|
|
801
|
-
export { AlertCircleIcon, BookingCalendar, BookingModal, type BookingSelection, type BookingStep, CalendarIcon, CheckCircleIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, type DeeplinkGuest, type DeeplinkSelection, DishShowcase, type DishShowcaseProps, type DomainConfig, GuestForm, type GuestFormErrors, type GuestFormValues, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, type ResiraClassNames, type ResiraContextValue, type ResiraDomain, type ResiraLocale, ResiraProvider, type ResiraProviderConfig, type ResiraProviderProps, type ResiraTheme, ResourcePicker, type ServiceLayout, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };
|
|
832
|
+
export { AlertCircleIcon, BookingCalendar, BookingModal, type BookingSelection, type BookingStep, CalendarIcon, CheckCircleIcon, CheckIcon, type CheckoutSessionErrorCode, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, type DeeplinkGuest, type DeeplinkSelection, DishShowcase, type DishShowcaseProps, type DomainConfig, GuestForm, type GuestFormErrors, type GuestFormValues, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, type ResiraClassNames, type ResiraContextValue, type ResiraDomain, type ResiraLocale, ResiraProvider, type ResiraProviderConfig, type ResiraProviderProps, type ResiraTheme, ResourcePicker, type ServiceLayout, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useCheckoutSession, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import React from 'react';
|
|
3
|
-
import { Product, WeightedBaseUrl, Resira, RefundRule, TimeSlotAvailability, DurationPrice, PublicResource, ValidatePromoCodeResponse, Reservation, AvailabilityParams, Availability, Dish, PaymentIntentResponse, CreatePaymentIntentRequest, CreateReservationRequest } from '@resira/sdk';
|
|
4
|
-
export { ConfirmPaymentRequest, ConfirmPaymentResponse, CreatePaymentIntentRequest, Dish, DishListResponse, DishModel, DishResponse, PaymentIntentResponse, PricingModel, Product, ProductListResponse, PublicResource, ResourceListResponse } from '@resira/sdk';
|
|
3
|
+
import { Product, WeightedBaseUrl, Resira, RefundRule, TimeSlotAvailability, DurationPrice, PublicResource, ValidatePromoCodeResponse, Reservation, AvailabilityParams, Availability, CheckoutSession, Dish, PaymentIntentResponse, CreatePaymentIntentRequest, CreateReservationRequest } from '@resira/sdk';
|
|
4
|
+
export { CheckoutConfig, CheckoutSession, CheckoutSessionResponse, ConfirmPaymentRequest, ConfirmPaymentResponse, CreateCheckoutSessionRequest, CreateCheckoutSessionResponse, CreatePaymentIntentRequest, Dish, DishListResponse, DishModel, DishResponse, PaymentIntentResponse, PricingModel, Product, ProductListResponse, ProductVariant, PublicResource, ResourceListResponse } from '@resira/sdk';
|
|
5
5
|
|
|
6
6
|
type ResiraDomain = "rental" | "restaurant" | "watersport" | "service";
|
|
7
7
|
/** Layout direction for the product/service selector. */
|
|
@@ -320,6 +320,8 @@ interface ResiraProviderProps {
|
|
|
320
320
|
domain: ResiraDomain;
|
|
321
321
|
/** Configuration overrides. */
|
|
322
322
|
config?: ResiraProviderConfig;
|
|
323
|
+
/** Checkout session token. When provided, skips service selection and opens directly into checkout. */
|
|
324
|
+
checkoutSessionToken?: string;
|
|
323
325
|
/** Callback when the modal/widget should close. */
|
|
324
326
|
onClose?: () => void;
|
|
325
327
|
/** Child components. */
|
|
@@ -392,9 +394,11 @@ interface ResiraContextValue {
|
|
|
392
394
|
}) => void;
|
|
393
395
|
/** Called when an error occurs during the booking flow. */
|
|
394
396
|
onError?: (code: string, message: string) => void;
|
|
397
|
+
/** Checkout session token — when provided, the widget skips to checkout. */
|
|
398
|
+
checkoutSessionToken?: string;
|
|
395
399
|
}
|
|
396
400
|
/** Steps in the booking flow. */
|
|
397
|
-
type BookingStep = "resource" | "availability" | "details" | "terms" | "payment" | "confirmation";
|
|
401
|
+
type BookingStep = "resource" | "availability" | "details" | "terms" | "payment" | "confirmation" | "checkout";
|
|
398
402
|
/** Selection state from the availability step. */
|
|
399
403
|
interface BookingSelection {
|
|
400
404
|
/** Selected start date (YYYY-MM-DD). */
|
|
@@ -438,7 +442,7 @@ declare function useResira(): ResiraContextValue;
|
|
|
438
442
|
* </ResiraProvider>
|
|
439
443
|
* ```
|
|
440
444
|
*/
|
|
441
|
-
declare function ResiraProvider({ apiKey, resourceId, domain, config, onClose, children, }: ResiraProviderProps): react_jsx_runtime.JSX.Element;
|
|
445
|
+
declare function ResiraProvider({ apiKey, resourceId, domain, config, checkoutSessionToken, onClose, children, }: ResiraProviderProps): react_jsx_runtime.JSX.Element;
|
|
442
446
|
|
|
443
447
|
declare function ResiraBookingWidget(): react_jsx_runtime.JSX.Element;
|
|
444
448
|
|
|
@@ -451,6 +455,8 @@ interface BookingModalProps {
|
|
|
451
455
|
resourceId?: string;
|
|
452
456
|
/** Configuration overrides. */
|
|
453
457
|
config?: ResiraProviderConfig;
|
|
458
|
+
/** Checkout session token. When provided, skips to checkout. */
|
|
459
|
+
checkoutSessionToken?: string;
|
|
454
460
|
/** Custom trigger button — if omitted, uses the default "Book Now" button. */
|
|
455
461
|
trigger?: React.ReactNode;
|
|
456
462
|
/** Custom button label. @default "Book Now" */
|
|
@@ -460,7 +466,7 @@ interface BookingModalProps {
|
|
|
460
466
|
/** Custom button style. */
|
|
461
467
|
buttonStyle?: React.CSSProperties;
|
|
462
468
|
}
|
|
463
|
-
declare function BookingModal({ apiKey, domain, resourceId, config, trigger, buttonLabel, buttonClassName, buttonStyle, }: BookingModalProps): react_jsx_runtime.JSX.Element;
|
|
469
|
+
declare function BookingModal({ apiKey, domain, resourceId, config, checkoutSessionToken, trigger, buttonLabel, buttonClassName, buttonStyle, }: BookingModalProps): react_jsx_runtime.JSX.Element;
|
|
464
470
|
|
|
465
471
|
interface BookingCalendarProps {
|
|
466
472
|
/** Set of blocked/unavailable dates (YYYY-MM-DD). */
|
|
@@ -759,6 +765,31 @@ interface UseDishesReturn {
|
|
|
759
765
|
* ```
|
|
760
766
|
*/
|
|
761
767
|
declare function useDishes(enabled?: boolean): UseDishesReturn;
|
|
768
|
+
/** Checkout session error codes for UX branching. */
|
|
769
|
+
type CheckoutSessionErrorCode = "not_found" | "consumed" | "expired" | "unknown";
|
|
770
|
+
interface UseCheckoutSessionReturn {
|
|
771
|
+
/** The hydrated checkout session. */
|
|
772
|
+
session: CheckoutSession | null;
|
|
773
|
+
/** Whether the session is loading. */
|
|
774
|
+
loading: boolean;
|
|
775
|
+
/** Error message if loading failed. */
|
|
776
|
+
error: string | null;
|
|
777
|
+
/** Structured error code for UX branching. */
|
|
778
|
+
errorCode: CheckoutSessionErrorCode | null;
|
|
779
|
+
}
|
|
780
|
+
/**
|
|
781
|
+
* Fetch and hydrate a checkout session by token.
|
|
782
|
+
*
|
|
783
|
+
* Handles the three error cases from the API:
|
|
784
|
+
* - 404 → "Invalid booking link"
|
|
785
|
+
* - "already consumed" → "This booking was already completed"
|
|
786
|
+
* - "expired" → "Session expired"
|
|
787
|
+
*
|
|
788
|
+
* ```tsx
|
|
789
|
+
* const { session, loading, error, errorCode } = useCheckoutSession("cs_ab12cd34...");
|
|
790
|
+
* ```
|
|
791
|
+
*/
|
|
792
|
+
declare function useCheckoutSession(token: string | undefined): UseCheckoutSessionReturn;
|
|
762
793
|
|
|
763
794
|
/** Default theme values. */
|
|
764
795
|
declare const DEFAULT_THEME: Required<ResiraTheme>;
|
|
@@ -798,4 +829,4 @@ declare function TagIcon({ size, className }: IconProps): react_jsx_runtime.JSX.
|
|
|
798
829
|
declare function CubeIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
|
|
799
830
|
declare function ViewfinderIcon({ size, className }: IconProps): react_jsx_runtime.JSX.Element;
|
|
800
831
|
|
|
801
|
-
export { AlertCircleIcon, BookingCalendar, BookingModal, type BookingSelection, type BookingStep, CalendarIcon, CheckCircleIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, type DeeplinkGuest, type DeeplinkSelection, DishShowcase, type DishShowcaseProps, type DomainConfig, GuestForm, type GuestFormErrors, type GuestFormValues, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, type ResiraClassNames, type ResiraContextValue, type ResiraDomain, type ResiraLocale, ResiraProvider, type ResiraProviderConfig, type ResiraProviderProps, type ResiraTheme, ResourcePicker, type ServiceLayout, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };
|
|
832
|
+
export { AlertCircleIcon, BookingCalendar, BookingModal, type BookingSelection, type BookingStep, CalendarIcon, CheckCircleIcon, CheckIcon, type CheckoutSessionErrorCode, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, type DeeplinkGuest, type DeeplinkSelection, DishShowcase, type DishShowcaseProps, type DomainConfig, GuestForm, type GuestFormErrors, type GuestFormValues, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, type ResiraClassNames, type ResiraContextValue, type ResiraDomain, type ResiraLocale, ResiraProvider, type ResiraProviderConfig, type ResiraProviderProps, type ResiraTheme, ResourcePicker, type ServiceLayout, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useCheckoutSession, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };
|
package/dist/index.js
CHANGED
|
@@ -171,6 +171,7 @@ function ResiraProvider({
|
|
|
171
171
|
resourceId,
|
|
172
172
|
domain,
|
|
173
173
|
config,
|
|
174
|
+
checkoutSessionToken,
|
|
174
175
|
onClose,
|
|
175
176
|
children
|
|
176
177
|
}) {
|
|
@@ -260,9 +261,10 @@ function ResiraProvider({
|
|
|
260
261
|
deeplinkGuest,
|
|
261
262
|
onStepChange,
|
|
262
263
|
onBookingComplete,
|
|
263
|
-
onError
|
|
264
|
+
onError,
|
|
265
|
+
checkoutSessionToken
|
|
264
266
|
}),
|
|
265
|
-
[client, resourceId, activeResourceId, setActiveResourceId, catalogMode, allowMultiSelect, domain, theme, locale, domainConfig, stripePublishableKey, termsText, waiverText, showWaiver, showTerms, showRemainingSpots, depositPercent, refundPolicy, onClose, classNames, serviceLayout, visibleServiceCount, groupServicesByCategory, renderServiceCard, showStepIndicator, deeplink, deeplinkGuest, onStepChange, onBookingComplete, onError]
|
|
267
|
+
[client, resourceId, activeResourceId, setActiveResourceId, catalogMode, allowMultiSelect, domain, theme, locale, domainConfig, stripePublishableKey, termsText, waiverText, showWaiver, showTerms, showRemainingSpots, depositPercent, refundPolicy, onClose, classNames, serviceLayout, visibleServiceCount, groupServicesByCategory, renderServiceCard, showStepIndicator, deeplink, deeplinkGuest, onStepChange, onBookingComplete, onError, checkoutSessionToken]
|
|
266
268
|
);
|
|
267
269
|
return /* @__PURE__ */ jsx(ResiraContext.Provider, { value, children: /* @__PURE__ */ jsx("div", { className: "resira-root", style: cssVars, children }) });
|
|
268
270
|
}
|
|
@@ -594,6 +596,60 @@ function useDishes(enabled = true) {
|
|
|
594
596
|
}, [client, enabled]);
|
|
595
597
|
return { dishes, loading, error };
|
|
596
598
|
}
|
|
599
|
+
function useCheckoutSession(token) {
|
|
600
|
+
const { client } = useResira();
|
|
601
|
+
const [session, setSession] = useState(null);
|
|
602
|
+
const [loading, setLoading] = useState(!!token);
|
|
603
|
+
const [error, setError] = useState(null);
|
|
604
|
+
const [errorCode, setErrorCode] = useState(null);
|
|
605
|
+
useEffect(() => {
|
|
606
|
+
if (!token) {
|
|
607
|
+
setSession(null);
|
|
608
|
+
setLoading(false);
|
|
609
|
+
setError(null);
|
|
610
|
+
setErrorCode(null);
|
|
611
|
+
return;
|
|
612
|
+
}
|
|
613
|
+
let cancelled = false;
|
|
614
|
+
setLoading(true);
|
|
615
|
+
setError(null);
|
|
616
|
+
setErrorCode(null);
|
|
617
|
+
async function fetchSession() {
|
|
618
|
+
try {
|
|
619
|
+
const data = await client.getCheckoutSession(token);
|
|
620
|
+
if (!cancelled) {
|
|
621
|
+
setSession(data.session);
|
|
622
|
+
}
|
|
623
|
+
} catch (err) {
|
|
624
|
+
if (cancelled) return;
|
|
625
|
+
const apiErr = err;
|
|
626
|
+
const message = apiErr.body?.error ?? (err instanceof Error ? err.message : "Failed to load checkout session");
|
|
627
|
+
if (apiErr.status === 404) {
|
|
628
|
+
setError("Invalid booking link");
|
|
629
|
+
setErrorCode("not_found");
|
|
630
|
+
} else if (message.toLowerCase().includes("consumed")) {
|
|
631
|
+
setError("This booking was already completed");
|
|
632
|
+
setErrorCode("consumed");
|
|
633
|
+
} else if (message.toLowerCase().includes("expired")) {
|
|
634
|
+
setError("Session expired \u2014 please start a new booking");
|
|
635
|
+
setErrorCode("expired");
|
|
636
|
+
} else {
|
|
637
|
+
setError(message);
|
|
638
|
+
setErrorCode("unknown");
|
|
639
|
+
}
|
|
640
|
+
} finally {
|
|
641
|
+
if (!cancelled) {
|
|
642
|
+
setLoading(false);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
fetchSession();
|
|
647
|
+
return () => {
|
|
648
|
+
cancelled = true;
|
|
649
|
+
};
|
|
650
|
+
}, [client, token]);
|
|
651
|
+
return { session, loading, error, errorCode };
|
|
652
|
+
}
|
|
597
653
|
var defaultSize = 20;
|
|
598
654
|
function CalendarIcon({ size = defaultSize, className }) {
|
|
599
655
|
return /* @__PURE__ */ jsxs(
|
|
@@ -2675,7 +2731,8 @@ var STEP_LABELS = {
|
|
|
2675
2731
|
details: "Details",
|
|
2676
2732
|
terms: "Terms",
|
|
2677
2733
|
payment: "Payment",
|
|
2678
|
-
confirmation: "Done"
|
|
2734
|
+
confirmation: "Done",
|
|
2735
|
+
checkout: "Checkout"
|
|
2679
2736
|
};
|
|
2680
2737
|
function ResiraBookingWidget() {
|
|
2681
2738
|
const {
|
|
@@ -2697,16 +2754,26 @@ function ResiraBookingWidget() {
|
|
|
2697
2754
|
deeplinkGuest,
|
|
2698
2755
|
onStepChange,
|
|
2699
2756
|
onBookingComplete,
|
|
2700
|
-
onError
|
|
2757
|
+
onError,
|
|
2758
|
+
checkoutSessionToken
|
|
2701
2759
|
} = useResira();
|
|
2702
2760
|
const isDateBased = domain === "rental";
|
|
2703
2761
|
const isTimeBased = domain === "restaurant" || domain === "watersport" || domain === "service";
|
|
2704
2762
|
const isServiceBased = domain === "watersport" || domain === "service";
|
|
2705
2763
|
const hasPayment = !!stripePublishableKey;
|
|
2706
|
-
const
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2764
|
+
const isCheckoutMode = !!checkoutSessionToken;
|
|
2765
|
+
const {
|
|
2766
|
+
session: checkoutSession,
|
|
2767
|
+
loading: checkoutSessionLoading,
|
|
2768
|
+
error: checkoutSessionError,
|
|
2769
|
+
errorCode: checkoutSessionErrorCode
|
|
2770
|
+
} = useCheckoutSession(checkoutSessionToken);
|
|
2771
|
+
const STEPS = useMemo(() => {
|
|
2772
|
+
if (isCheckoutMode) {
|
|
2773
|
+
return ["checkout", "payment", "confirmation"];
|
|
2774
|
+
}
|
|
2775
|
+
return buildSteps(domain, hasPayment, catalogMode);
|
|
2776
|
+
}, [domain, hasPayment, catalogMode, isCheckoutMode]);
|
|
2710
2777
|
const initialStep = STEPS[0];
|
|
2711
2778
|
const [step, setStep] = useState(initialStep);
|
|
2712
2779
|
const [selectedResourceIds, setSelectedResourceIds] = useState([]);
|
|
@@ -2787,6 +2854,16 @@ function ResiraBookingWidget() {
|
|
|
2787
2854
|
const [paymentFormReady, setPaymentFormReady] = useState(false);
|
|
2788
2855
|
const [paymentFormSubmitting, setPaymentFormSubmitting] = useState(false);
|
|
2789
2856
|
const paymentPayload = useMemo(() => {
|
|
2857
|
+
if (isCheckoutMode && checkoutSession) {
|
|
2858
|
+
return {
|
|
2859
|
+
checkoutSessionToken,
|
|
2860
|
+
guestName: guest.guestName.trim() || checkoutSession.guestName || "",
|
|
2861
|
+
guestEmail: guest.guestEmail.trim() || checkoutSession.guestEmail || void 0,
|
|
2862
|
+
guestPhone: guest.guestPhone.trim() || void 0,
|
|
2863
|
+
notes: guest.notes.trim() || void 0,
|
|
2864
|
+
termsAccepted: termsAccepted || void 0
|
|
2865
|
+
};
|
|
2866
|
+
}
|
|
2790
2867
|
const resourceId = activeResourceId ?? selectedProduct?.equipmentIds?.[0] ?? "";
|
|
2791
2868
|
return {
|
|
2792
2869
|
productId: selectedProduct?.id ?? "",
|
|
@@ -2803,7 +2880,7 @@ function ResiraBookingWidget() {
|
|
|
2803
2880
|
promoCode: discountCode.trim() || void 0,
|
|
2804
2881
|
termsAccepted: termsAccepted || void 0
|
|
2805
2882
|
};
|
|
2806
|
-
}, [activeResourceId, selectedProduct, selection, guest, discountCode, termsAccepted]);
|
|
2883
|
+
}, [activeResourceId, selectedProduct, selection, guest, discountCode, termsAccepted, isCheckoutMode, checkoutSession, checkoutSessionToken]);
|
|
2807
2884
|
const blockedDates = useMemo(() => {
|
|
2808
2885
|
const dates = calendarData?.dates?.blockedDates ?? availability?.dates?.blockedDates ?? [];
|
|
2809
2886
|
return new Set(dates);
|
|
@@ -2861,6 +2938,8 @@ function ResiraBookingWidget() {
|
|
|
2861
2938
|
return locale.payment;
|
|
2862
2939
|
case "confirmation":
|
|
2863
2940
|
return locale.bookingConfirmed;
|
|
2941
|
+
case "checkout":
|
|
2942
|
+
return "Checkout";
|
|
2864
2943
|
}
|
|
2865
2944
|
}, [step, isDateBased, isServiceBased, locale, domain]);
|
|
2866
2945
|
const stepSubtitle = useMemo(() => {
|
|
@@ -2879,8 +2958,10 @@ function ResiraBookingWidget() {
|
|
|
2879
2958
|
return "Complete your booking securely";
|
|
2880
2959
|
case "confirmation":
|
|
2881
2960
|
return "";
|
|
2961
|
+
case "checkout":
|
|
2962
|
+
return checkoutSession?.productName ?? "Complete your booking";
|
|
2882
2963
|
}
|
|
2883
|
-
}, [step, domainConfig.label, locale, allowMultiSelect, isServiceBased, selectedProduct, domain]);
|
|
2964
|
+
}, [step, domainConfig.label, locale, allowMultiSelect, isServiceBased, selectedProduct, domain, checkoutSession]);
|
|
2884
2965
|
const canContinue = useMemo(() => {
|
|
2885
2966
|
if (step === "resource") {
|
|
2886
2967
|
if (isServiceBased) return !!selectedProduct;
|
|
@@ -3058,6 +3139,35 @@ function ResiraBookingWidget() {
|
|
|
3058
3139
|
const handlePaymentError = useCallback((msg) => {
|
|
3059
3140
|
onError?.("payment_error", msg);
|
|
3060
3141
|
}, [onError]);
|
|
3142
|
+
const handleCheckoutSubmit = useCallback(async () => {
|
|
3143
|
+
const contactMode = "email-required";
|
|
3144
|
+
const errors = validateGuestForm(guest, {
|
|
3145
|
+
required: locale.required,
|
|
3146
|
+
invalidEmail: locale.invalidEmail,
|
|
3147
|
+
contactRequired: locale.contactRequired
|
|
3148
|
+
}, contactMode);
|
|
3149
|
+
if (Object.keys(errors).length > 0) {
|
|
3150
|
+
setFormErrors(errors);
|
|
3151
|
+
return;
|
|
3152
|
+
}
|
|
3153
|
+
setFormErrors({});
|
|
3154
|
+
if (checkoutSession?.checkoutConfig.termsRequired && !termsAccepted) {
|
|
3155
|
+
setTermsError(locale.termsRequired);
|
|
3156
|
+
return;
|
|
3157
|
+
}
|
|
3158
|
+
setTermsError(null);
|
|
3159
|
+
const result = await createPayment(paymentPayload);
|
|
3160
|
+
if (!result) return;
|
|
3161
|
+
if (result.amountNow === 0) {
|
|
3162
|
+
if (result.reservationId) {
|
|
3163
|
+
const confirmed = await confirmPayment(result.paymentIntentId, result.reservationId);
|
|
3164
|
+
if (!confirmed) return;
|
|
3165
|
+
}
|
|
3166
|
+
setStep("confirmation");
|
|
3167
|
+
} else {
|
|
3168
|
+
setStep("payment");
|
|
3169
|
+
}
|
|
3170
|
+
}, [guest, locale, checkoutSession, termsAccepted, createPayment, paymentPayload, confirmPayment]);
|
|
3061
3171
|
const handleSubmitNoPayment = useCallback(async () => {
|
|
3062
3172
|
if (showTerms && !termsAccepted) {
|
|
3063
3173
|
setTermsError(locale.termsRequired);
|
|
@@ -3088,6 +3198,17 @@ function ResiraBookingWidget() {
|
|
|
3088
3198
|
const footerBusy = submitting || creatingPayment || confirmingPayment || paymentFormSubmitting;
|
|
3089
3199
|
const paymentActionDisabled = !paymentIntent || !paymentFormReady || paymentFormSubmitting || confirmingPayment;
|
|
3090
3200
|
const [deeplinkApplied, setDeeplinkApplied] = useState(false);
|
|
3201
|
+
const [checkoutGuestFilled, setCheckoutGuestFilled] = useState(false);
|
|
3202
|
+
useEffect(() => {
|
|
3203
|
+
if (checkoutGuestFilled || !checkoutSession) return;
|
|
3204
|
+
setGuest((prev) => ({
|
|
3205
|
+
guestName: checkoutSession.guestName ?? prev.guestName,
|
|
3206
|
+
guestEmail: checkoutSession.guestEmail ?? prev.guestEmail,
|
|
3207
|
+
guestPhone: prev.guestPhone,
|
|
3208
|
+
notes: prev.notes
|
|
3209
|
+
}));
|
|
3210
|
+
setCheckoutGuestFilled(true);
|
|
3211
|
+
}, [checkoutSession, checkoutGuestFilled]);
|
|
3091
3212
|
useEffect(() => {
|
|
3092
3213
|
if (deeplinkApplied || !deeplink) return;
|
|
3093
3214
|
if (deeplink.productId && products.length > 0 && !selectedProduct) {
|
|
@@ -3323,6 +3444,93 @@ function ResiraBookingWidget() {
|
|
|
3323
3444
|
/* @__PURE__ */ jsx("p", { className: "resira-error-message", children: paymentError })
|
|
3324
3445
|
] })
|
|
3325
3446
|
] }),
|
|
3447
|
+
step === "checkout" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3448
|
+
checkoutSessionLoading && /* @__PURE__ */ jsxs("div", { className: "resira-loading", role: "status", "aria-live": "polite", "aria-busy": "true", children: [
|
|
3449
|
+
/* @__PURE__ */ jsx("div", { className: "resira-spinner", "aria-hidden": "true" }),
|
|
3450
|
+
/* @__PURE__ */ jsx("span", { className: "resira-loading-text", children: locale.loading })
|
|
3451
|
+
] }),
|
|
3452
|
+
checkoutSessionError && /* @__PURE__ */ jsxs("div", { className: "resira-error", role: "alert", "aria-live": "assertive", children: [
|
|
3453
|
+
/* @__PURE__ */ jsx(AlertCircleIcon, { size: 24 }),
|
|
3454
|
+
/* @__PURE__ */ jsx("p", { className: "resira-error-message", children: checkoutSessionError }),
|
|
3455
|
+
(checkoutSessionErrorCode === "not_found" || checkoutSessionErrorCode === "expired") && onClose && /* @__PURE__ */ jsx(
|
|
3456
|
+
"button",
|
|
3457
|
+
{
|
|
3458
|
+
type: "button",
|
|
3459
|
+
className: "resira-btn resira-btn--secondary resira-error-retry",
|
|
3460
|
+
onClick: onClose,
|
|
3461
|
+
children: "Start a new booking"
|
|
3462
|
+
}
|
|
3463
|
+
)
|
|
3464
|
+
] }),
|
|
3465
|
+
checkoutSession && !checkoutSessionError && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3466
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-summary", style: { marginBottom: 16 }, children: [
|
|
3467
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-summary-row", children: [
|
|
3468
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-label", children: "Service" }),
|
|
3469
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-value", children: checkoutSession.productName })
|
|
3470
|
+
] }),
|
|
3471
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-summary-row", children: [
|
|
3472
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-label", children: "Date" }),
|
|
3473
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-value", children: (/* @__PURE__ */ new Date(checkoutSession.date + "T00:00:00")).toLocaleDateString("default", { weekday: "short", month: "short", day: "numeric" }) })
|
|
3474
|
+
] }),
|
|
3475
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-summary-row", children: [
|
|
3476
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-label", children: "Time" }),
|
|
3477
|
+
/* @__PURE__ */ jsxs("span", { className: "resira-summary-value", children: [
|
|
3478
|
+
new Date(checkoutSession.startTime).toLocaleTimeString("default", { hour: "2-digit", minute: "2-digit", hour12: false }),
|
|
3479
|
+
" \u2013 ",
|
|
3480
|
+
new Date(checkoutSession.endTime).toLocaleTimeString("default", { hour: "2-digit", minute: "2-digit", hour12: false })
|
|
3481
|
+
] })
|
|
3482
|
+
] }),
|
|
3483
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-summary-row", children: [
|
|
3484
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-label", children: "Duration" }),
|
|
3485
|
+
/* @__PURE__ */ jsxs("span", { className: "resira-summary-value", children: [
|
|
3486
|
+
checkoutSession.durationMinutes,
|
|
3487
|
+
" min"
|
|
3488
|
+
] })
|
|
3489
|
+
] }),
|
|
3490
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-summary-row", children: [
|
|
3491
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-label", children: locale.guests }),
|
|
3492
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-value", children: checkoutSession.partySize })
|
|
3493
|
+
] }),
|
|
3494
|
+
checkoutSession.promoCode && /* @__PURE__ */ jsxs("div", { className: "resira-summary-row", children: [
|
|
3495
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-label", children: locale.discountCode }),
|
|
3496
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-value", children: checkoutSession.promoCode })
|
|
3497
|
+
] }),
|
|
3498
|
+
/* @__PURE__ */ jsx("div", { className: "resira-summary-divider" }),
|
|
3499
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-summary-row", children: [
|
|
3500
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-label resira-summary-total", children: locale.total }),
|
|
3501
|
+
/* @__PURE__ */ jsx("span", { className: "resira-summary-value resira-summary-total", children: formatPrice5(checkoutSession.priceCents, checkoutSession.currency) })
|
|
3502
|
+
] })
|
|
3503
|
+
] }),
|
|
3504
|
+
/* @__PURE__ */ jsx(
|
|
3505
|
+
GuestForm,
|
|
3506
|
+
{
|
|
3507
|
+
values: guest,
|
|
3508
|
+
onChange: setGuest,
|
|
3509
|
+
errors: formErrors
|
|
3510
|
+
}
|
|
3511
|
+
),
|
|
3512
|
+
checkoutSession.checkoutConfig.termsRequired && /* @__PURE__ */ jsx("div", { style: { marginTop: 14 }, children: /* @__PURE__ */ jsx(
|
|
3513
|
+
WaiverConsent,
|
|
3514
|
+
{
|
|
3515
|
+
termsAccepted,
|
|
3516
|
+
onTermsChange: setTermsAccepted,
|
|
3517
|
+
waiverAccepted: false,
|
|
3518
|
+
onWaiverChange: () => {
|
|
3519
|
+
},
|
|
3520
|
+
discountCode: "",
|
|
3521
|
+
onDiscountCodeChange: () => {
|
|
3522
|
+
},
|
|
3523
|
+
onPromoValidated: () => {
|
|
3524
|
+
},
|
|
3525
|
+
error: termsError ?? void 0
|
|
3526
|
+
}
|
|
3527
|
+
) }),
|
|
3528
|
+
paymentError && /* @__PURE__ */ jsxs("div", { className: "resira-error", style: { padding: "12px 0" }, children: [
|
|
3529
|
+
/* @__PURE__ */ jsx(AlertCircleIcon, { size: 18 }),
|
|
3530
|
+
/* @__PURE__ */ jsx("p", { className: "resira-error-message", children: paymentError })
|
|
3531
|
+
] })
|
|
3532
|
+
] })
|
|
3533
|
+
] }),
|
|
3326
3534
|
step === "payment" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3327
3535
|
paymentError && /* @__PURE__ */ jsxs("div", { className: "resira-error", children: [
|
|
3328
3536
|
/* @__PURE__ */ jsx(AlertCircleIcon, { size: 24 }),
|
|
@@ -3408,31 +3616,45 @@ function ResiraBookingWidget() {
|
|
|
3408
3616
|
/* @__PURE__ */ jsx("span", { className: "resira-summary-value resira-summary-total", children: formatPrice5(computedPrice.total, currency) })
|
|
3409
3617
|
] })
|
|
3410
3618
|
] })
|
|
3411
|
-
] }) })
|
|
3412
|
-
onClose && /* @__PURE__ */ jsx(
|
|
3413
|
-
"button",
|
|
3414
|
-
{
|
|
3415
|
-
type: "button",
|
|
3416
|
-
className: "resira-btn resira-btn--primary",
|
|
3417
|
-
style: { marginTop: 20, width: "100%" },
|
|
3418
|
-
onClick: onClose,
|
|
3419
|
-
children: locale.done
|
|
3420
|
-
}
|
|
3421
|
-
)
|
|
3619
|
+
] }) })
|
|
3422
3620
|
] })
|
|
3423
3621
|
] }),
|
|
3424
|
-
|
|
3425
|
-
|
|
3622
|
+
/* @__PURE__ */ jsxs("div", { className: "resira-widget-footer", children: [
|
|
3623
|
+
/* @__PURE__ */ jsx(
|
|
3426
3624
|
"button",
|
|
3427
3625
|
{
|
|
3428
3626
|
type: "button",
|
|
3429
3627
|
className: "resira-btn resira-btn--secondary",
|
|
3430
3628
|
onClick: handleBack,
|
|
3431
|
-
disabled: footerBusy,
|
|
3629
|
+
disabled: footerBusy || currentIndex === 0,
|
|
3630
|
+
style: currentIndex === 0 || step === "confirmation" ? { visibility: "hidden" } : void 0,
|
|
3631
|
+
"aria-hidden": currentIndex === 0 || step === "confirmation",
|
|
3432
3632
|
children: locale.back
|
|
3433
3633
|
}
|
|
3434
3634
|
),
|
|
3435
|
-
|
|
3635
|
+
step === "confirmation" ? onClose ? /* @__PURE__ */ jsx(
|
|
3636
|
+
"button",
|
|
3637
|
+
{
|
|
3638
|
+
type: "button",
|
|
3639
|
+
className: "resira-btn resira-btn--primary",
|
|
3640
|
+
onClick: onClose,
|
|
3641
|
+
children: locale.done
|
|
3642
|
+
}
|
|
3643
|
+
) : /* @__PURE__ */ jsx("span", { style: { visibility: "hidden" }, className: "resira-btn resira-btn--primary", children: locale.continue }) : step === "checkout" ? /* @__PURE__ */ jsx(
|
|
3644
|
+
"button",
|
|
3645
|
+
{
|
|
3646
|
+
type: "button",
|
|
3647
|
+
className: "resira-btn resira-btn--primary",
|
|
3648
|
+
onClick: () => {
|
|
3649
|
+
void handleCheckoutSubmit();
|
|
3650
|
+
},
|
|
3651
|
+
disabled: footerBusy || checkoutSessionLoading || !!checkoutSessionError,
|
|
3652
|
+
children: creatingPayment ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3653
|
+
/* @__PURE__ */ jsx("div", { className: "resira-spinner", style: { width: 16, height: 16 } }),
|
|
3654
|
+
locale.processingPayment
|
|
3655
|
+
] }) : checkoutSession ? `${locale.payNow} \u2014 ${formatPrice5(checkoutSession.priceCents, checkoutSession.currency)}` : locale.continue
|
|
3656
|
+
}
|
|
3657
|
+
) : step === "resource" || step === "availability" ? /* @__PURE__ */ jsx(
|
|
3436
3658
|
"button",
|
|
3437
3659
|
{
|
|
3438
3660
|
type: "button",
|
|
@@ -3443,8 +3665,7 @@ function ResiraBookingWidget() {
|
|
|
3443
3665
|
disabled: !canContinue || footerBusy,
|
|
3444
3666
|
children: locale.continue
|
|
3445
3667
|
}
|
|
3446
|
-
)
|
|
3447
|
-
step === "details" && /* @__PURE__ */ jsx(
|
|
3668
|
+
) : step === "details" ? /* @__PURE__ */ jsx(
|
|
3448
3669
|
"button",
|
|
3449
3670
|
{
|
|
3450
3671
|
type: "button",
|
|
@@ -3456,8 +3677,7 @@ function ResiraBookingWidget() {
|
|
|
3456
3677
|
locale.loading
|
|
3457
3678
|
] }) : domain === "restaurant" && !hasPayment ? locale.reserveTable : locale.continue
|
|
3458
3679
|
}
|
|
3459
|
-
)
|
|
3460
|
-
step === "terms" && /* @__PURE__ */ jsx(
|
|
3680
|
+
) : step === "terms" ? /* @__PURE__ */ jsx(
|
|
3461
3681
|
"button",
|
|
3462
3682
|
{
|
|
3463
3683
|
type: "button",
|
|
@@ -3474,8 +3694,7 @@ function ResiraBookingWidget() {
|
|
|
3474
3694
|
locale.loading
|
|
3475
3695
|
] }) : hasPayment ? locale.continue : locale.bookNow
|
|
3476
3696
|
}
|
|
3477
|
-
)
|
|
3478
|
-
step === "payment" && !paymentIntent && /* @__PURE__ */ jsx(
|
|
3697
|
+
) : step === "payment" && !paymentIntent ? /* @__PURE__ */ jsx(
|
|
3479
3698
|
"button",
|
|
3480
3699
|
{
|
|
3481
3700
|
type: "button",
|
|
@@ -3489,8 +3708,7 @@ function ResiraBookingWidget() {
|
|
|
3489
3708
|
locale.processingPayment
|
|
3490
3709
|
] }) : computedPrice ? `${locale.payNow} \u2014 ${formatPrice5(computedPrice.amountNow, currency)}` : locale.payNow
|
|
3491
3710
|
}
|
|
3492
|
-
)
|
|
3493
|
-
step === "payment" && paymentIntent?.amountNow != null && paymentIntent.amountNow > 0 && /* @__PURE__ */ jsx(
|
|
3711
|
+
) : step === "payment" && paymentIntent?.amountNow != null && paymentIntent.amountNow > 0 ? /* @__PURE__ */ jsx(
|
|
3494
3712
|
"button",
|
|
3495
3713
|
{
|
|
3496
3714
|
type: "button",
|
|
@@ -3502,6 +3720,9 @@ function ResiraBookingWidget() {
|
|
|
3502
3720
|
locale.processingPayment
|
|
3503
3721
|
] }) : `${locale.payNow} \u2014 ${formatPrice5(paymentIntent.amountNow, paymentIntent.currency)}`
|
|
3504
3722
|
}
|
|
3723
|
+
) : (
|
|
3724
|
+
/* Fallback placeholder to hold space (e.g. zero-amount payment auto-advancing) */
|
|
3725
|
+
/* @__PURE__ */ jsx("span", { style: { visibility: "hidden" }, className: "resira-btn resira-btn--primary", children: locale.continue })
|
|
3505
3726
|
)
|
|
3506
3727
|
] })
|
|
3507
3728
|
] });
|
|
@@ -3511,6 +3732,7 @@ function BookingModal({
|
|
|
3511
3732
|
domain,
|
|
3512
3733
|
resourceId,
|
|
3513
3734
|
config,
|
|
3735
|
+
checkoutSessionToken,
|
|
3514
3736
|
trigger,
|
|
3515
3737
|
buttonLabel = "Book Now",
|
|
3516
3738
|
buttonClassName,
|
|
@@ -3634,6 +3856,7 @@ function BookingModal({
|
|
|
3634
3856
|
domain,
|
|
3635
3857
|
resourceId,
|
|
3636
3858
|
config,
|
|
3859
|
+
checkoutSessionToken,
|
|
3637
3860
|
onClose: handleClose,
|
|
3638
3861
|
children: /* @__PURE__ */ jsx(ResiraBookingWidget, {})
|
|
3639
3862
|
}
|
|
@@ -3984,6 +4207,6 @@ function DishShowcase({
|
|
|
3984
4207
|
] });
|
|
3985
4208
|
}
|
|
3986
4209
|
|
|
3987
|
-
export { AlertCircleIcon, BookingCalendar, BookingModal, CalendarIcon, CheckCircleIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, DishShowcase, GuestForm, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, ResiraProvider, ResourcePicker, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };
|
|
4210
|
+
export { AlertCircleIcon, BookingCalendar, BookingModal, CalendarIcon, CheckCircleIcon, CheckIcon, ChevronLeftIcon, ChevronRightIcon, ClockIcon, ConfirmationView, CreditCardIcon, CubeIcon, DEFAULT_LOCALE, DEFAULT_THEME, DishShowcase, GuestForm, LockIcon, MailIcon, MinusIcon, NoteIcon, PaymentForm, PhoneIcon, PlusIcon, ProductSelector, ResiraBookingWidget, ResiraProvider, ResourcePicker, ShieldIcon, SummaryPreview, TagIcon, TimeSlotPicker, UserIcon, UsersIcon, ViewfinderIcon, WaiverConsent, XIcon, resolveTheme, themeToCSS, useAvailability, useCheckoutSession, useDish, useDishes, usePaymentIntent, useProducts, useReservation, useResira, useResources, validateGuestForm };
|
|
3988
4211
|
//# sourceMappingURL=index.js.map
|
|
3989
4212
|
//# sourceMappingURL=index.js.map
|