@riverbankcms/sdk 0.141.0 → 0.143.0
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/{PreviewEditorSidebar-Q-fy9GYw.mjs → PreviewEditorSidebar-DROGfMKi.mjs} +24 -15
- package/dist/{PreviewEditorUI-LYGzgk85.mjs → PreviewEditorUI-BaRjhFu-.mjs} +3 -3
- package/dist/{PreviewQueryProvider-CN0ewic5.mjs → PreviewQueryProvider-BCYICImX.mjs} +1 -1
- package/dist/{SdkPreviewModeRuntime-CoPYI5Jq.mjs → SdkPreviewModeRuntime-OIABYLES.mjs} +16 -11
- package/dist/{SiteChromeCustomizeContext-D8LePX8x.mjs → SiteChromeCustomizeContext-ohjTvZbc.mjs} +607 -545
- package/dist/_dts/api/src/billing.d.ts +6 -1
- package/dist/_dts/api/src/bookingConfig.d.ts +1 -1
- package/dist/_dts/api/src/commercePortalEndpoints.d.ts +2 -2
- package/dist/_dts/api/src/endpoints.d.ts +7 -27
- package/dist/_dts/api/src/index.d.ts +1 -1
- package/dist/_dts/api/src/publicBookingService.d.ts +1 -0
- package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +7 -0
- package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +48 -41
- package/dist/_dts/api/src/sdkConfig/layout.d.ts +13 -0
- package/dist/_dts/api/src/sdkContracts.d.ts +3 -8
- package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +1 -31
- package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +6 -1
- package/dist/_dts/billing/src/site-arrangements.d.ts +9 -5
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +56 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +8 -0
- package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +8 -0
- package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +95 -35
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.d.ts +10 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +0 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +12 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationCompletion.d.ts +1 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDerivations.d.ts +12 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/sessionStorage.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.d.ts +4 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +9 -11
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +56 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +10 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.d.ts +23 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +56 -0
- package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -4
- package/dist/_dts/commerce/src/purchase/eventCheckoutRecoveryWindow.d.ts +8 -0
- package/dist/_dts/commerce/src/purchase/index.d.ts +2 -1
- package/dist/_dts/commerce/src/purchase/stateTransitions.d.ts +1 -13
- package/dist/_dts/commerce/src/purchase/stripeCommissionMetadata.d.ts +1 -2
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +58 -45
- package/dist/_dts/editor-blocks/src/block-editor/ColourFieldOptionsProvider.d.ts +7 -0
- package/dist/_dts/editor-blocks/src/block-editor/colourFieldVisibility.d.ts +7 -0
- package/dist/_dts/editor-blocks/src/block-editor/preparedManifest.d.ts +2 -0
- package/dist/_dts/editor-blocks/src/index.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -2
- package/dist/_dts/preview-next/src/client/preview/PreviewFooterEditorPanel.d.ts +3 -6
- package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +2 -2
- package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +2 -2
- package/dist/_dts/preview-next/src/client/preview/footerInspection.d.ts +16 -0
- package/dist/_dts/preview-next/src/client/preview/sdkConfig.d.ts +6 -0
- package/dist/_dts/sdk/src/config/types.d.ts +2 -18
- package/dist/_dts/sdk/src/config/validation.d.ts +6 -0
- package/dist/_dts/sdk/src/public-api/contracts.d.ts +3 -0
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/theme-core/src/footer/mode.d.ts +10 -1
- package/dist/_dts/theme-core/src/schema.d.ts +1 -7
- package/dist/_dts/theme-core/src/site-styles/effectivePageDesign.d.ts +32 -0
- package/dist/_dts/theme-core/src/site-styles/index.d.ts +1 -0
- package/dist/client/{BookingConsentAgreement-xJeYNdnb.mjs → BookingConsentAgreement-BoCtvzzu.mjs} +2 -2
- package/dist/client/{DiscountCodeDisclosure-DdT6uzl9.mjs → DiscountCodeDisclosure-B5S30nZk.mjs} +1 -1
- package/dist/client/{EventCombined.client-Cp28uYuM.mjs → EventCombined.client-CeZ2-zSt.mjs} +5 -5
- package/dist/client/{EventListing.client-CD6AJsMr.mjs → EventListing.client-DJN3j8B3.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-DBsAi9-e.mjs → LeafletStaticMap-RjtGzDQT.mjs} +1 -1
- package/dist/client/{accordion-6dwbOKYR.mjs → accordion-DOmnDoyg.mjs} +1 -1
- package/dist/client/{bookingForm-CZE9_qPQ.mjs → bookingForm-C0vk7pgS.mjs} +5 -5
- package/dist/client/bookings.mjs +468 -534
- package/dist/client/{carousel-7VHGQARz.mjs → carousel-BZJ7pno3.mjs} +1 -1
- package/dist/client/{cart-Qg_mvQhh.mjs → cart-CaeVAHJl.mjs} +3 -3
- package/dist/client/{checkout-D84rpgdr.mjs → checkout-7wmoNDtG.mjs} +3 -3
- package/dist/client/client.mjs +559 -593
- package/dist/client/{context-Ctp3T0Wr.mjs → context-BOimxE3U.mjs} +12 -1
- package/dist/client/{dates-DJKFcI_N.mjs → dates-BnzVksi4.mjs} +2 -2
- package/dist/client/{eventCalendar-CK31z3vs.mjs → eventCalendar-l-fpaslC.mjs} +7 -7
- package/dist/client/{eventCombined-DiXd-ewn.mjs → eventCombined-DGGvssK6.mjs} +3 -3
- package/dist/client/{eventDetails-CTRgt2DK.mjs → eventDetails-DRiCm_hL.mjs} +4 -4
- package/dist/client/{eventListing-Dy9vi_j_.mjs → eventListing-dph8loYX.mjs} +3 -3
- package/dist/client/{eventRegistration-CnalYMr2.mjs → eventRegistration-ClBohmbY.mjs} +472 -531
- package/dist/client/{form-eUiMveTT.mjs → form-BLVVAnd3.mjs} +2 -2
- package/dist/client/{headerSection-Dy9kQpB1.mjs → headerSection-DHy4C8Ix.mjs} +2 -2
- package/dist/client/hooks.mjs +39 -13
- package/dist/client/{locationMap-DalCmWU0.mjs → locationMap-6HuS28ck.mjs} +2 -2
- package/dist/client/{newsletterForm-SDDPvhS0.mjs → newsletterForm-xOdcOhZP.mjs} +2 -2
- package/dist/client/{pricing-OcMz4SnX.mjs → pricing-ChinRYFt.mjs} +1 -1
- package/dist/client/{productDetail-BQrgHElM.mjs → productDetail-0chA5gbK.mjs} +3 -3
- package/dist/client/{productList-OnPn_UJj.mjs → productList-OoINA0h1.mjs} +3 -3
- package/dist/client/{propsDecoder-zBdsnS-N.mjs → propsDecoder-CIZ-hbIG.mjs} +33 -9
- package/dist/client/rendering/client.mjs +536 -550
- package/dist/client/rendering/islands.mjs +17 -17
- package/dist/client/rendering.mjs +602 -596
- package/dist/client/{scrollToBlock-BNM4Ob2Y.mjs → scrollToBlock-BPZl0gPZ.mjs} +1 -1
- package/dist/client/{shop-Bv1fPTwQ.mjs → shop-CLJFqNIq.mjs} +6 -6
- package/dist/client/{shop-commerce-D4KNGaW8.mjs → shop-commerce-PpANg5wB.mjs} +5 -5
- package/dist/client/{shop-commerce-store-2N5EV0Rc.mjs → shop-commerce-store-TA_Kz2ku.mjs} +1 -1
- package/dist/client/{shopShared-DvJGdHTV.mjs → shopShared-DzcFcA5g.mjs} +3 -3
- package/dist/client/{useEventFilters-BBBvGDHQ.mjs → useEventFilters-CFU21QZo.mjs} +5 -5
- package/dist/preview-next/before-render.mjs +11 -37
- package/dist/preview-next/client/runtime.mjs +4 -4
- package/dist/preview-next/keepAlive.mjs +11 -37
- package/dist/preview-next/middleware.mjs +11 -37
- package/dist/{previewAuthStore-Gjb6r6vz.mjs → previewAuthStore-JA6-I_sL.mjs} +11 -37
- package/dist/{sdk-runtime-Defnbfzw.mjs → sdk-runtime-CDKl0Fr7.mjs} +2 -2
- package/dist/{separator-CZXO3Sb0.mjs → separator-BTp96X32.mjs} +1 -1
- package/dist/server/components.mjs +80 -51
- package/dist/server/config-validation.mjs +43 -14
- package/dist/server/config.mjs +43 -14
- package/dist/server/data.mjs +39 -13
- package/dist/server/index.mjs +12 -38
- package/dist/server/next.mjs +40 -53
- package/dist/server/page-converter.mjs +20 -8
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +80 -51
- package/dist/server/rendering.mjs +80 -51
- package/dist/server/routing.mjs +52 -17
- package/dist/server/server.mjs +40 -51
- package/dist/server/theme-bridge.mjs +10 -8
- package/dist/server/theme.mjs +10 -8
- package/package.json +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +0 -14
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +0 -8
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as buildBookingPaymentSelectionViewModel, i as usePolling, n as StepIndicator$1, o as resolveBookingPaymentDueNowCents, r as SpinnerNode, s as formatPrice, t as BookingConsentAgreement } from "./BookingConsentAgreement-
|
|
3
|
-
import { C as resolveRegistrationTarget,
|
|
4
|
-
import { a as canJoinEventWaitlistOnAnyMode, c as formatTicketTypeRemaining, f as getRemainingPlaces, h as selectMostOpenCapacitySource, i as canJoinEventWaitlist, m as selectEventCapacitySource, o as formatEventRemainingPlaces, p as isEventFull, r as formatEventPriceDisplay, s as formatRemainingPlaces, u as getEventAvailability } from "./pricing-
|
|
5
|
-
import { n as useBlockApi, r as BlockApiError, t as BlockApiProvider } from "./context-
|
|
2
|
+
import { a as buildBookingPaymentSelectionViewModel, i as usePolling, n as StepIndicator$1, o as resolveBookingPaymentDueNowCents, r as SpinnerNode, s as formatPrice, t as BookingConsentAgreement } from "./BookingConsentAgreement-BoCtvzzu.mjs";
|
|
3
|
+
import { A as resolveEventRegistrationScopedEvents, C as resolveRegistrationTarget, D as getWizardStepsForContext, E as getStepNumber, Ft as assertNever, Jt as formatBookingDateTime, Kt as formatBookingDate, S as resolveEventRequiresPayment, T as WIZARD_STEPS, Xt as formatBookingTime, _ as toRegistrationEvents, b as findPreSelectedEvent, cn as publicEventPricingCurrency, dn as publicEventPricingStrategy, fn as publicEventPricingType, ft as themeButtonClassName, g as getRegistrationStartAt, h as buildEventRegistrationDisplayFromScopedEvents, in as toScheduledBookingDateTime, mn as parseCurrencyCode, nn as toBookingTimeZone, pn as formatCurrencyAmount, st as groupPublicEventsByRun, t as defineIslandPropsDecoder, un as publicEventPricingOptions, v as toWholeSeriesRegistrationEvents, w as toRegistrationRequestSubject, x as resolveDiscountContext, y as findEventByOccurrenceId } from "./propsDecoder-CIZ-hbIG.mjs";
|
|
4
|
+
import { a as canJoinEventWaitlistOnAnyMode, c as formatTicketTypeRemaining, f as getRemainingPlaces, h as selectMostOpenCapacitySource, i as canJoinEventWaitlist, m as selectEventCapacitySource, o as formatEventRemainingPlaces, p as isEventFull, r as formatEventPriceDisplay, s as formatRemainingPlaces, u as getEventAvailability } from "./pricing-ChinRYFt.mjs";
|
|
5
|
+
import { n as useBlockApi, r as BlockApiError, t as BlockApiProvider } from "./context-BOimxE3U.mjs";
|
|
6
6
|
import { n as isSpamProtectionEnabled, r as AltchaWidget, t as getChallengeUrl } from "./src-B833rYRr.mjs";
|
|
7
|
-
import { a as CheckIcon, i as StateIcon, n as useDiscountCodeUi, r as TerminalPanel, t as scrollToBlock } from "./scrollToBlock-
|
|
8
|
-
import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-
|
|
7
|
+
import { a as CheckIcon, i as StateIcon, n as useDiscountCodeUi, r as TerminalPanel, t as scrollToBlock } from "./scrollToBlock-BPZl0gPZ.mjs";
|
|
8
|
+
import { t as DiscountCodeDisclosure } from "./DiscountCodeDisclosure-B5S30nZk.mjs";
|
|
9
9
|
import { t as FeedbackMessage } from "./FeedbackMessage-CtLvvS_d.mjs";
|
|
10
10
|
import { n as getFieldValidationControlProps, t as FieldValidationMessage } from "./FieldValidationMessage-AYanWFb-.mjs";
|
|
11
11
|
import { t as buildCheckoutReturnUrls } from "./checkoutUrls-FL6lRkrt.mjs";
|
|
@@ -276,7 +276,7 @@ function resolveEventRegistrationDirectPaymentSelection(input) {
|
|
|
276
276
|
//#endregion
|
|
277
277
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationStateMachine.ts
|
|
278
278
|
function hasBlockingExistingRegistration(input) {
|
|
279
|
-
return !input.hasWaitlistClaim && input.isAuthenticated && input.registration.kind
|
|
279
|
+
return !input.hasWaitlistClaim && input.isAuthenticated && input.registration.kind === "waitlisted";
|
|
280
280
|
}
|
|
281
281
|
function createInitialRegistrationFlowState(hasPreSelectedContext) {
|
|
282
282
|
return {
|
|
@@ -328,7 +328,7 @@ function computeAutoSelection(input) {
|
|
|
328
328
|
return { method: null };
|
|
329
329
|
}
|
|
330
330
|
function computeDirectPaymentSelection(eligibility) {
|
|
331
|
-
if (!eligibility?.
|
|
331
|
+
if (!eligibility?.requiresPayment) return { method: null };
|
|
332
332
|
const approvedKinds = getApprovedDirectPaymentCollectionOptionKinds(eligibility.paymentOptions);
|
|
333
333
|
const collectionOptionKind = approvedKinds.includes("upfront") ? "upfront" : approvedKinds[0];
|
|
334
334
|
return collectionOptionKind ? {
|
|
@@ -342,7 +342,7 @@ function isSelectionValid(input) {
|
|
|
342
342
|
if (!eligibility) return selection.method === "stripe" || selection.method === "pass_bundle" || selection.method === "membership_bundle";
|
|
343
343
|
switch (selection.method) {
|
|
344
344
|
case "free": return eligibility.isFree;
|
|
345
|
-
case "stripe": return Boolean(eligibility.
|
|
345
|
+
case "stripe": return Boolean(eligibility.requiresPayment && eligibility.price);
|
|
346
346
|
case "pass": return isAuthenticated && ticketsCount === 1 && !!selection.passId && eligibility.eligiblePasses.some((pass) => pass.id === selection.passId);
|
|
347
347
|
case "membership": return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some((membership) => membership.id === selection.membershipId);
|
|
348
348
|
case "pass_bundle": return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some((pass) => pass.id === selection.bundlePassId);
|
|
@@ -361,7 +361,7 @@ function normalizeRegistrationFlowState(state) {
|
|
|
361
361
|
ticketsCount: state.ticketsCount,
|
|
362
362
|
passOptOut: nextPassOptOut
|
|
363
363
|
});
|
|
364
|
-
const canKeepManualSelection = state.step
|
|
364
|
+
const canKeepManualSelection = state.step !== "select-tickets" && state.selectionSource === "manual" && isSelectionValid({
|
|
365
365
|
selection: state.paymentSelection,
|
|
366
366
|
isAuthenticated: state.isAuthenticated,
|
|
367
367
|
eligibility: state.eligibility,
|
|
@@ -444,7 +444,7 @@ function resolveEventRegistrationSubmitPlan(input) {
|
|
|
444
444
|
const selection = input.paymentSelection.method ? input.paymentSelection : void 0;
|
|
445
445
|
if (input.canJoinWaitlist) return {
|
|
446
446
|
ok: true,
|
|
447
|
-
args:
|
|
447
|
+
args: { method: "free" }
|
|
448
448
|
};
|
|
449
449
|
switch (input.paymentSelection.method) {
|
|
450
450
|
case "pass": return input.paymentSelection.passId ? {
|
|
@@ -503,88 +503,53 @@ function missingPaymentSelection() {
|
|
|
503
503
|
};
|
|
504
504
|
}
|
|
505
505
|
//#endregion
|
|
506
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/
|
|
507
|
-
/**
|
|
508
|
-
function
|
|
509
|
-
|
|
510
|
-
kind: "available",
|
|
511
|
-
remainingPlaces: null
|
|
512
|
-
};
|
|
513
|
-
return availability;
|
|
506
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.ts
|
|
507
|
+
/** Ticket selection requests a quote; only the server admits a booking. */
|
|
508
|
+
function canRequestTicketOption(availability) {
|
|
509
|
+
return availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable";
|
|
514
510
|
}
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
ticketTypes: eligibility.ticketTypes.map((option) => ({
|
|
528
|
-
...option,
|
|
529
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
530
|
-
}))
|
|
531
|
-
} : eligibility;
|
|
532
|
-
const currency = eligibility.currency;
|
|
533
|
-
const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
|
|
534
|
-
switch (option.kind) {
|
|
535
|
-
case "upfront": return {
|
|
536
|
-
kind: "payInFull",
|
|
537
|
-
amountCents,
|
|
538
|
-
currency
|
|
539
|
-
};
|
|
540
|
-
case "deferred_manual": return {
|
|
541
|
-
kind: "deferredManual",
|
|
542
|
-
amountCents,
|
|
543
|
-
currency
|
|
544
|
-
};
|
|
545
|
-
case "instalment_plan": return {
|
|
546
|
-
kind: "instalmentPlan",
|
|
547
|
-
amountCents,
|
|
548
|
-
currency
|
|
549
|
-
};
|
|
550
|
-
case "flexible_balance": return {
|
|
551
|
-
kind: "flexibleBalance",
|
|
552
|
-
amountCents,
|
|
553
|
-
currency
|
|
554
|
-
};
|
|
555
|
-
}
|
|
556
|
-
});
|
|
557
|
-
return {
|
|
558
|
-
...eligibility,
|
|
559
|
-
registration: { kind: "none" },
|
|
560
|
-
availability: {
|
|
561
|
-
kind: "available",
|
|
562
|
-
remainingPlaces: null,
|
|
563
|
-
waitlistEnabled: eligibility.waitlistEnabled
|
|
564
|
-
},
|
|
565
|
-
eligible: paymentOptions.length > 0,
|
|
566
|
-
isFull: false,
|
|
567
|
-
canJoinWaitlist: false,
|
|
568
|
-
isFree: false,
|
|
569
|
-
requiresPayment: true,
|
|
570
|
-
canPayDirectly: paymentOptions.length > 0,
|
|
571
|
-
paymentOptions,
|
|
572
|
-
eligiblePasses: [],
|
|
573
|
-
eligibleMemberships: [],
|
|
574
|
-
ticketTypes: eligibility.ticketTypes.map((option) => ({
|
|
575
|
-
...option,
|
|
576
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
577
|
-
}))
|
|
578
|
-
};
|
|
511
|
+
function normalizeTicketSelectionLines(lines) {
|
|
512
|
+
const quantitiesByTicketType = /* @__PURE__ */ new Map();
|
|
513
|
+
for (const line of lines) {
|
|
514
|
+
const quantity = Math.floor(line.quantity);
|
|
515
|
+
if (quantity <= 0) continue;
|
|
516
|
+
const key = line.pricingOptionId ?? null;
|
|
517
|
+
quantitiesByTicketType.set(key, (quantitiesByTicketType.get(key) ?? 0) + quantity);
|
|
518
|
+
}
|
|
519
|
+
return [...quantitiesByTicketType.entries()].map(([pricingOptionId, quantity]) => ({
|
|
520
|
+
pricingOptionId,
|
|
521
|
+
quantity
|
|
522
|
+
}));
|
|
579
523
|
}
|
|
580
|
-
function
|
|
581
|
-
return
|
|
524
|
+
function getTicketSelectionTotal(lines) {
|
|
525
|
+
return normalizeTicketSelectionLines(lines).reduce((total, line) => total + line.quantity, 0);
|
|
582
526
|
}
|
|
583
|
-
function
|
|
584
|
-
return
|
|
527
|
+
function getTicketLineQuantity(lines, pricingOptionId) {
|
|
528
|
+
return normalizeTicketSelectionLines(lines).find((line) => line.pricingOptionId === pricingOptionId)?.quantity ?? 0;
|
|
529
|
+
}
|
|
530
|
+
function getSingleSelectedPricingOptionId(lines) {
|
|
531
|
+
const normalized = normalizeTicketSelectionLines(lines);
|
|
532
|
+
return normalized.length === 1 ? normalized[0]?.pricingOptionId ?? null : null;
|
|
585
533
|
}
|
|
586
|
-
function
|
|
587
|
-
|
|
534
|
+
function hasValidPricingOptionSelection(input) {
|
|
535
|
+
if (!input.selectionRequired) return true;
|
|
536
|
+
if (input.lines.length === 0) return false;
|
|
537
|
+
const availableOptionIds = new Set(input.visibleOptions.filter((option) => canRequestTicketOption(option.availability)).map((option) => option.pricingOptionId));
|
|
538
|
+
return input.lines.every((line) => line.pricingOptionId !== null && availableOptionIds.has(line.pricingOptionId));
|
|
539
|
+
}
|
|
540
|
+
function setTicketLineQuantity(input) {
|
|
541
|
+
const nextQuantity = Math.max(0, Math.floor(input.quantity));
|
|
542
|
+
const normalized = normalizeTicketSelectionLines(input.lines).filter((line) => line.pricingOptionId !== input.pricingOptionId);
|
|
543
|
+
if (nextQuantity <= 0) return normalized;
|
|
544
|
+
return [...normalized, {
|
|
545
|
+
pricingOptionId: input.pricingOptionId,
|
|
546
|
+
quantity: nextQuantity
|
|
547
|
+
}];
|
|
548
|
+
}
|
|
549
|
+
function getTicketTypeLineMax(input) {
|
|
550
|
+
const otherSelectedQuantity = input.totalSelectedQuantity - input.currentQuantity;
|
|
551
|
+
const maxByBlock = input.maxTickets - otherSelectedQuantity;
|
|
552
|
+
return Math.max(0, maxByBlock);
|
|
588
553
|
}
|
|
589
554
|
//#endregion
|
|
590
555
|
//#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
|
|
@@ -651,8 +616,6 @@ function formatPassCreditUsageLabel(creditsRemaining) {
|
|
|
651
616
|
return `Uses 1 of ${creditsRemaining} credits`;
|
|
652
617
|
}
|
|
653
618
|
function transformRegistrationOptionsResponse(response) {
|
|
654
|
-
const canJoinWaitlist = response.availability.kind === "waitlist";
|
|
655
|
-
const isFull = response.availability.remainingPlaces === 0 || response.availability.kind === "unavailable" && response.availability.reason === "full";
|
|
656
619
|
const eligiblePasses = response.entitlements.passes.map((pass) => ({
|
|
657
620
|
id: pass.customerPassId,
|
|
658
621
|
passName: pass.passName,
|
|
@@ -665,7 +628,6 @@ function transformRegistrationOptionsResponse(response) {
|
|
|
665
628
|
const eventAcceptsPasses = response.entitlements.requiresLoginForPasses || eligiblePasses.length > 0 || response.entitlements.availableForPurchase.passes.length > 0;
|
|
666
629
|
const eventAcceptsMemberships = response.entitlements.requiresLoginForMemberships || eligibleMemberships.length > 0 || response.entitlements.availableForPurchase.memberships.length > 0;
|
|
667
630
|
const monetaryPaymentAvailable = hasMonetaryPaymentOption(response);
|
|
668
|
-
const registrationAvailable = response.availability.kind === "available" || response.availability.kind === "waitlist";
|
|
669
631
|
return {
|
|
670
632
|
availability: response.availability,
|
|
671
633
|
registration: response.registration,
|
|
@@ -680,7 +642,6 @@ function transformRegistrationOptionsResponse(response) {
|
|
|
680
642
|
},
|
|
681
643
|
transactions: []
|
|
682
644
|
} : null,
|
|
683
|
-
eligible: response.registration.kind === "none" && registrationAvailable,
|
|
684
645
|
requiresPayment: monetaryPaymentAvailable,
|
|
685
646
|
pricingStrategy: response.pricing.strategy,
|
|
686
647
|
paymentTerms: response.pricing.paymentTerms,
|
|
@@ -695,16 +656,12 @@ function transformRegistrationOptionsResponse(response) {
|
|
|
695
656
|
currency: response.pricing.currency
|
|
696
657
|
})),
|
|
697
658
|
ticketTypes: response.pricing.options,
|
|
698
|
-
isFull,
|
|
699
|
-
waitlistEnabled: response.availability.waitlistEnabled,
|
|
700
|
-
canJoinWaitlist,
|
|
701
659
|
price: response.pricing.subtotalCents,
|
|
702
660
|
currency: response.pricing.currency,
|
|
703
661
|
requiresAuthForPasses: response.entitlements.requiresLoginForPasses,
|
|
704
662
|
requiresAuthForMemberships: response.entitlements.requiresLoginForMemberships,
|
|
705
663
|
eligiblePasses,
|
|
706
664
|
eligibleMemberships,
|
|
707
|
-
canPayDirectly: monetaryPaymentAvailable,
|
|
708
665
|
eventAcceptsPasses,
|
|
709
666
|
eventAcceptsMemberships,
|
|
710
667
|
availablePasses: [...response.entitlements.availableForPurchase.passes],
|
|
@@ -734,8 +691,8 @@ function getVisibleTicketTypes(input) {
|
|
|
734
691
|
})) : [];
|
|
735
692
|
return (input.eligibility?.ticketTypes ?? eventTicketTypes).filter((ticketType) => ticketType.isActive && (!input.selectedAttendanceMode || (ticketType.attendanceScope ?? "both") === "both" || (ticketType.attendanceScope ?? "both") === input.selectedAttendanceMode));
|
|
736
693
|
}
|
|
737
|
-
function
|
|
738
|
-
return ticketTypes.length === 1 && ticketTypes[0]
|
|
694
|
+
function getImplicitSingleTicketType(ticketTypes) {
|
|
695
|
+
return ticketTypes.length === 1 && ticketTypes[0] && canRequestTicketOption(ticketTypes[0].availability) ? ticketTypes[0] : null;
|
|
739
696
|
}
|
|
740
697
|
function findSelectedTicketType(input) {
|
|
741
698
|
if (!input.selectedPricingOptionId) return null;
|
|
@@ -772,25 +729,19 @@ const EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCa
|
|
|
772
729
|
const remaining = getRemainingPlaces(selectMostOpenCapacitySource(event));
|
|
773
730
|
const isSoldOut = isEventFull(event);
|
|
774
731
|
const canJoinWaitlist = canJoinEventWaitlistOnAnyMode(event);
|
|
775
|
-
const isUnavailable = isSoldOut && !isSoldOutEventSelectable(event, canJoinWaitlist);
|
|
776
732
|
const isLowCapacity = remaining.kind === "low";
|
|
777
733
|
const capacityLabel = formatEventRemainingPlaces(event, { full: "Sold out" });
|
|
778
734
|
const timeZone = event.timeZone ?? null;
|
|
779
|
-
const cardClasses = [
|
|
780
|
-
"er-event-card",
|
|
781
|
-
isSelected && "er-event-card--selected",
|
|
782
|
-
isUnavailable && "er-event-card--disabled"
|
|
783
|
-
].filter(Boolean).join(" ");
|
|
735
|
+
const cardClasses = ["er-event-card", isSelected && "er-event-card--selected"].filter(Boolean).join(" ");
|
|
784
736
|
const badgeClasses = [
|
|
785
737
|
"er-capacity-badge",
|
|
786
|
-
|
|
738
|
+
isSoldOut && "er-capacity-badge--soldout",
|
|
787
739
|
isLowCapacity && "er-capacity-badge--low",
|
|
788
|
-
(canJoinWaitlist || !
|
|
740
|
+
(canJoinWaitlist || !isSoldOut && !isLowCapacity) && "er-capacity-badge--available"
|
|
789
741
|
].filter(Boolean).join(" ");
|
|
790
742
|
return /* @__PURE__ */ jsx("button", {
|
|
791
743
|
type: "button",
|
|
792
|
-
onClick: () =>
|
|
793
|
-
disabled: isUnavailable,
|
|
744
|
+
onClick: () => onSelect(event),
|
|
794
745
|
className: cardClasses,
|
|
795
746
|
children: /* @__PURE__ */ jsxs("div", {
|
|
796
747
|
className: "er-event-option",
|
|
@@ -817,41 +768,15 @@ const EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCa
|
|
|
817
768
|
});
|
|
818
769
|
};
|
|
819
770
|
//#endregion
|
|
820
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
|
|
821
|
-
/** Recovery belongs to the selected booking subject; changing events resets its scope. */
|
|
822
|
-
function useCheckoutRecovery(event, setStep) {
|
|
823
|
-
const [recoveryEventId, setRecoveryEventId] = useState(null);
|
|
824
|
-
return {
|
|
825
|
-
checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
|
|
826
|
-
startCheckoutRecovery: useCallback(() => {
|
|
827
|
-
if (!event) return;
|
|
828
|
-
setRecoveryEventId(event.selectionId);
|
|
829
|
-
setStep("select-tickets");
|
|
830
|
-
}, [event, setStep])
|
|
831
|
-
};
|
|
832
|
-
}
|
|
833
|
-
/** Authenticated pending bookings enter the same form-only recovery path as guests. */
|
|
834
|
-
function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
|
|
835
|
-
const registrationKind = eligibility?.registration.kind;
|
|
836
|
-
useEffect(() => {
|
|
837
|
-
if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
|
|
838
|
-
}, [
|
|
839
|
-
registrationKind,
|
|
840
|
-
step,
|
|
841
|
-
checkoutRecovery,
|
|
842
|
-
startCheckoutRecovery
|
|
843
|
-
]);
|
|
844
|
-
return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
|
|
845
|
-
}
|
|
846
|
-
//#endregion
|
|
847
771
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
|
|
848
772
|
function resolveRegistrationRecoveryAction(step, action) {
|
|
849
773
|
if (step === "payment-failed") return "payment-options";
|
|
850
|
-
if (step === "
|
|
774
|
+
if (step === "payment-status") return "none";
|
|
775
|
+
if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "none";
|
|
851
776
|
return action;
|
|
852
777
|
}
|
|
853
778
|
function canRecoverToWaitlist(eligibility) {
|
|
854
|
-
return
|
|
779
|
+
return eligibility?.availability.kind === "waitlist" && eligibility.registration.kind !== "pending_payment";
|
|
855
780
|
}
|
|
856
781
|
function shouldRefreshAfterRegistrationError(step, action, enabled) {
|
|
857
782
|
return enabled || step === "error" && action === "places";
|
|
@@ -868,19 +793,19 @@ function resetRegistrationAfterExpiry(input) {
|
|
|
868
793
|
input.setErrorMessage("");
|
|
869
794
|
input.setPendingRegistrationReference(null);
|
|
870
795
|
}
|
|
871
|
-
/**
|
|
796
|
+
/** Retry the retained submission in place; explicit payment uncertainty stays status-only. */
|
|
872
797
|
function recoverRegistrationError(action, handlers) {
|
|
873
798
|
switch (action) {
|
|
874
799
|
case "none": return;
|
|
875
800
|
case "portal":
|
|
876
|
-
case "payment-status":
|
|
877
801
|
window.location.assign("/portal");
|
|
878
802
|
return;
|
|
879
803
|
case "event":
|
|
880
804
|
window.location.assign(window.location.pathname);
|
|
881
805
|
return;
|
|
882
806
|
case "retry":
|
|
883
|
-
|
|
807
|
+
handlers.clearError();
|
|
808
|
+
handlers.setStep("select-payment");
|
|
884
809
|
return;
|
|
885
810
|
case "details":
|
|
886
811
|
handlers.clearError();
|
|
@@ -918,53 +843,6 @@ function validateFormData(formData, requiresConsent = false) {
|
|
|
918
843
|
return errors;
|
|
919
844
|
}
|
|
920
845
|
//#endregion
|
|
921
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.ts
|
|
922
|
-
function normalizeTicketSelectionLines(lines) {
|
|
923
|
-
const quantitiesByTicketType = /* @__PURE__ */ new Map();
|
|
924
|
-
for (const line of lines) {
|
|
925
|
-
const quantity = Math.floor(line.quantity);
|
|
926
|
-
if (quantity <= 0) continue;
|
|
927
|
-
const key = line.pricingOptionId ?? null;
|
|
928
|
-
quantitiesByTicketType.set(key, (quantitiesByTicketType.get(key) ?? 0) + quantity);
|
|
929
|
-
}
|
|
930
|
-
return [...quantitiesByTicketType.entries()].map(([pricingOptionId, quantity]) => ({
|
|
931
|
-
pricingOptionId,
|
|
932
|
-
quantity
|
|
933
|
-
}));
|
|
934
|
-
}
|
|
935
|
-
function getTicketSelectionTotal(lines) {
|
|
936
|
-
return normalizeTicketSelectionLines(lines).reduce((total, line) => total + line.quantity, 0);
|
|
937
|
-
}
|
|
938
|
-
function getTicketLineQuantity(lines, pricingOptionId) {
|
|
939
|
-
return normalizeTicketSelectionLines(lines).find((line) => line.pricingOptionId === pricingOptionId)?.quantity ?? 0;
|
|
940
|
-
}
|
|
941
|
-
function getSingleSelectedPricingOptionId(lines) {
|
|
942
|
-
const normalized = normalizeTicketSelectionLines(lines);
|
|
943
|
-
return normalized.length === 1 ? normalized[0]?.pricingOptionId ?? null : null;
|
|
944
|
-
}
|
|
945
|
-
function hasValidPricingOptionSelection(input) {
|
|
946
|
-
if (!input.selectionRequired) return true;
|
|
947
|
-
if (input.lines.length === 0) return false;
|
|
948
|
-
const availableOptionIds = new Set(input.visibleOptions.filter((option) => option.availability.kind === "available").map((option) => option.pricingOptionId));
|
|
949
|
-
return input.lines.every((line) => line.pricingOptionId !== null && availableOptionIds.has(line.pricingOptionId));
|
|
950
|
-
}
|
|
951
|
-
function setTicketLineQuantity(input) {
|
|
952
|
-
const nextQuantity = Math.max(0, Math.floor(input.quantity));
|
|
953
|
-
const normalized = normalizeTicketSelectionLines(input.lines).filter((line) => line.pricingOptionId !== input.pricingOptionId);
|
|
954
|
-
if (nextQuantity <= 0) return normalized;
|
|
955
|
-
return [...normalized, {
|
|
956
|
-
pricingOptionId: input.pricingOptionId,
|
|
957
|
-
quantity: nextQuantity
|
|
958
|
-
}];
|
|
959
|
-
}
|
|
960
|
-
function getTicketTypeLineMax(input) {
|
|
961
|
-
const otherSelectedQuantity = input.totalSelectedQuantity - input.currentQuantity;
|
|
962
|
-
const maxByBlock = input.maxTickets - otherSelectedQuantity;
|
|
963
|
-
const maxByEvent = input.availableSpots == null ? input.maxTickets : input.availableSpots - otherSelectedQuantity;
|
|
964
|
-
const maxByTicketType = input.ticketTypeRemainingCapacity ?? input.maxTickets;
|
|
965
|
-
return Math.max(0, Math.min(maxByBlock, maxByEvent, maxByTicketType));
|
|
966
|
-
}
|
|
967
|
-
//#endregion
|
|
968
846
|
//#region ../blocks/src/system/runtime/nodes/event-registration/hooks.state.ts
|
|
969
847
|
const initialEligibilityLookupState = {
|
|
970
848
|
tag: "idle",
|
|
@@ -1082,17 +960,6 @@ function usePortalAuthWithDeps(deps) {
|
|
|
1082
960
|
logout
|
|
1083
961
|
};
|
|
1084
962
|
}
|
|
1085
|
-
function toRegistrationOptionsSubject(subject, attendanceMode) {
|
|
1086
|
-
return subject.kind === "occurrence" ? {
|
|
1087
|
-
kind: "occurrence",
|
|
1088
|
-
occurrenceId: subject.occurrenceId,
|
|
1089
|
-
attendanceMode: attendanceMode ?? void 0
|
|
1090
|
-
} : {
|
|
1091
|
-
kind: "wholeSeries",
|
|
1092
|
-
eventSeriesId: subject.eventSeriesId,
|
|
1093
|
-
attendanceMode: attendanceMode ?? void 0
|
|
1094
|
-
};
|
|
1095
|
-
}
|
|
1096
963
|
function useEligibility(params) {
|
|
1097
964
|
return useEligibilityWithDeps(params, eventRegistrationHooksDeps);
|
|
1098
965
|
}
|
|
@@ -1133,7 +1000,7 @@ function useEligibilityWithDeps(params, deps) {
|
|
|
1133
1000
|
requestIdRef.current = requestId;
|
|
1134
1001
|
dispatch({ type: "loading-started" });
|
|
1135
1002
|
try {
|
|
1136
|
-
const subject =
|
|
1003
|
+
const subject = toRegistrationRequestSubject(params.subject, params.attendanceMode);
|
|
1137
1004
|
const result = await api.getRegistrationOptions({
|
|
1138
1005
|
subject,
|
|
1139
1006
|
selections: ticketSelections.map((selection) => ({
|
|
@@ -1423,7 +1290,6 @@ const STRIPE_COMMISSION_FREE_REASONS = [
|
|
|
1423
1290
|
"no_commission_plan",
|
|
1424
1291
|
"billing_evidence_invalid",
|
|
1425
1292
|
"fee_rounds_to_zero",
|
|
1426
|
-
"non_commissionable_scope",
|
|
1427
1293
|
"payment_not_stripe"
|
|
1428
1294
|
];
|
|
1429
1295
|
const historicalContext = {
|
|
@@ -1501,9 +1367,9 @@ const eventRegistrationErrors = {
|
|
|
1501
1367
|
message: "Booking is currently closed for this event. Please contact the organiser if you’d like to find out more.",
|
|
1502
1368
|
action: "none"
|
|
1503
1369
|
},
|
|
1504
|
-
|
|
1505
|
-
message: "We’
|
|
1506
|
-
action: "
|
|
1370
|
+
paymentInvestigationRequired: {
|
|
1371
|
+
message: "We still can’t confirm your payment. Please don’t make another payment. Contact the organiser so they can check your booking.",
|
|
1372
|
+
action: "none"
|
|
1507
1373
|
},
|
|
1508
1374
|
paymentProviderUnavailable: {
|
|
1509
1375
|
message: "We couldn’t reach the payment provider. Please try again in a minute.",
|
|
@@ -2001,7 +1867,30 @@ function checkoutReturnCommand(params) {
|
|
|
2001
1867
|
};
|
|
2002
1868
|
return null;
|
|
2003
1869
|
}
|
|
2004
|
-
|
|
1870
|
+
function handleCheckoutReturnOutcome(options, deps, context, outcome) {
|
|
1871
|
+
const { pending, params } = context;
|
|
1872
|
+
if (outcome.kind === "resolved") {
|
|
1873
|
+
deps.clearReturnParams();
|
|
1874
|
+
options.setPendingRegistrationReference(outcome.reference);
|
|
1875
|
+
options.setStep("verifying-payment");
|
|
1876
|
+
return "settled";
|
|
1877
|
+
}
|
|
1878
|
+
if (outcome.kind === "abandoned") {
|
|
1879
|
+
deps.clearReturnParams();
|
|
1880
|
+
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
1881
|
+
options.setStep("select-payment");
|
|
1882
|
+
return "settled";
|
|
1883
|
+
}
|
|
1884
|
+
if (outcome.kind === "notFound" && params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
|
|
1885
|
+
deps.clearReturnParams();
|
|
1886
|
+
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
1887
|
+
options.setStep("select-payment");
|
|
1888
|
+
return "settled";
|
|
1889
|
+
}
|
|
1890
|
+
showReturnReconciliation(options, "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.");
|
|
1891
|
+
return outcome.kind === "notFound" ? "settled" : "retryable";
|
|
1892
|
+
}
|
|
1893
|
+
async function handleCheckoutReturn(options, deps, returnContextRef) {
|
|
2005
1894
|
deps.cleanupStaleRegistrations();
|
|
2006
1895
|
const params = deps.readReturnParams();
|
|
2007
1896
|
if (params.registration !== "cancelled" && params.registration !== "success") return "settled";
|
|
@@ -2015,34 +1904,15 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
|
|
|
2015
1904
|
}
|
|
2016
1905
|
const { checkoutAttemptId } = command;
|
|
2017
1906
|
const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
|
|
2018
|
-
|
|
1907
|
+
returnContextRef.current = { checkoutAttemptId };
|
|
2019
1908
|
if (pending) restorePendingPresentation(options, pending);
|
|
2020
1909
|
options.setStep("verifying-payment");
|
|
2021
1910
|
try {
|
|
2022
1911
|
const outcome = await options.api.resolveEventCheckoutReturn(command);
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
options.setStep("verifying-payment");
|
|
2028
|
-
return "settled";
|
|
2029
|
-
case "abandoned":
|
|
2030
|
-
deps.clearReturnParams();
|
|
2031
|
-
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
2032
|
-
options.setStep("select-payment");
|
|
2033
|
-
return "settled";
|
|
2034
|
-
case "notFound":
|
|
2035
|
-
if (params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
|
|
2036
|
-
deps.clearReturnParams();
|
|
2037
|
-
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
2038
|
-
options.setStep("select-payment");
|
|
2039
|
-
return "settled";
|
|
2040
|
-
}
|
|
2041
|
-
showReturnReconciliation(options, "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.");
|
|
2042
|
-
return "settled";
|
|
2043
|
-
case "reconciliationRequired": break;
|
|
2044
|
-
}
|
|
2045
|
-
showReturnReconciliation(options, "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.");
|
|
1912
|
+
return handleCheckoutReturnOutcome(options, deps, {
|
|
1913
|
+
pending,
|
|
1914
|
+
params
|
|
1915
|
+
}, outcome);
|
|
2046
1916
|
} catch {
|
|
2047
1917
|
showReturnReconciliation(options, "We couldn’t check your payment just now. Please check again in a moment. Don’t make another booking while we’re checking.");
|
|
2048
1918
|
}
|
|
@@ -2051,9 +1921,16 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
|
|
|
2051
1921
|
function useEventRegistrationStripeReturn(options) {
|
|
2052
1922
|
return useEventRegistrationStripeReturnWithDeps(options, eventRegistrationStripeReturnDeps);
|
|
2053
1923
|
}
|
|
1924
|
+
function completeVerifiedRegistration(options, deps, returnContext) {
|
|
1925
|
+
const siteId = options.api.config.siteId;
|
|
1926
|
+
const checkoutAttemptId = returnContext?.checkoutAttemptId;
|
|
1927
|
+
if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
|
|
1928
|
+
options.setRegistrationResult({ status: "confirmed" });
|
|
1929
|
+
options.setStep("success");
|
|
1930
|
+
}
|
|
2054
1931
|
function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
2055
1932
|
const { api, pendingRegistrationReference, setErrorMessage, setRegistrationResult, setStep, step } = options;
|
|
2056
|
-
const
|
|
1933
|
+
const returnContextRef = useRef(null);
|
|
2057
1934
|
const lookupInFlightRef = useRef(false);
|
|
2058
1935
|
const [lookupState, setLookupState] = useState("settled");
|
|
2059
1936
|
const resolveReturn = useCallback(async () => {
|
|
@@ -2061,7 +1938,7 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
|
2061
1938
|
lookupInFlightRef.current = true;
|
|
2062
1939
|
setLookupState("loading");
|
|
2063
1940
|
try {
|
|
2064
|
-
setLookupState(await handleCheckoutReturn(options, deps,
|
|
1941
|
+
setLookupState(await handleCheckoutReturn(options, deps, returnContextRef));
|
|
2065
1942
|
} finally {
|
|
2066
1943
|
lookupInFlightRef.current = false;
|
|
2067
1944
|
}
|
|
@@ -2084,13 +1961,8 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
|
2084
1961
|
resolveReturn();
|
|
2085
1962
|
}, []);
|
|
2086
1963
|
useEffect(() => {
|
|
2087
|
-
if (verification.status === "completed")
|
|
2088
|
-
|
|
2089
|
-
const checkoutAttemptId = checkoutAttemptIdRef.current;
|
|
2090
|
-
if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
|
|
2091
|
-
setRegistrationResult({ status: "confirmed" });
|
|
2092
|
-
setStep("success");
|
|
2093
|
-
} else if (verification.status === "failed") {
|
|
1964
|
+
if (verification.status === "completed") completeVerifiedRegistration(options, deps, returnContextRef.current);
|
|
1965
|
+
else if (verification.status === "failed") {
|
|
2094
1966
|
setErrorMessage("Please try again or choose another payment option. If this keeps happening, contact the organiser for help.");
|
|
2095
1967
|
setStep("payment-failed");
|
|
2096
1968
|
} else if (verification.status === "timeout") setStep("verifying-timeout");
|
|
@@ -2119,7 +1991,10 @@ function registrationErrorPresentation(error) {
|
|
|
2119
1991
|
const reason = error instanceof BlockApiError ? parseEventRegistrationErrorReason(error.tag) : null;
|
|
2120
1992
|
if (reason) return eventRegistrationErrors[reason];
|
|
2121
1993
|
if (error instanceof BlockApiError && error.status < 500) return eventRegistrationErrors.invalidCommitInput;
|
|
2122
|
-
return
|
|
1994
|
+
return {
|
|
1995
|
+
message: "Something went wrong. Please try again.",
|
|
1996
|
+
action: "retry"
|
|
1997
|
+
};
|
|
2123
1998
|
}
|
|
2124
1999
|
//#endregion
|
|
2125
2000
|
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.ts
|
|
@@ -2148,26 +2023,6 @@ function useEventRegistrationSubmit(options) {
|
|
|
2148
2023
|
* and the balance left, which the block's copy cannot. Every other method keeps
|
|
2149
2024
|
* whatever success message the site configured.
|
|
2150
2025
|
*/
|
|
2151
|
-
function toRegistrationResult(result) {
|
|
2152
|
-
if (result.alreadyRegistered) {
|
|
2153
|
-
const waitlisted = result.status === "waitlist";
|
|
2154
|
-
return {
|
|
2155
|
-
status: result.status,
|
|
2156
|
-
variant: "info",
|
|
2157
|
-
title: waitlisted ? "Already waitlisted" : "Already registered",
|
|
2158
|
-
message: result.message ?? (waitlisted ? "You are already on the waitlist for this event." : "You are already registered for this event.")
|
|
2159
|
-
};
|
|
2160
|
-
}
|
|
2161
|
-
if (result.status === "waitlist") return {
|
|
2162
|
-
status: "waitlist",
|
|
2163
|
-
title: "Added to waitlist",
|
|
2164
|
-
message: result.message ?? (typeof result.waitlistPosition === "number" ? `You've been added to the waitlist (position ${result.waitlistPosition}).` : "You've been added to the waitlist.")
|
|
2165
|
-
};
|
|
2166
|
-
return {
|
|
2167
|
-
status: result.status,
|
|
2168
|
-
message: result.paymentMethod === "pass" ? result.message : void 0
|
|
2169
|
-
};
|
|
2170
|
-
}
|
|
2171
2026
|
function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
2172
2027
|
/**
|
|
2173
2028
|
* The command identity for the submission currently in progress.
|
|
@@ -2181,7 +2036,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
2181
2036
|
* Identical retries retain the command after a lost response. Changed form
|
|
2182
2037
|
* details get a new command so the server applies the new booking intent.
|
|
2183
2038
|
*/
|
|
2184
|
-
const commandRef =
|
|
2039
|
+
const { commandRef } = options;
|
|
2185
2040
|
const inFlightRef = useRef(null);
|
|
2186
2041
|
const submit = async (method, passId, membershipId, selection, submitOptions) => {
|
|
2187
2042
|
const target = options.registrationTarget;
|
|
@@ -2194,19 +2049,15 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
2194
2049
|
const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
|
|
2195
2050
|
try {
|
|
2196
2051
|
let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2052
|
+
let request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
|
|
2053
|
+
const intentKey = registrationRequestIntentKey(request);
|
|
2054
|
+
if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) {
|
|
2055
|
+
prepared = {
|
|
2200
2056
|
...prepared,
|
|
2201
|
-
|
|
2202
|
-
}
|
|
2057
|
+
registrationCommandId: deps.createClientCommandId()
|
|
2058
|
+
};
|
|
2059
|
+
request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
|
|
2203
2060
|
}
|
|
2204
|
-
const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
|
|
2205
|
-
const intentKey = registrationRequestIntentKey(request);
|
|
2206
|
-
if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
|
|
2207
|
-
...prepared,
|
|
2208
|
-
registrationCommandId: deps.createClientCommandId()
|
|
2209
|
-
};
|
|
2210
2061
|
commandRef.current = {
|
|
2211
2062
|
id: prepared.registrationCommandId,
|
|
2212
2063
|
intentKey
|
|
@@ -2215,8 +2066,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
2215
2066
|
...request,
|
|
2216
2067
|
registrationCommandId: prepared.registrationCommandId
|
|
2217
2068
|
});
|
|
2218
|
-
|
|
2219
|
-
return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
|
|
2069
|
+
return await completeRegistrationSubmission(options, deps, prepared, result, submitOptions);
|
|
2220
2070
|
} catch (error) {
|
|
2221
2071
|
if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
|
|
2222
2072
|
const { message, action } = registrationErrorPresentation(error);
|
|
@@ -2240,9 +2090,40 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
2240
2090
|
return pending;
|
|
2241
2091
|
};
|
|
2242
2092
|
}
|
|
2243
|
-
async function completeRegistrationSubmission(options, deps, prepared, result,
|
|
2244
|
-
|
|
2245
|
-
|
|
2093
|
+
async function completeRegistrationSubmission(options, deps, prepared, result, submitOptions) {
|
|
2094
|
+
switch (result.kind) {
|
|
2095
|
+
case "paymentStatusRequired":
|
|
2096
|
+
options.setPaymentStatusRecovery({
|
|
2097
|
+
kind: "ready",
|
|
2098
|
+
subject: result.subject
|
|
2099
|
+
});
|
|
2100
|
+
options.setStep("payment-status");
|
|
2101
|
+
return {
|
|
2102
|
+
ok: true,
|
|
2103
|
+
outcome: { kind: "payment_status" }
|
|
2104
|
+
};
|
|
2105
|
+
case "checkoutRequired":
|
|
2106
|
+
options.setPendingRegistrationReference(result.reference);
|
|
2107
|
+
savePendingCheckout(options, deps, prepared, result.submissionId, result.reference);
|
|
2108
|
+
options.setStep("redirecting");
|
|
2109
|
+
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
2110
|
+
case "waitlisted":
|
|
2111
|
+
options.setRegistrationResult({
|
|
2112
|
+
status: "waitlist",
|
|
2113
|
+
title: "Added to waitlist",
|
|
2114
|
+
message: result.waitlist.message
|
|
2115
|
+
});
|
|
2116
|
+
break;
|
|
2117
|
+
case "bookingComplete":
|
|
2118
|
+
case "paymentDeferred":
|
|
2119
|
+
options.setPendingRegistrationReference(result.reference);
|
|
2120
|
+
options.setRegistrationResult({
|
|
2121
|
+
status: "confirmed",
|
|
2122
|
+
message: result.summary.paymentMethod === "pass" ? result.summary.message : void 0
|
|
2123
|
+
});
|
|
2124
|
+
break;
|
|
2125
|
+
}
|
|
2126
|
+
options.commandRef.current = null;
|
|
2246
2127
|
options.setStep("success");
|
|
2247
2128
|
return {
|
|
2248
2129
|
ok: true,
|
|
@@ -2273,15 +2154,7 @@ function prepareSubmitContext(options, registrationCommandId, target, method, pa
|
|
|
2273
2154
|
email: guest.email?.trim().toLowerCase() || void 0,
|
|
2274
2155
|
phone: guest.phone?.trim() || void 0
|
|
2275
2156
|
})) : void 0,
|
|
2276
|
-
subject: target.subject.
|
|
2277
|
-
kind: "occurrence",
|
|
2278
|
-
occurrenceId: target.subject.occurrenceId,
|
|
2279
|
-
attendanceMode: options.selectedAttendanceMode ?? void 0
|
|
2280
|
-
} : {
|
|
2281
|
-
kind: "wholeSeries",
|
|
2282
|
-
eventSeriesId: target.subject.eventSeriesId,
|
|
2283
|
-
attendanceMode: options.selectedAttendanceMode ?? void 0
|
|
2284
|
-
}
|
|
2157
|
+
subject: toRegistrationRequestSubject(target.subject, options.selectedAttendanceMode)
|
|
2285
2158
|
};
|
|
2286
2159
|
}
|
|
2287
2160
|
function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId, selection) {
|
|
@@ -2305,85 +2178,6 @@ function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId,
|
|
|
2305
2178
|
if (method === "free") return { method };
|
|
2306
2179
|
throw new Error("Choose an available payment option.");
|
|
2307
2180
|
}
|
|
2308
|
-
async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions) {
|
|
2309
|
-
options.setStep("redirecting");
|
|
2310
|
-
if (prepared.selectionSnapshot.method !== "stripe") throw new Error("Choose an available payment option.");
|
|
2311
|
-
const checkoutAttemptId = deps.createClientCommandId();
|
|
2312
|
-
const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
|
|
2313
|
-
const result = await options.api.createEventCheckout({
|
|
2314
|
-
subject: prepared.subject,
|
|
2315
|
-
ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
|
|
2316
|
-
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
2317
|
-
email: options.formData.email.trim().toLowerCase(),
|
|
2318
|
-
name: options.formData.name.trim(),
|
|
2319
|
-
phone: options.formData.phone.trim() || void 0,
|
|
2320
|
-
formData: options.formData,
|
|
2321
|
-
consentAccepted: options.formData.consentAccepted,
|
|
2322
|
-
altchaSolution: options.altchaSolution,
|
|
2323
|
-
guests: prepared.guestsPayload,
|
|
2324
|
-
claimToken: options.claimToken ?? void 0,
|
|
2325
|
-
waitlistEntryId: options.waitlistEntryId ?? void 0,
|
|
2326
|
-
discountCode: options.discountCode.trim() || void 0,
|
|
2327
|
-
collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
|
|
2328
|
-
checkoutAttemptId,
|
|
2329
|
-
...urls
|
|
2330
|
-
});
|
|
2331
|
-
if (result.scope !== "wholeSeries") throw new Error("Unexpected registration scope for event checkout.");
|
|
2332
|
-
if ("waitlistEntryId" in result) {
|
|
2333
|
-
options.setRegistrationResult({
|
|
2334
|
-
status: "waitlist",
|
|
2335
|
-
variant: result.alreadyRegistered ? "info" : void 0,
|
|
2336
|
-
title: result.alreadyRegistered ? "Already waitlisted" : "Added to waitlist",
|
|
2337
|
-
message: result.alreadyRegistered ? "You are already on the waitlist for this event." : "You've been added to the waitlist."
|
|
2338
|
-
});
|
|
2339
|
-
options.setStep("success");
|
|
2340
|
-
return {
|
|
2341
|
-
ok: true,
|
|
2342
|
-
outcome: { kind: "completed" }
|
|
2343
|
-
};
|
|
2344
|
-
}
|
|
2345
|
-
if (result.bypassed) return completeBypassedCheckout(options);
|
|
2346
|
-
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
2347
|
-
savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
|
|
2348
|
-
scope: "wholeSeries",
|
|
2349
|
-
registrationId: result.registrationId
|
|
2350
|
-
});
|
|
2351
|
-
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
2352
|
-
}
|
|
2353
|
-
function needsOccurrenceCheckout(result, method) {
|
|
2354
|
-
return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
|
|
2355
|
-
"stripe",
|
|
2356
|
-
"pass_bundle",
|
|
2357
|
-
"membership_bundle"
|
|
2358
|
-
].includes(method);
|
|
2359
|
-
}
|
|
2360
|
-
async function submitOccurrenceCheckout(options, deps, prepared, registration, method, submitOptions) {
|
|
2361
|
-
const reference = {
|
|
2362
|
-
scope: "occurrence",
|
|
2363
|
-
attendeeId: registration.attendeeId
|
|
2364
|
-
};
|
|
2365
|
-
options.setPendingRegistrationReference(reference);
|
|
2366
|
-
options.setStep("redirecting");
|
|
2367
|
-
const checkoutAttemptId = deps.createClientCommandId();
|
|
2368
|
-
const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
|
|
2369
|
-
const result = await options.api.createEventCheckout({
|
|
2370
|
-
subject: {
|
|
2371
|
-
kind: "occurrence",
|
|
2372
|
-
attendeeId: registration.attendeeId
|
|
2373
|
-
},
|
|
2374
|
-
registrationCommandId: prepared.registrationCommandId,
|
|
2375
|
-
checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
|
|
2376
|
-
productId: prepared.bundleProductId,
|
|
2377
|
-
discountCode: options.discountCode.trim() || void 0,
|
|
2378
|
-
collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0,
|
|
2379
|
-
...urls
|
|
2380
|
-
});
|
|
2381
|
-
if (result.scope !== "occurrence") throw new Error("Unexpected registration scope for event checkout.");
|
|
2382
|
-
if (result.bypassed) return completeBypassedCheckout(options);
|
|
2383
|
-
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
2384
|
-
if (prepared.subject.kind === "occurrence") savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference);
|
|
2385
|
-
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
2386
|
-
}
|
|
2387
2181
|
function savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference) {
|
|
2388
2182
|
const siteId = options.api.config.siteId;
|
|
2389
2183
|
if (!siteId) return;
|
|
@@ -2396,14 +2190,6 @@ function savePendingCheckout(options, deps, prepared, checkoutAttemptId, referen
|
|
|
2396
2190
|
paymentSelection: prepared.selectionSnapshot
|
|
2397
2191
|
});
|
|
2398
2192
|
}
|
|
2399
|
-
function completeBypassedCheckout(options) {
|
|
2400
|
-
options.setRegistrationResult({ status: "confirmed" });
|
|
2401
|
-
options.setStep("success");
|
|
2402
|
-
return {
|
|
2403
|
-
ok: true,
|
|
2404
|
-
outcome: { kind: "completed" }
|
|
2405
|
-
};
|
|
2406
|
-
}
|
|
2407
2193
|
function redirectToCheckout(checkoutUrl, submitOptions) {
|
|
2408
2194
|
if (submitOptions?.redirect !== "manual") window.location.href = checkoutUrl;
|
|
2409
2195
|
return {
|
|
@@ -2415,12 +2201,23 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
|
|
|
2415
2201
|
};
|
|
2416
2202
|
}
|
|
2417
2203
|
function registrationRequestIntentKey(request) {
|
|
2418
|
-
const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
|
|
2419
|
-
return JSON.stringify(
|
|
2204
|
+
const { registrationCommandId: _command, altchaSolution: _proof, checkout, ...intent } = request;
|
|
2205
|
+
return JSON.stringify({
|
|
2206
|
+
...intent,
|
|
2207
|
+
checkout: checkout ? {
|
|
2208
|
+
discountCode: checkout.discountCode,
|
|
2209
|
+
collectionOptionKind: checkout.collectionOptionKind
|
|
2210
|
+
} : void 0
|
|
2211
|
+
});
|
|
2420
2212
|
}
|
|
2421
|
-
function
|
|
2213
|
+
function buildRegistrationRequest(options, prepared, method, passId, membershipId) {
|
|
2422
2214
|
return {
|
|
2423
2215
|
registrationCommandId: prepared.registrationCommandId,
|
|
2216
|
+
checkout: {
|
|
2217
|
+
...buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: prepared.registrationCommandId }),
|
|
2218
|
+
discountCode: options.discountCode.trim() || void 0,
|
|
2219
|
+
collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0
|
|
2220
|
+
},
|
|
2424
2221
|
subject: prepared.subject,
|
|
2425
2222
|
ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
|
|
2426
2223
|
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
@@ -2638,20 +2435,124 @@ function useWaitlistClaimRestoration(input) {
|
|
|
2638
2435
|
}
|
|
2639
2436
|
//#endregion
|
|
2640
2437
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationCompletion.ts
|
|
2438
|
+
function isSelectionSoldOut(availability) {
|
|
2439
|
+
return availability?.kind === "unavailable" && availability.reason === "full";
|
|
2440
|
+
}
|
|
2641
2441
|
function resolveRegistrationAvailabilityBlocker(input) {
|
|
2642
2442
|
if (input.hasWaitlistClaim) return null;
|
|
2643
2443
|
if (input.eligibilityError) return input.eligibilityError;
|
|
2644
2444
|
if (!input.eligibility) return "Registration is not available for this event.";
|
|
2445
|
+
if (input.eligibility.registration.kind === "pending_payment") return null;
|
|
2446
|
+
if (isSelectionSoldOut(input.eligibility.availability)) return null;
|
|
2645
2447
|
if (input.eligibility.availability.kind === "unavailable" && input.eligibility.availability.reason === "paymentUnavailable") return "Payment options are not available for this event.";
|
|
2646
|
-
if (input.eligibility.availability.kind === "unavailable" ||
|
|
2448
|
+
if (input.eligibility.availability.kind === "unavailable" || input.eligibility.registration.kind === "waitlisted") return "Registration is not available for this event.";
|
|
2647
2449
|
return null;
|
|
2648
2450
|
}
|
|
2649
2451
|
function resolvePricingSelectionBlocker(input) {
|
|
2650
2452
|
if (input.selectionRequired && !input.hasValidSelection) return "Choose at least one available ticket to continue.";
|
|
2651
2453
|
return input.slidingScaleSelectionMessage;
|
|
2652
2454
|
}
|
|
2653
|
-
|
|
2654
|
-
|
|
2455
|
+
//#endregion
|
|
2456
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.ts
|
|
2457
|
+
function isCheckableRecovery(state) {
|
|
2458
|
+
return state.kind === "ready" || state.kind === "processing" || state.kind === "temporarilyUnavailable";
|
|
2459
|
+
}
|
|
2460
|
+
function assistanceRequired(recovery) {
|
|
2461
|
+
return {
|
|
2462
|
+
kind: "assistanceRequired",
|
|
2463
|
+
subject: recovery.subject
|
|
2464
|
+
};
|
|
2465
|
+
}
|
|
2466
|
+
function applyStatusOutcome(outcome, recovery, setters, setRecovery) {
|
|
2467
|
+
if (outcome.kind === "resolved") {
|
|
2468
|
+
setters.setPendingRegistrationReference(outcome.reference);
|
|
2469
|
+
setters.setRegistrationResult({ status: "confirmed" });
|
|
2470
|
+
setRecovery(null);
|
|
2471
|
+
setters.setStep("success");
|
|
2472
|
+
return;
|
|
2473
|
+
}
|
|
2474
|
+
switch (outcome.kind) {
|
|
2475
|
+
case "paymentProcessing":
|
|
2476
|
+
setRecovery({
|
|
2477
|
+
...recovery,
|
|
2478
|
+
kind: "processing"
|
|
2479
|
+
});
|
|
2480
|
+
return;
|
|
2481
|
+
case "paymentAvailable":
|
|
2482
|
+
setRecovery({
|
|
2483
|
+
...recovery,
|
|
2484
|
+
kind: "paymentAvailable",
|
|
2485
|
+
checkoutUrl: outcome.checkoutUrl
|
|
2486
|
+
});
|
|
2487
|
+
return;
|
|
2488
|
+
case "paymentCheckUnavailable":
|
|
2489
|
+
setRecovery({
|
|
2490
|
+
...recovery,
|
|
2491
|
+
kind: "temporarilyUnavailable"
|
|
2492
|
+
});
|
|
2493
|
+
return;
|
|
2494
|
+
case "paymentRetryAvailable":
|
|
2495
|
+
setRecovery({
|
|
2496
|
+
...recovery,
|
|
2497
|
+
kind: "retryAvailable"
|
|
2498
|
+
});
|
|
2499
|
+
return;
|
|
2500
|
+
case "abandoned":
|
|
2501
|
+
case "notFound":
|
|
2502
|
+
case "reconciliationRequired":
|
|
2503
|
+
case "paymentAssistanceRequired":
|
|
2504
|
+
setRecovery(assistanceRequired(recovery));
|
|
2505
|
+
return;
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
function usePaymentStatusRecovery(options) {
|
|
2509
|
+
const [recovery, setRecovery] = useState(null);
|
|
2510
|
+
const checkRef = useRef(null);
|
|
2511
|
+
return {
|
|
2512
|
+
recovery,
|
|
2513
|
+
showRecovery: useCallback((next) => setRecovery(next), []),
|
|
2514
|
+
check: useCallback(() => {
|
|
2515
|
+
if (!recovery || !isCheckableRecovery(recovery) || checkRef.current) return;
|
|
2516
|
+
const pending = (async () => {
|
|
2517
|
+
setRecovery({
|
|
2518
|
+
...recovery,
|
|
2519
|
+
kind: "checking"
|
|
2520
|
+
});
|
|
2521
|
+
try {
|
|
2522
|
+
applyStatusOutcome(await options.api.resolveEventCheckoutReturn({
|
|
2523
|
+
kind: "checkStatus",
|
|
2524
|
+
subject: recovery.subject
|
|
2525
|
+
}), recovery, options, setRecovery);
|
|
2526
|
+
} catch {
|
|
2527
|
+
setRecovery({
|
|
2528
|
+
...recovery,
|
|
2529
|
+
kind: "temporarilyUnavailable"
|
|
2530
|
+
});
|
|
2531
|
+
}
|
|
2532
|
+
})();
|
|
2533
|
+
checkRef.current = pending;
|
|
2534
|
+
pending.finally(() => {
|
|
2535
|
+
if (checkRef.current === pending) checkRef.current = null;
|
|
2536
|
+
});
|
|
2537
|
+
}, [options, recovery]),
|
|
2538
|
+
continuePayment: useCallback(() => {
|
|
2539
|
+
if (recovery?.kind === "paymentAvailable") window.location.assign(recovery.checkoutUrl);
|
|
2540
|
+
}, [recovery]),
|
|
2541
|
+
returnToPayment: useCallback(() => {
|
|
2542
|
+
if (recovery?.kind !== "retryAvailable") return;
|
|
2543
|
+
options.beginNewSubmission();
|
|
2544
|
+
setRecovery(null);
|
|
2545
|
+
options.setOptionsRefreshKey((value) => value + 1);
|
|
2546
|
+
options.setStep("select-payment");
|
|
2547
|
+
}, [options, recovery]),
|
|
2548
|
+
returnToBooking: useCallback(() => {
|
|
2549
|
+
if (recovery?.kind !== "assistanceRequired") return;
|
|
2550
|
+
options.beginNewSubmission();
|
|
2551
|
+
setRecovery(null);
|
|
2552
|
+
options.setOptionsRefreshKey((value) => value + 1);
|
|
2553
|
+
options.setStep("select-tickets");
|
|
2554
|
+
}, [options, recovery])
|
|
2555
|
+
};
|
|
2655
2556
|
}
|
|
2656
2557
|
//#endregion
|
|
2657
2558
|
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
|
|
@@ -2709,6 +2610,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
2709
2610
|
const [errorAction, setErrorAction] = useState("retry");
|
|
2710
2611
|
const [optionsRefreshKey, setOptionsRefreshKey] = useState(0);
|
|
2711
2612
|
const [altchaSolution, setAltchaSolution] = useState(null);
|
|
2613
|
+
const [checkingNextStep, setCheckingNextStep] = useState(false);
|
|
2712
2614
|
const { authState: portalAuthState, profile: portalProfile } = deps.usePortalAuth();
|
|
2713
2615
|
const waitlistClaim = deps.useWaitlistClaim();
|
|
2714
2616
|
const [showMagicLinkModal, setShowMagicLinkModal] = useState(false);
|
|
@@ -2735,28 +2637,29 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
2735
2637
|
}), [options.occurrenceContext, selectedEvent]);
|
|
2736
2638
|
const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
|
|
2737
2639
|
const currentEvent = selectedEvent ?? preSelectedEvent;
|
|
2640
|
+
const commandRef = useRef(null);
|
|
2738
2641
|
const setStep = useCallback((nextStep) => {
|
|
2739
2642
|
dispatchFlow({
|
|
2740
2643
|
type: "set-step",
|
|
2741
2644
|
step: nextStep
|
|
2742
2645
|
});
|
|
2743
2646
|
}, []);
|
|
2744
|
-
const {
|
|
2745
|
-
|
|
2746
|
-
|
|
2747
|
-
|
|
2647
|
+
const { recovery: paymentStatusRecovery, showRecovery: setPaymentStatusRecovery, check: handleCheckPaymentStatus, continuePayment: handleContinueExistingPayment, returnToPayment: handleReturnToPayment, returnToBooking: handleReturnToBooking } = usePaymentStatusRecovery({
|
|
2648
|
+
api,
|
|
2649
|
+
beginNewSubmission: () => {
|
|
2650
|
+
commandRef.current = null;
|
|
2651
|
+
},
|
|
2652
|
+
setPendingRegistrationReference,
|
|
2653
|
+
setRegistrationResult,
|
|
2654
|
+
setOptionsRefreshKey,
|
|
2655
|
+
setStep
|
|
2656
|
+
});
|
|
2657
|
+
const usesTicketTypeSelections = usesTieredPricing(currentEvent);
|
|
2748
2658
|
const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
|
|
2749
2659
|
event: currentEvent,
|
|
2750
2660
|
eligibility: null,
|
|
2751
2661
|
selectedAttendanceMode
|
|
2752
|
-
})
|
|
2753
|
-
...option,
|
|
2754
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
2755
|
-
} : option), [
|
|
2756
|
-
currentEvent,
|
|
2757
|
-
selectedAttendanceMode,
|
|
2758
|
-
checkoutRecovery
|
|
2759
|
-
]);
|
|
2662
|
+
}), [currentEvent, selectedAttendanceMode]);
|
|
2760
2663
|
const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
|
|
2761
2664
|
const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
|
|
2762
2665
|
const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
|
|
@@ -2794,7 +2697,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
2794
2697
|
isAuthenticated: portalAuthState === "authenticated",
|
|
2795
2698
|
occurrenceId: registrationOccurrenceId
|
|
2796
2699
|
});
|
|
2797
|
-
const eligibility =
|
|
2700
|
+
const eligibility = eligibilityResult.eligibility;
|
|
2798
2701
|
const eligibilityLoading = eligibilityResult.isLoading;
|
|
2799
2702
|
const eligibilityError = eligibilityResult.error;
|
|
2800
2703
|
const portalCreditState = eligibilityResult.creditState;
|
|
@@ -2906,14 +2809,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
2906
2809
|
event: currentEvent,
|
|
2907
2810
|
eligibility,
|
|
2908
2811
|
selectedAttendanceMode
|
|
2909
|
-
})
|
|
2910
|
-
...option,
|
|
2911
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
2912
|
-
} : option), [
|
|
2812
|
+
}), [
|
|
2913
2813
|
currentEvent,
|
|
2914
2814
|
selectedAttendanceMode,
|
|
2915
|
-
eligibility
|
|
2916
|
-
checkoutRecovery
|
|
2815
|
+
eligibility
|
|
2917
2816
|
]);
|
|
2918
2817
|
const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
|
|
2919
2818
|
const selectedTicketType = useMemo(() => findSelectedTicketType({
|
|
@@ -2937,12 +2836,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
2937
2836
|
const event = currentEvent;
|
|
2938
2837
|
if (!usesTieredPricing(event)) return false;
|
|
2939
2838
|
if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
|
|
2940
|
-
return
|
|
2941
|
-
}, [
|
|
2942
|
-
currentEvent,
|
|
2943
|
-
selectedAttendanceMode,
|
|
2944
|
-
checkoutRecovery
|
|
2945
|
-
]);
|
|
2839
|
+
return true;
|
|
2840
|
+
}, [currentEvent, selectedAttendanceMode]);
|
|
2946
2841
|
const hasValidTicketSelection = hasValidPricingOptionSelection({
|
|
2947
2842
|
selectionRequired: ticketTypeSelectionRequired,
|
|
2948
2843
|
lines: normalizedSelectedTicketLines,
|
|
@@ -2953,8 +2848,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
2953
2848
|
if (selectedTicketLines.length > 0) setSelectedTicketLines([]);
|
|
2954
2849
|
return;
|
|
2955
2850
|
}
|
|
2956
|
-
const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => ticketType.availability
|
|
2957
|
-
const implicitTicketType =
|
|
2851
|
+
const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => canRequestTicketOption(ticketType.availability));
|
|
2852
|
+
const implicitTicketType = getImplicitSingleTicketType(eventTicketTypesForSelection);
|
|
2958
2853
|
if (implicitTicketType && normalizedSelectedTicketLines.length === 0) {
|
|
2959
2854
|
setSelectedTicketLines([{
|
|
2960
2855
|
pricingOptionId: implicitTicketType.pricingOptionId,
|
|
@@ -3021,6 +2916,26 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3021
2916
|
selectedEventSlidingScale,
|
|
3022
2917
|
selectedSlidingAmount
|
|
3023
2918
|
]);
|
|
2919
|
+
const checkDetailsNextStep = async () => {
|
|
2920
|
+
if (portalAuthState === "authenticated" || waitlistClaim.claim || eligibility?.availability.kind === "available" || !registrationTarget) return { kind: canRecoverToWaitlist(eligibility) ? "waitlist" : "continue" };
|
|
2921
|
+
setCheckingNextStep(true);
|
|
2922
|
+
try {
|
|
2923
|
+
return await api.checkRegistrationNextStep({
|
|
2924
|
+
subject: toRegistrationRequestSubject(registrationTarget.subject, selectedAttendanceMode),
|
|
2925
|
+
selections: ticketSelections,
|
|
2926
|
+
selectedSlidingAmount: selectedSlidingAmount ?? void 0,
|
|
2927
|
+
email: formData.email,
|
|
2928
|
+
altchaSolution
|
|
2929
|
+
});
|
|
2930
|
+
} catch {
|
|
2931
|
+
return {
|
|
2932
|
+
kind: "unavailable",
|
|
2933
|
+
message: "We could not check availability. Please try again."
|
|
2934
|
+
};
|
|
2935
|
+
} finally {
|
|
2936
|
+
setCheckingNextStep(false);
|
|
2937
|
+
}
|
|
2938
|
+
};
|
|
3024
2939
|
const handleDetailsComplete = async () => {
|
|
3025
2940
|
const blockDetailsCompletion = (message) => {
|
|
3026
2941
|
setErrorAction("places");
|
|
@@ -3052,11 +2967,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3052
2967
|
message: "Check the highlighted fields and try again."
|
|
3053
2968
|
};
|
|
3054
2969
|
}
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
if (!eligibility?.canJoinWaitlist && requiresPaymentStep({
|
|
2970
|
+
const next = await checkDetailsNextStep();
|
|
2971
|
+
if (next.kind === "unavailable") return blockDetailsCompletion(next.message);
|
|
2972
|
+
const canJoinWaitlist = next.kind === "waitlist";
|
|
2973
|
+
if (!canJoinWaitlist && requiresPaymentStep({
|
|
3060
2974
|
eventRequiresPayment,
|
|
3061
2975
|
paymentSelection
|
|
3062
2976
|
})) {
|
|
@@ -3069,7 +2983,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3069
2983
|
const submitPlan = resolveEventRegistrationSubmitPlan({
|
|
3070
2984
|
paymentSelection,
|
|
3071
2985
|
eventRequiresPayment,
|
|
3072
|
-
canJoinWaitlist
|
|
2986
|
+
canJoinWaitlist
|
|
3073
2987
|
});
|
|
3074
2988
|
if (!submitPlan.ok) return blockDetailsCompletion(submitPlan.message);
|
|
3075
2989
|
const submitResult = await handleSubmit(submitPlan.args.method, submitPlan.args.passId, submitPlan.args.membershipId, submitPlan.args.selection);
|
|
@@ -3087,7 +3001,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3087
3001
|
const submitPlan = resolveEventRegistrationSubmitPlan({
|
|
3088
3002
|
paymentSelection,
|
|
3089
3003
|
eventRequiresPayment,
|
|
3090
|
-
canJoinWaitlist:
|
|
3004
|
+
canJoinWaitlist: false
|
|
3091
3005
|
});
|
|
3092
3006
|
if (!submitPlan.ok) {
|
|
3093
3007
|
setErrorMessage(submitPlan.message);
|
|
@@ -3119,6 +3033,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3119
3033
|
const selectionMethod = paymentSelection.method;
|
|
3120
3034
|
const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
|
|
3121
3035
|
const handleSubmit = deps.useEventRegistrationSubmit({
|
|
3036
|
+
commandRef,
|
|
3122
3037
|
setErrorAction,
|
|
3123
3038
|
api,
|
|
3124
3039
|
registrationTarget,
|
|
@@ -3135,7 +3050,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3135
3050
|
setPendingRegistrationReference,
|
|
3136
3051
|
setStep,
|
|
3137
3052
|
setRegistrationResult: (result) => setRegistrationResult(result),
|
|
3138
|
-
setErrorMessage
|
|
3053
|
+
setErrorMessage,
|
|
3054
|
+
setPaymentStatusRecovery
|
|
3139
3055
|
});
|
|
3140
3056
|
const handleEventSelect = (event) => {
|
|
3141
3057
|
setSelectedEvent(event);
|
|
@@ -3194,8 +3110,6 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3194
3110
|
scopedEvents,
|
|
3195
3111
|
preSelectedEvent,
|
|
3196
3112
|
hasPreSelectedContext,
|
|
3197
|
-
checkoutRecovery,
|
|
3198
|
-
startCheckoutRecovery,
|
|
3199
3113
|
step,
|
|
3200
3114
|
setStep,
|
|
3201
3115
|
selectedEvent,
|
|
@@ -3249,7 +3163,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3249
3163
|
waitlistClaim,
|
|
3250
3164
|
eligibility,
|
|
3251
3165
|
registrationOptionsState: eligibilityResult.state,
|
|
3252
|
-
eligibilityLoading,
|
|
3166
|
+
eligibilityLoading: eligibilityLoading || checkingNextStep,
|
|
3253
3167
|
eligibilityError,
|
|
3254
3168
|
existingRegistration: existingRegistrationResult.registration,
|
|
3255
3169
|
existingRegistrationLoading: existingRegistrationResult.isLoading || portalAuthState === "authenticated" && eligibilityLoading,
|
|
@@ -3269,6 +3183,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
3269
3183
|
discountContext,
|
|
3270
3184
|
shouldShowDiscountToggle,
|
|
3271
3185
|
verification,
|
|
3186
|
+
paymentStatusRecovery,
|
|
3187
|
+
handleCheckPaymentStatus,
|
|
3188
|
+
handleContinueExistingPayment,
|
|
3189
|
+
handleReturnToPayment,
|
|
3190
|
+
handleReturnToBooking,
|
|
3272
3191
|
handleDetailsComplete,
|
|
3273
3192
|
handlePaymentSelect,
|
|
3274
3193
|
handleUseCardInsteadOfPass,
|
|
@@ -3440,7 +3359,6 @@ const labels = {
|
|
|
3440
3359
|
start: "Start again",
|
|
3441
3360
|
details: "Check my details",
|
|
3442
3361
|
"payment-options": "View payment options",
|
|
3443
|
-
"payment-status": "Check payment status",
|
|
3444
3362
|
portal: "View my bookings",
|
|
3445
3363
|
event: "View event"
|
|
3446
3364
|
};
|
|
@@ -3459,7 +3377,7 @@ const ErrorStep = ({ message, onRetry, action = "retry", canJoinWaitlist = false
|
|
|
3459
3377
|
className: "er-text--muted er-message",
|
|
3460
3378
|
children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
|
|
3461
3379
|
}),
|
|
3462
|
-
actions: action === "none" ? void 0 : action === "portal"
|
|
3380
|
+
actions: action === "none" ? void 0 : action === "portal" ? /* @__PURE__ */ jsx("a", {
|
|
3463
3381
|
href: "/portal",
|
|
3464
3382
|
className: "er-retry-btn",
|
|
3465
3383
|
children: labels[action]
|
|
@@ -3713,8 +3631,11 @@ function EventRegistrationSummaryBar(props) {
|
|
|
3713
3631
|
*/
|
|
3714
3632
|
function resolveDetailsButtonText(input) {
|
|
3715
3633
|
const { wizard } = input;
|
|
3716
|
-
|
|
3717
|
-
|
|
3634
|
+
const availability = wizard.eligibility?.availability;
|
|
3635
|
+
const full = availability?.kind === "waitlist" || isSelectionSoldOut(availability);
|
|
3636
|
+
if (wizard.portalAuthState !== "authenticated" && full) return "Continue";
|
|
3637
|
+
if (canRecoverToWaitlist(wizard.eligibility)) return "Join waitlist";
|
|
3638
|
+
if (!input.hasWaitlistClaim && full && wizard.eligibility?.registration.kind !== "pending_payment") return "Sold out";
|
|
3718
3639
|
if (wizard.paymentSelection.method === "pass") return "Book using class pass";
|
|
3719
3640
|
if (wizard.paymentSelection.method === "membership") return input.fallbackText;
|
|
3720
3641
|
return wizard.eventRequiresPayment ? "Continue to payment" : input.fallbackText;
|
|
@@ -3729,44 +3650,28 @@ function isExistingRegistrationBlocking$1(wizard) {
|
|
|
3729
3650
|
hasWaitlistClaim: wizard.waitlistClaim.claim !== null
|
|
3730
3651
|
});
|
|
3731
3652
|
}
|
|
3732
|
-
/**
|
|
3733
|
-
* Full for the visitor's selected attendance mode (or the whole event when no
|
|
3734
|
-
* mode is chosen) with no waitlist to fall back on. Reads the same capacity
|
|
3735
|
-
* source as the steps above the action bar so the button never disagrees
|
|
3736
|
-
* with them on a hybrid event.
|
|
3737
|
-
*/
|
|
3738
|
-
function isFullWithNoWaitlist(event, attendanceMode) {
|
|
3739
|
-
if (!event) return false;
|
|
3740
|
-
const source = selectEventCapacitySource(event, attendanceMode);
|
|
3741
|
-
return getEventAvailability(source).isFull && !source.waitlistEnabled;
|
|
3742
|
-
}
|
|
3743
3653
|
function resolveTicketSelectionContinueLabel(input) {
|
|
3744
3654
|
if (input.isCheckingExistingRegistration) return "Checking registration...";
|
|
3745
3655
|
if (input.registrationOptionsPending) return "Checking availability...";
|
|
3746
3656
|
if (input.registrationOptionsFailed) return "Availability unavailable";
|
|
3747
3657
|
if (input.hasExistingRegistration) return resolveExistingRegistrationLabel(input.wizard);
|
|
3748
|
-
if (input.isSoldOutWithoutWaitlist) return "Sold out";
|
|
3749
3658
|
if (input.ticketTypeSelectionBlocked) return "Choose a ticket";
|
|
3750
3659
|
return "Continue";
|
|
3751
3660
|
}
|
|
3752
3661
|
function SelectTicketsActions(props) {
|
|
3753
3662
|
const { wizard } = props;
|
|
3754
|
-
const hasWaitlistClaim = wizard.waitlistClaim.claim !== null;
|
|
3755
|
-
const currentEvent = wizard.selectedEvent ?? wizard.preSelectedEvent;
|
|
3756
3663
|
const registrationOptionsPending = wizard.registrationOptionsState.tag === "idle" || wizard.registrationOptionsState.tag === "loading";
|
|
3757
3664
|
const registrationOptionsFailed = wizard.registrationOptionsState.tag === "failed";
|
|
3758
|
-
const isSoldOutWithoutWaitlist = !wizard.checkoutRecovery && !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
|
|
3759
3665
|
const isCheckingExistingRegistration = wizard.portalAuthState === "authenticated" && wizard.existingRegistrationLoading;
|
|
3760
3666
|
const hasExistingRegistration = isExistingRegistrationBlocking$1(wizard);
|
|
3761
3667
|
const ticketTypeSelectionBlocked = wizard.ticketTypeSelectionRequired && !wizard.hasValidTicketSelection;
|
|
3762
|
-
const isContinueDisabled = registrationOptionsPending || registrationOptionsFailed || isCheckingExistingRegistration || hasExistingRegistration ||
|
|
3668
|
+
const isContinueDisabled = registrationOptionsPending || registrationOptionsFailed || isCheckingExistingRegistration || hasExistingRegistration || ticketTypeSelectionBlocked;
|
|
3763
3669
|
const continueLabel = resolveTicketSelectionContinueLabel({
|
|
3764
3670
|
wizard,
|
|
3765
3671
|
registrationOptionsPending,
|
|
3766
3672
|
registrationOptionsFailed,
|
|
3767
3673
|
isCheckingExistingRegistration,
|
|
3768
3674
|
hasExistingRegistration,
|
|
3769
|
-
isSoldOutWithoutWaitlist,
|
|
3770
3675
|
ticketTypeSelectionBlocked
|
|
3771
3676
|
});
|
|
3772
3677
|
return /* @__PURE__ */ jsxs("div", {
|
|
@@ -3797,8 +3702,12 @@ function EnterDetailsActions(props) {
|
|
|
3797
3702
|
const { wizard } = props;
|
|
3798
3703
|
const hasWaitlistClaim = wizard.waitlistClaim.claim !== null;
|
|
3799
3704
|
const isCheckingEligibility = wizard.eligibilityLoading;
|
|
3800
|
-
const eligibilityUnavailable =
|
|
3801
|
-
|
|
3705
|
+
const eligibilityUnavailable = Boolean(resolveRegistrationAvailabilityBlocker({
|
|
3706
|
+
hasWaitlistClaim,
|
|
3707
|
+
eligibility: wizard.eligibility,
|
|
3708
|
+
eligibilityError: wizard.eligibilityError
|
|
3709
|
+
}));
|
|
3710
|
+
const isSoldOut = !hasWaitlistClaim && wizard.portalAuthState === "authenticated" && wizard.eligibility?.registration.kind !== "pending_payment" && isSelectionSoldOut(wizard.eligibility?.availability);
|
|
3802
3711
|
const isContinueDisabled = isCheckingEligibility || eligibilityUnavailable || isSoldOut;
|
|
3803
3712
|
const continueLabel = isCheckingEligibility ? "Checking availability..." : wizard.eligibilityError ? "Availability unavailable" : eligibilityUnavailable ? "Registration unavailable" : resolveDetailsButtonText({
|
|
3804
3713
|
wizard,
|
|
@@ -3849,6 +3758,7 @@ function EventRegistrationWizardActions(props) {
|
|
|
3849
3758
|
case "redirecting":
|
|
3850
3759
|
case "verifying-payment":
|
|
3851
3760
|
case "verifying-timeout":
|
|
3761
|
+
case "payment-status":
|
|
3852
3762
|
case "payment-failed": return null;
|
|
3853
3763
|
case "select-event": return null;
|
|
3854
3764
|
case "select-tickets": return /* @__PURE__ */ jsx(SelectTicketsActions, { ...props });
|
|
@@ -3933,7 +3843,7 @@ function buildSelectedSiteCreditPreview(input) {
|
|
|
3933
3843
|
function resolvePaymentStepStatus(input) {
|
|
3934
3844
|
if (input.loading) return "loading";
|
|
3935
3845
|
if (input.error || !input.eligibility) return "error";
|
|
3936
|
-
if (input.eligibility.registration.kind
|
|
3846
|
+
if (input.eligibility.registration.kind === "waitlisted" || input.eligibility.paymentOptions.length === 0) return "not-eligible";
|
|
3937
3847
|
return "ready";
|
|
3938
3848
|
}
|
|
3939
3849
|
function shouldPromptForLogin(status, isAuthenticated, eligibility) {
|
|
@@ -3968,7 +3878,7 @@ function UnavailableEntitlementMessage(props) {
|
|
|
3968
3878
|
] });
|
|
3969
3879
|
}
|
|
3970
3880
|
function IneligiblePaymentPanel(props) {
|
|
3971
|
-
if (props.eligibility.
|
|
3881
|
+
if (isSelectionSoldOut(props.eligibility.availability)) return /* @__PURE__ */ jsxs("div", {
|
|
3972
3882
|
className: "rb-reg-stack er-stack",
|
|
3973
3883
|
children: [/* @__PURE__ */ jsx("h3", {
|
|
3974
3884
|
className: "er-title",
|
|
@@ -4037,26 +3947,23 @@ function PaymentBlockingPanel(props) {
|
|
|
4037
3947
|
})
|
|
4038
3948
|
});
|
|
4039
3949
|
if (!props.eligibility) return /* @__PURE__ */ jsx(MissingEligibilityPanel, {});
|
|
4040
|
-
if (props.eligibility.registration.kind
|
|
4041
|
-
|
|
4042
|
-
|
|
4043
|
-
className: "
|
|
4044
|
-
children:
|
|
4045
|
-
|
|
4046
|
-
|
|
4047
|
-
|
|
4048
|
-
className: "er-
|
|
4049
|
-
children:
|
|
4050
|
-
|
|
4051
|
-
|
|
4052
|
-
|
|
4053
|
-
|
|
4054
|
-
className: "er-retry-btn",
|
|
4055
|
-
children: "View my bookings"
|
|
4056
|
-
})]
|
|
3950
|
+
if (props.eligibility.registration.kind === "waitlisted") return /* @__PURE__ */ jsxs("div", {
|
|
3951
|
+
className: "rb-reg-stack er-stack",
|
|
3952
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
3953
|
+
className: "er-title",
|
|
3954
|
+
children: "Already on the waitlist"
|
|
3955
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
3956
|
+
className: "er-center",
|
|
3957
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
3958
|
+
className: "er-text er-text--muted",
|
|
3959
|
+
children: "You're already on the waitlist for this event."
|
|
3960
|
+
}), /* @__PURE__ */ jsx("a", {
|
|
3961
|
+
href: "/portal",
|
|
3962
|
+
className: "er-retry-btn",
|
|
3963
|
+
children: "View my bookings"
|
|
4057
3964
|
})]
|
|
4058
|
-
})
|
|
4059
|
-
}
|
|
3965
|
+
})]
|
|
3966
|
+
});
|
|
4060
3967
|
if (props.eligibility.isFree) return /* @__PURE__ */ jsxs("div", {
|
|
4061
3968
|
className: "rb-reg-stack er-stack",
|
|
4062
3969
|
children: [/* @__PURE__ */ jsx("h3", {
|
|
@@ -4077,7 +3984,7 @@ function PaymentBlockingPanel(props) {
|
|
|
4077
3984
|
})]
|
|
4078
3985
|
})]
|
|
4079
3986
|
});
|
|
4080
|
-
return props.eligibility.
|
|
3987
|
+
return props.eligibility.paymentOptions.length > 0 ? null : /* @__PURE__ */ jsx(IneligiblePaymentPanel, {
|
|
4081
3988
|
eligibility: props.eligibility,
|
|
4082
3989
|
email: props.email,
|
|
4083
3990
|
isAuthenticated: props.isAuthenticated,
|
|
@@ -4209,7 +4116,7 @@ function SlidingScaleAmountField(props) {
|
|
|
4209
4116
|
}
|
|
4210
4117
|
function TicketTypeQuantityRows(props) {
|
|
4211
4118
|
const totalSelectedQuantity = getTicketSelectionTotal(props.ticketSelections);
|
|
4212
|
-
const effectiveMaxTickets = props.
|
|
4119
|
+
const effectiveMaxTickets = props.maxTickets;
|
|
4213
4120
|
return /* @__PURE__ */ jsxs("div", {
|
|
4214
4121
|
className: "er-ticket-lines",
|
|
4215
4122
|
children: [
|
|
@@ -4219,16 +4126,14 @@ function TicketTypeQuantityRows(props) {
|
|
|
4219
4126
|
"aria-label": props.bookingUnit === "place" ? "Places" : "Tickets",
|
|
4220
4127
|
children: props.ticketTypes.map((ticketType) => {
|
|
4221
4128
|
const quantity = getTicketLineQuantity(props.ticketSelections, ticketType.pricingOptionId);
|
|
4222
|
-
const disabled = ticketType.availability
|
|
4129
|
+
const disabled = !canRequestTicketOption(ticketType.availability);
|
|
4223
4130
|
const availabilityLabel = getTicketTypeAvailabilityLabel(ticketType);
|
|
4224
4131
|
const ticketTypeRemainingLabel = formatTicketTypeRemaining(ticketType.availability.remainingPlaces);
|
|
4225
4132
|
const priceLabel = ticketType.priceAmount > 0 ? formatPrice(ticketType.priceAmount, props.currency) : "Free";
|
|
4226
4133
|
const maxAllowed = disabled ? 0 : getTicketTypeLineMax({
|
|
4227
4134
|
currentQuantity: quantity,
|
|
4228
4135
|
totalSelectedQuantity,
|
|
4229
|
-
maxTickets: props.maxTickets
|
|
4230
|
-
availableSpots: props.availableSpots,
|
|
4231
|
-
ticketTypeRemainingCapacity: ticketType.availability.remainingPlaces
|
|
4136
|
+
maxTickets: props.maxTickets
|
|
4232
4137
|
});
|
|
4233
4138
|
return /* @__PURE__ */ jsxs("div", {
|
|
4234
4139
|
className: `er-ticket-line${disabled ? " er-ticket-line--disabled" : ""}`,
|
|
@@ -4333,33 +4238,13 @@ function AttendanceModeTiles(props) {
|
|
|
4333
4238
|
})
|
|
4334
4239
|
});
|
|
4335
4240
|
}
|
|
4336
|
-
function getMaxAllowedTicketCount(input) {
|
|
4337
|
-
if (input.canJoinWaitlist) return input.maxTickets;
|
|
4338
|
-
if (!input.usesTicketTypes) return Math.min(input.maxTickets, input.availableSpots ?? input.maxTickets);
|
|
4339
|
-
if (!input.hasSelectedTicketType) return 1;
|
|
4340
|
-
return Math.max(1, Math.min(input.maxTickets, input.selectedTicketTypeRemainingCapacity ?? input.maxTickets, input.availableSpots ?? input.maxTickets));
|
|
4341
|
-
}
|
|
4342
4241
|
function resolveTicketSelectionPricing(event) {
|
|
4343
4242
|
return {
|
|
4344
4243
|
mode: event ? publicEventPricingStrategy(event.pricing) : void 0,
|
|
4345
4244
|
currency: event ? publicEventPricingCurrency(event.pricing) : null
|
|
4346
4245
|
};
|
|
4347
4246
|
}
|
|
4348
|
-
function
|
|
4349
|
-
return props.onContinue ? /* @__PURE__ */ jsx("button", {
|
|
4350
|
-
type: "button",
|
|
4351
|
-
className: "er-back-btn",
|
|
4352
|
-
onClick: props.onContinue,
|
|
4353
|
-
children: "Continue an existing booking"
|
|
4354
|
-
}) : null;
|
|
4355
|
-
}
|
|
4356
|
-
function getTicketSelectionCapacity(event, attendanceMode, checkoutRecovery) {
|
|
4357
|
-
if (checkoutRecovery) return {
|
|
4358
|
-
availableSpots: null,
|
|
4359
|
-
isSoldOut: false,
|
|
4360
|
-
canJoinWaitlist: false,
|
|
4361
|
-
eventAvailabilityLabel: null
|
|
4362
|
-
};
|
|
4247
|
+
function getTicketSelectionCapacity(event, attendanceMode) {
|
|
4363
4248
|
const source = event ? selectEventCapacitySource(event, attendanceMode) : null;
|
|
4364
4249
|
const availability = source ? getEventAvailability(source) : null;
|
|
4365
4250
|
const canJoinWaitlist = source ? canJoinEventWaitlist(source) : false;
|
|
@@ -4378,29 +4263,21 @@ function getTicketSelectionCapacity(event, attendanceMode, checkoutRecovery) {
|
|
|
4378
4263
|
*
|
|
4379
4264
|
* Can use either a full PublicEvent or just occurrence context (when on event page).
|
|
4380
4265
|
*/
|
|
4381
|
-
const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" }
|
|
4266
|
+
const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" } }) => {
|
|
4382
4267
|
const unit = bookingUnit.kind;
|
|
4383
4268
|
const deliveryMode = event?.deliveryMode ?? "in_person";
|
|
4384
4269
|
const attendanceModes = event?.attendanceModes ?? [];
|
|
4385
|
-
const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode
|
|
4270
|
+
const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode);
|
|
4386
4271
|
const { mode: eventPricingMode, currency: eventPricingCurrency } = resolveTicketSelectionPricing(event);
|
|
4387
|
-
const usesTicketTypes = eventPricingMode === "tiered"
|
|
4272
|
+
const usesTicketTypes = eventPricingMode === "tiered";
|
|
4388
4273
|
const visibleTicketTypes = usesTicketTypes ? visibleTicketTypesOverride ?? getVisibleTicketTypes({
|
|
4389
4274
|
event,
|
|
4390
4275
|
eligibility: null,
|
|
4391
4276
|
selectedAttendanceMode
|
|
4392
4277
|
}) : [];
|
|
4393
|
-
const implicitTicketType = usesTicketTypes ? getImplicitSingleAvailableTicketType(visibleTicketTypes) : null;
|
|
4394
4278
|
const noVisibleTicketTypes = usesTicketTypes && visibleTicketTypes.length === 0;
|
|
4395
|
-
const hasAvailableTicketTypes = usesTicketTypes && visibleTicketTypes.some((ticketType) => ticketType.availability
|
|
4396
|
-
const maxAllowed =
|
|
4397
|
-
canJoinWaitlist,
|
|
4398
|
-
usesTicketTypes,
|
|
4399
|
-
maxTickets,
|
|
4400
|
-
availableSpots,
|
|
4401
|
-
selectedTicketTypeRemainingCapacity: implicitTicketType?.availability.remainingPlaces ?? null,
|
|
4402
|
-
hasSelectedTicketType: implicitTicketType !== null
|
|
4403
|
-
});
|
|
4279
|
+
const hasAvailableTicketTypes = usesTicketTypes && visibleTicketTypes.some((ticketType) => canRequestTicketOption(ticketType.availability));
|
|
4280
|
+
const maxAllowed = maxTickets;
|
|
4404
4281
|
if (deliveryMode === "hybrid" && !selectedAttendanceMode) return /* @__PURE__ */ jsxs("div", {
|
|
4405
4282
|
className: "rb-reg-stack er-stack",
|
|
4406
4283
|
children: [
|
|
@@ -4419,20 +4296,6 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
|
|
|
4419
4296
|
})
|
|
4420
4297
|
]
|
|
4421
4298
|
});
|
|
4422
|
-
if (isSoldOut && !canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
|
|
4423
|
-
className: "rb-reg-stack er-stack",
|
|
4424
|
-
children: [
|
|
4425
|
-
/* @__PURE__ */ jsx("h3", {
|
|
4426
|
-
className: "er-title",
|
|
4427
|
-
children: "Sold out"
|
|
4428
|
-
}),
|
|
4429
|
-
/* @__PURE__ */ jsx("p", {
|
|
4430
|
-
className: "er-text er-text--muted",
|
|
4431
|
-
children: "Sorry you missed out! This event is fully booked."
|
|
4432
|
-
}),
|
|
4433
|
-
/* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })
|
|
4434
|
-
]
|
|
4435
|
-
});
|
|
4436
4299
|
if (!eventPricingCurrency) return /* @__PURE__ */ jsx("div", {
|
|
4437
4300
|
className: "rb-reg-stack er-stack",
|
|
4438
4301
|
children: /* @__PURE__ */ jsx("p", {
|
|
@@ -4499,14 +4362,14 @@ const TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, sel
|
|
|
4499
4362
|
})]
|
|
4500
4363
|
})
|
|
4501
4364
|
] }),
|
|
4502
|
-
|
|
4365
|
+
isSoldOut && !canJoinWaitlist && /* @__PURE__ */ jsx("p", {
|
|
4503
4366
|
className: "er-text er-text--muted",
|
|
4504
|
-
children: "This event is
|
|
4505
|
-
}),
|
|
4506
|
-
|
|
4367
|
+
children: "This event is fully booked."
|
|
4368
|
+
}),
|
|
4369
|
+
canJoinWaitlist && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("p", {
|
|
4507
4370
|
className: "er-text er-text--muted",
|
|
4508
|
-
children: "
|
|
4509
|
-
})
|
|
4371
|
+
children: "This event is currently full. Continue to join the waitlist if a place opens up."
|
|
4372
|
+
}) })
|
|
4510
4373
|
]
|
|
4511
4374
|
});
|
|
4512
4375
|
};
|
|
@@ -5101,7 +4964,7 @@ const PaymentSelectionStep = ({ event, occurrenceContext, ticketsCount, email, i
|
|
|
5101
4964
|
const occurrenceId = occurrenceContext?.id ?? (event?.registrationSubject.kind === "occurrence" ? event.registrationSubject.occurrenceId : "");
|
|
5102
4965
|
const selectedMethod = selectedSelection.method;
|
|
5103
4966
|
const totalPrice = directPaymentTotalCents;
|
|
5104
|
-
const canShowDirectPaymentOptions = Boolean(eligibility?.
|
|
4967
|
+
const canShowDirectPaymentOptions = Boolean(eligibility?.requiresPayment && eligibility.price);
|
|
5105
4968
|
const directPaymentOptions = eligibility && canShowDirectPaymentOptions ? buildEventRegistrationPaymentOptionsViewModel({
|
|
5106
4969
|
eventTitle: event?.title ?? "Event",
|
|
5107
4970
|
approvedPaymentOptions: eligibility.paymentOptions,
|
|
@@ -5164,7 +5027,7 @@ const PaymentSelectionStep = ({ event, occurrenceContext, ticketsCount, email, i
|
|
|
5164
5027
|
onRequestLogin
|
|
5165
5028
|
});
|
|
5166
5029
|
if (eligibilityLoading || eligibilityError || !eligibility) return blockingPanel;
|
|
5167
|
-
if (eligibility.isFree ||
|
|
5030
|
+
if (eligibility.isFree || paymentStepStatus !== "ready") return blockingPanel;
|
|
5168
5031
|
const isMultiTicket = areEntitlementsDisabledForTicketCount(ticketsCount);
|
|
5169
5032
|
return /* @__PURE__ */ jsxs("div", {
|
|
5170
5033
|
className: "rb-reg-stack er-stack",
|
|
@@ -5398,6 +5261,7 @@ function EventRegistrationWizardContent(props) {
|
|
|
5398
5261
|
case "redirecting":
|
|
5399
5262
|
case "verifying-payment":
|
|
5400
5263
|
case "verifying-timeout":
|
|
5264
|
+
case "payment-status":
|
|
5401
5265
|
case "payment-failed": return null;
|
|
5402
5266
|
case "select-event": return /* @__PURE__ */ jsx(EventSelectionStep, {
|
|
5403
5267
|
events: wizard.scopedEvents,
|
|
@@ -5413,8 +5277,6 @@ function EventRegistrationWizardContent(props) {
|
|
|
5413
5277
|
onBookForSomeoneElse: wizard.handleBookForSomeoneElse
|
|
5414
5278
|
}), /* @__PURE__ */ jsx(TicketSelectionStep, {
|
|
5415
5279
|
event: wizard.selectedEvent,
|
|
5416
|
-
checkoutRecovery: wizard.checkoutRecovery,
|
|
5417
|
-
onCheckoutRecovery: canRecoverEventCheckout(wizard.selectedEvent) ? wizard.startCheckoutRecovery : void 0,
|
|
5418
5280
|
occurrenceContext: wizard.occurrenceContext,
|
|
5419
5281
|
selectedAttendanceMode: wizard.selectedAttendanceMode,
|
|
5420
5282
|
onAttendanceModeChange: wizard.setSelectedAttendanceMode,
|
|
@@ -5469,6 +5331,81 @@ const PaymentFailedStep = ({ onRetry }) => {
|
|
|
5469
5331
|
});
|
|
5470
5332
|
};
|
|
5471
5333
|
//#endregion
|
|
5334
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.tsx
|
|
5335
|
+
function presentation(state) {
|
|
5336
|
+
switch (state.kind) {
|
|
5337
|
+
case "ready": return {
|
|
5338
|
+
title: "We haven’t confirmed your payment yet",
|
|
5339
|
+
message: "We’ve saved your booking details, but we haven’t been able to confirm that your payment was successful. Please don’t make another payment. Select Check payment status to get the latest update.",
|
|
5340
|
+
action: { label: "Check payment status" }
|
|
5341
|
+
};
|
|
5342
|
+
case "checking": return {
|
|
5343
|
+
title: "We haven’t confirmed your payment yet",
|
|
5344
|
+
message: "We’ve saved your booking details, but we haven’t been able to confirm that your payment was successful. Please don’t make another payment.",
|
|
5345
|
+
action: {
|
|
5346
|
+
label: "Checking payment…",
|
|
5347
|
+
disabled: true
|
|
5348
|
+
}
|
|
5349
|
+
};
|
|
5350
|
+
case "processing": return {
|
|
5351
|
+
title: "Your payment is still being processed",
|
|
5352
|
+
message: "Please don’t make another payment. You can check its status again in a moment.",
|
|
5353
|
+
action: { label: "Check payment status" }
|
|
5354
|
+
};
|
|
5355
|
+
case "paymentAvailable": return {
|
|
5356
|
+
title: "Your payment hasn’t been completed",
|
|
5357
|
+
message: "Your booking details are still saved. Continue to payment to finish your booking.",
|
|
5358
|
+
action: { label: "Continue to payment" }
|
|
5359
|
+
};
|
|
5360
|
+
case "retryAvailable": return {
|
|
5361
|
+
title: "Continue your booking",
|
|
5362
|
+
message: "You can return to payment. We’ll check your booking, any existing payment and availability before starting another checkout.",
|
|
5363
|
+
action: { label: "Return to payment" }
|
|
5364
|
+
};
|
|
5365
|
+
case "temporarilyUnavailable": return {
|
|
5366
|
+
title: "We couldn’t check your payment",
|
|
5367
|
+
message: "Please don’t make another payment yet. Try checking again in a moment.",
|
|
5368
|
+
action: { label: "Check payment status" }
|
|
5369
|
+
};
|
|
5370
|
+
case "assistanceRequired": return {
|
|
5371
|
+
title: "We still can’t confirm your payment",
|
|
5372
|
+
message: "Please don’t make another payment. Contact the organiser so they can check your booking.",
|
|
5373
|
+
action: { label: "Return to booking" }
|
|
5374
|
+
};
|
|
5375
|
+
}
|
|
5376
|
+
}
|
|
5377
|
+
function PaymentStatusStep(props) {
|
|
5378
|
+
const view = presentation(props.state);
|
|
5379
|
+
const onClick = props.state.kind === "paymentAvailable" ? props.onContinuePayment : props.state.kind === "retryAvailable" ? props.onReturnToPayment : props.state.kind === "assistanceRequired" ? props.onReturnToBooking : props.onCheck;
|
|
5380
|
+
return /* @__PURE__ */ jsx(TerminalPanel, {
|
|
5381
|
+
tone: "warning",
|
|
5382
|
+
className: "er-center",
|
|
5383
|
+
titleClassName: "er-title--lg er-message",
|
|
5384
|
+
icon: /* @__PURE__ */ jsx(StateIcon, {
|
|
5385
|
+
variant: "warning",
|
|
5386
|
+
children: /* @__PURE__ */ jsx(ClockIcon, {})
|
|
5387
|
+
}),
|
|
5388
|
+
title: view.title,
|
|
5389
|
+
body: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
|
|
5390
|
+
className: "er-text--muted er-message",
|
|
5391
|
+
children: view.message
|
|
5392
|
+
}), /* @__PURE__ */ jsx("span", {
|
|
5393
|
+
className: "rb-sr-only",
|
|
5394
|
+
"aria-live": "polite",
|
|
5395
|
+
"aria-atomic": "true",
|
|
5396
|
+
children: props.state.kind === "checking" ? "Checking payment…" : view.title
|
|
5397
|
+
})] }),
|
|
5398
|
+
actionsClassName: "er-button-group",
|
|
5399
|
+
actions: view.action ? /* @__PURE__ */ jsx("button", {
|
|
5400
|
+
type: "button",
|
|
5401
|
+
onClick,
|
|
5402
|
+
disabled: view.action.disabled,
|
|
5403
|
+
className: "er-btn er-btn--primary",
|
|
5404
|
+
children: /* @__PURE__ */ jsx("span", { children: view.action.label })
|
|
5405
|
+
}) : void 0
|
|
5406
|
+
});
|
|
5407
|
+
}
|
|
5408
|
+
//#endregion
|
|
5472
5409
|
//#region ../blocks/src/system/runtime/nodes/event-registration/StepIndicator.tsx
|
|
5473
5410
|
/**
|
|
5474
5411
|
* Step indicator component for the event registration wizard.
|
|
@@ -5586,7 +5523,7 @@ const VerifyingTimeoutStep = ({ onCheckAgain, supportEmail, title = "We’re che
|
|
|
5586
5523
|
title,
|
|
5587
5524
|
body: /* @__PURE__ */ jsx("p", {
|
|
5588
5525
|
className: "er-text--muted er-message",
|
|
5589
|
-
children: message
|
|
5526
|
+
children: onCheckAgain ? message : "We still can’t confirm your payment. Please don’t make another payment. Contact the organiser so they can check your booking."
|
|
5590
5527
|
}),
|
|
5591
5528
|
actionsClassName: "er-button-group",
|
|
5592
5529
|
actions: onCheckAgain ? /* @__PURE__ */ jsx("button", {
|
|
@@ -5594,11 +5531,7 @@ const VerifyingTimeoutStep = ({ onCheckAgain, supportEmail, title = "We’re che
|
|
|
5594
5531
|
onClick: onCheckAgain,
|
|
5595
5532
|
className: "er-btn er-btn--primary",
|
|
5596
5533
|
children: "Check payment status"
|
|
5597
|
-
}) :
|
|
5598
|
-
href: "/portal",
|
|
5599
|
-
className: "er-btn er-btn--primary",
|
|
5600
|
-
children: "Check payment status"
|
|
5601
|
-
}),
|
|
5534
|
+
}) : void 0,
|
|
5602
5535
|
secondaryBody: supportEmail ? /* @__PURE__ */ jsxs("p", {
|
|
5603
5536
|
className: "er-text--sm er-text--muted er-message",
|
|
5604
5537
|
children: [
|
|
@@ -5699,6 +5632,13 @@ function EventRegistrationTerminalState(props) {
|
|
|
5699
5632
|
message: wizard.verification.status === "timeout" ? void 0 : wizard.errorMessage,
|
|
5700
5633
|
supportEmail: props.supportEmail
|
|
5701
5634
|
});
|
|
5635
|
+
case "payment-status": return wizard.paymentStatusRecovery ? /* @__PURE__ */ jsx(PaymentStatusStep, {
|
|
5636
|
+
state: wizard.paymentStatusRecovery,
|
|
5637
|
+
onCheck: wizard.handleCheckPaymentStatus,
|
|
5638
|
+
onContinuePayment: wizard.handleContinueExistingPayment,
|
|
5639
|
+
onReturnToPayment: wizard.handleReturnToPayment,
|
|
5640
|
+
onReturnToBooking: wizard.handleReturnToBooking
|
|
5641
|
+
}) : null;
|
|
5702
5642
|
case "success": return wizard.registrationResult ? /* @__PURE__ */ jsx(SuccessStep, {
|
|
5703
5643
|
title: wizard.registrationResult.title,
|
|
5704
5644
|
variant: wizard.registrationResult.variant,
|
|
@@ -5707,7 +5647,7 @@ function EventRegistrationTerminalState(props) {
|
|
|
5707
5647
|
case "error": return /* @__PURE__ */ jsx(ErrorStep, {
|
|
5708
5648
|
message: wizard.errorMessage,
|
|
5709
5649
|
action: wizard.errorAction,
|
|
5710
|
-
canJoinWaitlist: wizard.eligibility?.
|
|
5650
|
+
canJoinWaitlist: wizard.eligibility?.availability.kind === "waitlist" && wizard.eligibility.registration.kind !== "pending_payment",
|
|
5711
5651
|
onRetry: wizard.handleRetry
|
|
5712
5652
|
});
|
|
5713
5653
|
case "select-event":
|
|
@@ -5901,6 +5841,7 @@ function getWizardStepLabel(input) {
|
|
|
5901
5841
|
case "redirecting":
|
|
5902
5842
|
case "verifying-payment":
|
|
5903
5843
|
case "verifying-timeout":
|
|
5844
|
+
case "payment-status":
|
|
5904
5845
|
case "payment-failed": return "";
|
|
5905
5846
|
}
|
|
5906
5847
|
}
|