@riverbankcms/sdk 0.142.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-Dk6Dt11f.mjs → PreviewEditorSidebar-DROGfMKi.mjs} +4 -4
- package/dist/{PreviewEditorUI-D6EQTsCA.mjs → PreviewEditorUI-BaRjhFu-.mjs} +3 -3
- package/dist/{PreviewQueryProvider-CC-EPkyQ.mjs → PreviewQueryProvider-BCYICImX.mjs} +1 -1
- package/dist/{SdkPreviewModeRuntime-DH1n4ytY.mjs → SdkPreviewModeRuntime-OIABYLES.mjs} +5 -5
- package/dist/{SiteChromeCustomizeContext-DunIzY0K.mjs → SiteChromeCustomizeContext-ohjTvZbc.mjs} +491 -525
- package/dist/_dts/api/src/endpoints.d.ts +7 -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/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/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/db/src/generated/supabase/database.types.d.ts +3113 -3077
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/client/{BookingConsentAgreement-CnJeq3_r.mjs → BookingConsentAgreement-BoCtvzzu.mjs} +2 -2
- package/dist/client/{DiscountCodeDisclosure-BINEO6J9.mjs → DiscountCodeDisclosure-B5S30nZk.mjs} +1 -1
- package/dist/client/{EventCombined.client-srxNQ6sZ.mjs → EventCombined.client-CeZ2-zSt.mjs} +5 -5
- package/dist/client/{EventListing.client-DbyVyGkX.mjs → EventListing.client-DJN3j8B3.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-B-wpijzL.mjs → LeafletStaticMap-RjtGzDQT.mjs} +1 -1
- package/dist/client/{accordion-B-iUXU7n.mjs → accordion-DOmnDoyg.mjs} +1 -1
- package/dist/client/{bookingForm-BXYPke5q.mjs → bookingForm-C0vk7pgS.mjs} +5 -5
- package/dist/client/bookings.mjs +449 -525
- package/dist/client/{carousel-Cr4aj63H.mjs → carousel-BZJ7pno3.mjs} +1 -1
- package/dist/client/{cart-DibP9WWa.mjs → cart-CaeVAHJl.mjs} +3 -3
- package/dist/client/{checkout-CrSBVnL8.mjs → checkout-7wmoNDtG.mjs} +3 -3
- package/dist/client/client.mjs +518 -540
- package/dist/client/{context-Ces-AgdR.mjs → context-BOimxE3U.mjs} +12 -1
- package/dist/client/{dates-BXyNeNhB.mjs → dates-BnzVksi4.mjs} +2 -2
- package/dist/client/{eventCalendar-HwpPeqrH.mjs → eventCalendar-l-fpaslC.mjs} +7 -7
- package/dist/client/{eventCombined-BpFUkuEI.mjs → eventCombined-DGGvssK6.mjs} +3 -3
- package/dist/client/{eventDetails-DK_agiWy.mjs → eventDetails-DRiCm_hL.mjs} +4 -4
- package/dist/client/{eventListing-DhzHqP1c.mjs → eventListing-dph8loYX.mjs} +3 -3
- package/dist/client/{eventRegistration-BdQ_Dn2d.mjs → eventRegistration-ClBohmbY.mjs} +472 -530
- package/dist/client/{form-B1frcuzy.mjs → form-BLVVAnd3.mjs} +2 -2
- package/dist/client/{headerSection-CT5z460s.mjs → headerSection-DHy4C8Ix.mjs} +2 -2
- package/dist/client/hooks.mjs +12 -0
- package/dist/client/{locationMap-CIQXB9i2.mjs → locationMap-6HuS28ck.mjs} +2 -2
- package/dist/client/{newsletterForm-BYNYZSes.mjs → newsletterForm-xOdcOhZP.mjs} +2 -2
- package/dist/client/{pricing-CbTlAsmt.mjs → pricing-ChinRYFt.mjs} +1 -1
- package/dist/client/{productDetail-CR7Z3yjS.mjs → productDetail-0chA5gbK.mjs} +3 -3
- package/dist/client/{productList-DXj00vzR.mjs → productList-OoINA0h1.mjs} +3 -3
- package/dist/client/{propsDecoder-DiLiBdek.mjs → propsDecoder-CIZ-hbIG.mjs} +14 -1
- package/dist/client/rendering/client.mjs +506 -539
- package/dist/client/rendering/islands.mjs +17 -17
- package/dist/client/rendering.mjs +517 -539
- package/dist/client/{scrollToBlock-CrcbBf0h.mjs → scrollToBlock-BPZl0gPZ.mjs} +1 -1
- package/dist/client/{shop-DgqiB_1b.mjs → shop-CLJFqNIq.mjs} +6 -6
- package/dist/client/{shop-commerce-D_J781in.mjs → shop-commerce-PpANg5wB.mjs} +5 -5
- package/dist/client/{shop-commerce-store-PGUbDwqe.mjs → shop-commerce-store-TA_Kz2ku.mjs} +1 -1
- package/dist/client/{shopShared-C_Bb2zwG.mjs → shopShared-DzcFcA5g.mjs} +3 -3
- package/dist/client/{useEventFilters-CM17Xpr1.mjs → useEventFilters-CFU21QZo.mjs} +5 -5
- package/dist/preview-next/before-render.mjs +11 -0
- package/dist/preview-next/client/runtime.mjs +4 -4
- package/dist/preview-next/keepAlive.mjs +11 -0
- package/dist/preview-next/middleware.mjs +11 -0
- package/dist/{previewAuthStore-oVttoRDO.mjs → previewAuthStore-JA6-I_sL.mjs} +11 -0
- package/dist/{sdk-runtime-DhmuRhIX.mjs → sdk-runtime-CDKl0Fr7.mjs} +2 -2
- package/dist/{separator-C3hlg9LH.mjs → separator-BTp96X32.mjs} +1 -1
- package/dist/server/components.mjs +12 -2
- package/dist/server/config-validation.mjs +12 -0
- package/dist/server/config.mjs +12 -0
- package/dist/server/data.mjs +12 -0
- package/dist/server/index.mjs +12 -1
- package/dist/server/next.mjs +13 -3
- package/dist/server/page-converter.mjs +1 -0
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +12 -0
- package/dist/server/rendering.mjs +12 -2
- package/dist/server/routing.mjs +12 -0
- package/dist/server/server.mjs +13 -1
- 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
package/dist/client/bookings.mjs
CHANGED
|
@@ -8360,6 +8360,10 @@ const EVENTS = {
|
|
|
8360
8360
|
method: "POST",
|
|
8361
8361
|
authScope: "portal"
|
|
8362
8362
|
},
|
|
8363
|
+
registrationNextStep: {
|
|
8364
|
+
path: "/public/sites/{siteId}/events/registration-next-step",
|
|
8365
|
+
method: "POST"
|
|
8366
|
+
},
|
|
8363
8367
|
registrationStatus: {
|
|
8364
8368
|
path: "/public/sites/{siteId}/events/registration-status",
|
|
8365
8369
|
method: "GET"
|
|
@@ -8964,6 +8968,13 @@ function createBlockApi(config) {
|
|
|
8964
8968
|
body: data
|
|
8965
8969
|
});
|
|
8966
8970
|
},
|
|
8971
|
+
async checkRegistrationNextStep(data) {
|
|
8972
|
+
const path = buildPath(EVENTS.registrationNextStep.path, { siteId: requireSiteId() });
|
|
8973
|
+
return request(EVENTS.registrationNextStep, {
|
|
8974
|
+
path,
|
|
8975
|
+
body: data
|
|
8976
|
+
});
|
|
8977
|
+
},
|
|
8967
8978
|
async getEventRegistrationStatus(params) {
|
|
8968
8979
|
const sid = requireSiteId();
|
|
8969
8980
|
const path = buildPath(EVENTS.registrationStatus.path, { siteId: sid });
|
|
@@ -14911,188 +14922,15 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
|
|
|
14911
14922
|
});
|
|
14912
14923
|
};
|
|
14913
14924
|
//#endregion
|
|
14914
|
-
//#region ../blocks/src/system/runtime/nodes/events/domain/capacity.ts
|
|
14915
|
-
/**
|
|
14916
|
-
* Compute remaining spots for an event from `availableSpots` with a fallback
|
|
14917
|
-
* to `capacity - registeredCount`. Returns `{ available: null, isFull: false }`
|
|
14918
|
-
* for uncapped events so call sites can render no capacity indicator at all.
|
|
14919
|
-
*
|
|
14920
|
-
* The single source of truth for capacity math across event cards, agenda
|
|
14921
|
-
* rows, and timetable cells — keep wording variations in the call sites.
|
|
14922
|
-
*/
|
|
14923
|
-
function getEventAvailability(event) {
|
|
14924
|
-
if (event.capacity == null) return {
|
|
14925
|
-
available: null,
|
|
14926
|
-
isFull: false
|
|
14927
|
-
};
|
|
14928
|
-
const available = event.availableSpots ?? event.capacity - event.registeredCount;
|
|
14929
|
-
if (available <= 0) return {
|
|
14930
|
-
available: 0,
|
|
14931
|
-
isFull: true
|
|
14932
|
-
};
|
|
14933
|
-
return {
|
|
14934
|
-
available,
|
|
14935
|
-
isFull: false
|
|
14936
|
-
};
|
|
14937
|
-
}
|
|
14938
|
-
/**
|
|
14939
|
-
* Pick the capacity row a booking decision should read: the selected
|
|
14940
|
-
* attendance mode's availability when the visitor has chosen one and the
|
|
14941
|
-
* event publishes it, otherwise the event-level aggregate.
|
|
14942
|
-
*
|
|
14943
|
-
* The mode row is used wholesale. A mode with `capacity: null` on a capped
|
|
14944
|
-
* event is uncapped *by design*: the registration write path applies the
|
|
14945
|
-
* same rule via `getEffectiveOccurrenceCapacityForAttendanceMode`, so falling
|
|
14946
|
-
* back to the event's `availableSpots` here would block bookings the server
|
|
14947
|
-
* accepts. (Waitlist claims are still occurrence-scoped; see issue 1377.)
|
|
14948
|
-
*/
|
|
14949
|
-
function selectEventCapacitySource(event, attendanceMode) {
|
|
14950
|
-
if (!attendanceMode) return event;
|
|
14951
|
-
return (event.attendanceModes ?? []).find((mode) => mode.mode === attendanceMode) ?? event;
|
|
14952
|
-
}
|
|
14953
|
-
/**
|
|
14954
|
-
* Whether the visitor's next step is the waitlist: the source is full *and*
|
|
14955
|
-
* a waitlist is open. The one place this is decided — cards, rows, the
|
|
14956
|
-
* wizard's steps and its action bar all route through here so they agree,
|
|
14957
|
-
* including for producers that omit `availableSpots` and rely on the
|
|
14958
|
-
* `capacity - registeredCount` fallback.
|
|
14959
|
-
*/
|
|
14960
|
-
function canJoinEventWaitlist(event, options) {
|
|
14961
|
-
const source = selectEventCapacitySource(event, options?.attendanceMode);
|
|
14962
|
-
return getEventAvailability(source).isFull && source.waitlistEnabled === true;
|
|
14963
|
-
}
|
|
14964
|
-
//#endregion
|
|
14965
|
-
//#region ../blocks/src/system/runtime/nodes/events/domain/destination.ts
|
|
14966
|
-
function isRecord$1(value) {
|
|
14967
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14968
|
-
}
|
|
14969
|
-
function isRuntimeEventDestination(value) {
|
|
14970
|
-
if (!isRecord$1(value) || typeof value.kind !== "string") return false;
|
|
14971
|
-
if (value.kind === "native") return (value.mode === "cms-managed" || value.mode === "system-managed") && typeof value.path === "string";
|
|
14972
|
-
return value.kind === "external" && typeof value.url === "string" && typeof value.label === "string";
|
|
14973
|
-
}
|
|
14974
|
-
function resolveRuntimeEventDestination(event) {
|
|
14975
|
-
if (isRuntimeEventDestination(event.destination)) return event.destination;
|
|
14976
|
-
return {
|
|
14977
|
-
kind: "native",
|
|
14978
|
-
mode: event.eventDestinationMode === "system-managed" ? "system-managed" : "cms-managed",
|
|
14979
|
-
path: typeof event.path === "string" ? event.path : ""
|
|
14980
|
-
};
|
|
14981
|
-
}
|
|
14982
|
-
//#endregion
|
|
14983
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.ts
|
|
14984
|
-
/** Recovery may select held places; checkout still owns admission and payment validation. */
|
|
14985
|
-
function checkoutRecoveryOptionAvailability(availability) {
|
|
14986
|
-
if (availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable") return {
|
|
14987
|
-
kind: "available",
|
|
14988
|
-
remainingPlaces: null
|
|
14989
|
-
};
|
|
14990
|
-
return availability;
|
|
14991
|
-
}
|
|
14992
|
-
/**
|
|
14993
|
-
* A form-only projection for the explicit existing-checkout path. It permits
|
|
14994
|
-
* collecting the original selection without claiming a new place is available.
|
|
14995
|
-
* The public checkout service identifies the customer and remains the admission
|
|
14996
|
-
* authority; no reservation/customer data is exposed through this projection.
|
|
14997
|
-
*/
|
|
14998
|
-
function getCheckoutRecoveryFormEligibility(eligibility) {
|
|
14999
|
-
if (!eligibility || eligibility.registration.kind !== "none" && eligibility.registration.kind !== "pending_payment" || eligibility.availability.kind === "unavailable" && eligibility.availability.reason !== "full" && eligibility.availability.reason !== "selectionRequired") return eligibility;
|
|
15000
|
-
const amountCents = eligibility.price ?? 0;
|
|
15001
|
-
if (amountCents <= 0 || !eligibility.currency || eligibility.availability.kind === "unavailable" && eligibility.availability.reason === "selectionRequired") return eligibility.registration.kind === "pending_payment" ? {
|
|
15002
|
-
...eligibility,
|
|
15003
|
-
registration: { kind: "none" },
|
|
15004
|
-
ticketTypes: eligibility.ticketTypes.map((option) => ({
|
|
15005
|
-
...option,
|
|
15006
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
15007
|
-
}))
|
|
15008
|
-
} : eligibility;
|
|
15009
|
-
const currency = eligibility.currency;
|
|
15010
|
-
const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
|
|
15011
|
-
switch (option.kind) {
|
|
15012
|
-
case "upfront": return {
|
|
15013
|
-
kind: "payInFull",
|
|
15014
|
-
amountCents,
|
|
15015
|
-
currency
|
|
15016
|
-
};
|
|
15017
|
-
case "deferred_manual": return {
|
|
15018
|
-
kind: "deferredManual",
|
|
15019
|
-
amountCents,
|
|
15020
|
-
currency
|
|
15021
|
-
};
|
|
15022
|
-
case "instalment_plan": return {
|
|
15023
|
-
kind: "instalmentPlan",
|
|
15024
|
-
amountCents,
|
|
15025
|
-
currency
|
|
15026
|
-
};
|
|
15027
|
-
case "flexible_balance": return {
|
|
15028
|
-
kind: "flexibleBalance",
|
|
15029
|
-
amountCents,
|
|
15030
|
-
currency
|
|
15031
|
-
};
|
|
15032
|
-
}
|
|
15033
|
-
});
|
|
15034
|
-
return {
|
|
15035
|
-
...eligibility,
|
|
15036
|
-
registration: { kind: "none" },
|
|
15037
|
-
availability: {
|
|
15038
|
-
kind: "available",
|
|
15039
|
-
remainingPlaces: null,
|
|
15040
|
-
waitlistEnabled: eligibility.waitlistEnabled
|
|
15041
|
-
},
|
|
15042
|
-
eligible: paymentOptions.length > 0,
|
|
15043
|
-
isFull: false,
|
|
15044
|
-
canJoinWaitlist: false,
|
|
15045
|
-
isFree: false,
|
|
15046
|
-
requiresPayment: true,
|
|
15047
|
-
canPayDirectly: paymentOptions.length > 0,
|
|
15048
|
-
paymentOptions,
|
|
15049
|
-
eligiblePasses: [],
|
|
15050
|
-
eligibleMemberships: [],
|
|
15051
|
-
ticketTypes: eligibility.ticketTypes.map((option) => ({
|
|
15052
|
-
...option,
|
|
15053
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
15054
|
-
}))
|
|
15055
|
-
};
|
|
15056
|
-
}
|
|
15057
|
-
function canJoinWaitlistOutsideRecovery(event, attendanceMode, checkoutRecovery) {
|
|
15058
|
-
return !checkoutRecovery && event !== null && canJoinEventWaitlist(event, { attendanceMode });
|
|
15059
|
-
}
|
|
15060
|
-
//#endregion
|
|
15061
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
|
|
15062
|
-
/** Recovery belongs to the selected booking subject; changing events resets its scope. */
|
|
15063
|
-
function useCheckoutRecovery(event, setStep) {
|
|
15064
|
-
const [recoveryEventId, setRecoveryEventId] = useState(null);
|
|
15065
|
-
return {
|
|
15066
|
-
checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
|
|
15067
|
-
startCheckoutRecovery: useCallback(() => {
|
|
15068
|
-
if (!event) return;
|
|
15069
|
-
setRecoveryEventId(event.selectionId);
|
|
15070
|
-
setStep("select-tickets");
|
|
15071
|
-
}, [event, setStep])
|
|
15072
|
-
};
|
|
15073
|
-
}
|
|
15074
|
-
/** Authenticated pending bookings enter the same form-only recovery path as guests. */
|
|
15075
|
-
function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
|
|
15076
|
-
const registrationKind = eligibility?.registration.kind;
|
|
15077
|
-
useEffect(() => {
|
|
15078
|
-
if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
|
|
15079
|
-
}, [
|
|
15080
|
-
registrationKind,
|
|
15081
|
-
step,
|
|
15082
|
-
checkoutRecovery,
|
|
15083
|
-
startCheckoutRecovery
|
|
15084
|
-
]);
|
|
15085
|
-
return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
|
|
15086
|
-
}
|
|
15087
|
-
//#endregion
|
|
15088
14925
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
|
|
15089
14926
|
function resolveRegistrationRecoveryAction(step, action) {
|
|
15090
14927
|
if (step === "payment-failed") return "payment-options";
|
|
15091
|
-
if (step === "
|
|
14928
|
+
if (step === "payment-status") return "none";
|
|
14929
|
+
if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "none";
|
|
15092
14930
|
return action;
|
|
15093
14931
|
}
|
|
15094
14932
|
function canRecoverToWaitlist(eligibility) {
|
|
15095
|
-
return
|
|
14933
|
+
return eligibility?.availability.kind === "waitlist" && eligibility.registration.kind !== "pending_payment";
|
|
15096
14934
|
}
|
|
15097
14935
|
function shouldRefreshAfterRegistrationError(step, action, enabled) {
|
|
15098
14936
|
return enabled || step === "error" && action === "places";
|
|
@@ -15109,19 +14947,19 @@ function resetRegistrationAfterExpiry(input) {
|
|
|
15109
14947
|
input.setErrorMessage("");
|
|
15110
14948
|
input.setPendingRegistrationReference(null);
|
|
15111
14949
|
}
|
|
15112
|
-
/**
|
|
14950
|
+
/** Retry the retained submission in place; explicit payment uncertainty stays status-only. */
|
|
15113
14951
|
function recoverRegistrationError(action, handlers) {
|
|
15114
14952
|
switch (action) {
|
|
15115
14953
|
case "none": return;
|
|
15116
14954
|
case "portal":
|
|
15117
|
-
case "payment-status":
|
|
15118
14955
|
window.location.assign("/portal");
|
|
15119
14956
|
return;
|
|
15120
14957
|
case "event":
|
|
15121
14958
|
window.location.assign(window.location.pathname);
|
|
15122
14959
|
return;
|
|
15123
14960
|
case "retry":
|
|
15124
|
-
|
|
14961
|
+
handlers.clearError();
|
|
14962
|
+
handlers.setStep("select-payment");
|
|
15125
14963
|
return;
|
|
15126
14964
|
case "details":
|
|
15127
14965
|
handlers.clearError();
|
|
@@ -15159,13 +14997,43 @@ function validateFormData(formData, requiresConsent = false) {
|
|
|
15159
14997
|
return errors;
|
|
15160
14998
|
}
|
|
15161
14999
|
//#endregion
|
|
15000
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.ts
|
|
15001
|
+
/** Ticket selection requests a quote; only the server admits a booking. */
|
|
15002
|
+
function canRequestTicketOption(availability) {
|
|
15003
|
+
return availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable";
|
|
15004
|
+
}
|
|
15005
|
+
function normalizeTicketSelectionLines(lines) {
|
|
15006
|
+
const quantitiesByTicketType = /* @__PURE__ */ new Map();
|
|
15007
|
+
for (const line of lines) {
|
|
15008
|
+
const quantity = Math.floor(line.quantity);
|
|
15009
|
+
if (quantity <= 0) continue;
|
|
15010
|
+
const key = line.pricingOptionId ?? null;
|
|
15011
|
+
quantitiesByTicketType.set(key, (quantitiesByTicketType.get(key) ?? 0) + quantity);
|
|
15012
|
+
}
|
|
15013
|
+
return [...quantitiesByTicketType.entries()].map(([pricingOptionId, quantity]) => ({
|
|
15014
|
+
pricingOptionId,
|
|
15015
|
+
quantity
|
|
15016
|
+
}));
|
|
15017
|
+
}
|
|
15018
|
+
function getTicketSelectionTotal(lines) {
|
|
15019
|
+
return normalizeTicketSelectionLines(lines).reduce((total, line) => total + line.quantity, 0);
|
|
15020
|
+
}
|
|
15021
|
+
function getSingleSelectedPricingOptionId(lines) {
|
|
15022
|
+
const normalized = normalizeTicketSelectionLines(lines);
|
|
15023
|
+
return normalized.length === 1 ? normalized[0]?.pricingOptionId ?? null : null;
|
|
15024
|
+
}
|
|
15025
|
+
function hasValidPricingOptionSelection(input) {
|
|
15026
|
+
if (!input.selectionRequired) return true;
|
|
15027
|
+
if (input.lines.length === 0) return false;
|
|
15028
|
+
const availableOptionIds = new Set(input.visibleOptions.filter((option) => canRequestTicketOption(option.availability)).map((option) => option.pricingOptionId));
|
|
15029
|
+
return input.lines.every((line) => line.pricingOptionId !== null && availableOptionIds.has(line.pricingOptionId));
|
|
15030
|
+
}
|
|
15031
|
+
//#endregion
|
|
15162
15032
|
//#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
|
|
15163
15033
|
function getPortalSubjectEmail(profile) {
|
|
15164
15034
|
return profile?.email ?? null;
|
|
15165
15035
|
}
|
|
15166
15036
|
function transformRegistrationOptionsResponse(response) {
|
|
15167
|
-
const canJoinWaitlist = response.availability.kind === "waitlist";
|
|
15168
|
-
const isFull = response.availability.remainingPlaces === 0 || response.availability.kind === "unavailable" && response.availability.reason === "full";
|
|
15169
15037
|
const eligiblePasses = response.entitlements.passes.map((pass) => ({
|
|
15170
15038
|
id: pass.customerPassId,
|
|
15171
15039
|
passName: pass.passName,
|
|
@@ -15178,7 +15046,6 @@ function transformRegistrationOptionsResponse(response) {
|
|
|
15178
15046
|
const eventAcceptsPasses = response.entitlements.requiresLoginForPasses || eligiblePasses.length > 0 || response.entitlements.availableForPurchase.passes.length > 0;
|
|
15179
15047
|
const eventAcceptsMemberships = response.entitlements.requiresLoginForMemberships || eligibleMemberships.length > 0 || response.entitlements.availableForPurchase.memberships.length > 0;
|
|
15180
15048
|
const monetaryPaymentAvailable = hasMonetaryPaymentOption(response);
|
|
15181
|
-
const registrationAvailable = response.availability.kind === "available" || response.availability.kind === "waitlist";
|
|
15182
15049
|
return {
|
|
15183
15050
|
availability: response.availability,
|
|
15184
15051
|
registration: response.registration,
|
|
@@ -15193,7 +15060,6 @@ function transformRegistrationOptionsResponse(response) {
|
|
|
15193
15060
|
},
|
|
15194
15061
|
transactions: []
|
|
15195
15062
|
} : null,
|
|
15196
|
-
eligible: response.registration.kind === "none" && registrationAvailable,
|
|
15197
15063
|
requiresPayment: monetaryPaymentAvailable,
|
|
15198
15064
|
pricingStrategy: response.pricing.strategy,
|
|
15199
15065
|
paymentTerms: response.pricing.paymentTerms,
|
|
@@ -15208,16 +15074,12 @@ function transformRegistrationOptionsResponse(response) {
|
|
|
15208
15074
|
currency: response.pricing.currency
|
|
15209
15075
|
})),
|
|
15210
15076
|
ticketTypes: response.pricing.options,
|
|
15211
|
-
isFull,
|
|
15212
|
-
waitlistEnabled: response.availability.waitlistEnabled,
|
|
15213
|
-
canJoinWaitlist,
|
|
15214
15077
|
price: response.pricing.subtotalCents,
|
|
15215
15078
|
currency: response.pricing.currency,
|
|
15216
15079
|
requiresAuthForPasses: response.entitlements.requiresLoginForPasses,
|
|
15217
15080
|
requiresAuthForMemberships: response.entitlements.requiresLoginForMemberships,
|
|
15218
15081
|
eligiblePasses,
|
|
15219
15082
|
eligibleMemberships,
|
|
15220
|
-
canPayDirectly: monetaryPaymentAvailable,
|
|
15221
15083
|
eventAcceptsPasses,
|
|
15222
15084
|
eventAcceptsMemberships,
|
|
15223
15085
|
availablePasses: [...response.entitlements.availableForPurchase.passes],
|
|
@@ -15234,8 +15096,8 @@ function getVisibleTicketTypes(input) {
|
|
|
15234
15096
|
})) : [];
|
|
15235
15097
|
return (input.eligibility?.ticketTypes ?? eventTicketTypes).filter((ticketType) => ticketType.isActive && (!input.selectedAttendanceMode || (ticketType.attendanceScope ?? "both") === "both" || (ticketType.attendanceScope ?? "both") === input.selectedAttendanceMode));
|
|
15236
15098
|
}
|
|
15237
|
-
function
|
|
15238
|
-
return ticketTypes.length === 1 && ticketTypes[0]
|
|
15099
|
+
function getImplicitSingleTicketType(ticketTypes) {
|
|
15100
|
+
return ticketTypes.length === 1 && ticketTypes[0] && canRequestTicketOption(ticketTypes[0].availability) ? ticketTypes[0] : null;
|
|
15239
15101
|
}
|
|
15240
15102
|
function findSelectedTicketType(input) {
|
|
15241
15103
|
if (!input.selectedPricingOptionId) return null;
|
|
@@ -15246,32 +15108,74 @@ function findSelectedTicketType(input) {
|
|
|
15246
15108
|
}).find((ticketType) => ticketType.pricingOptionId === input.selectedPricingOptionId) ?? null;
|
|
15247
15109
|
}
|
|
15248
15110
|
//#endregion
|
|
15249
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/
|
|
15250
|
-
|
|
15251
|
-
|
|
15252
|
-
|
|
15253
|
-
|
|
15254
|
-
|
|
15255
|
-
|
|
15256
|
-
|
|
15257
|
-
|
|
15258
|
-
|
|
15259
|
-
|
|
15260
|
-
|
|
15111
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
|
|
15112
|
+
/** Public requests share subject identity without copying the run's display sessions. */
|
|
15113
|
+
function toRegistrationRequestSubject(subject, attendanceMode) {
|
|
15114
|
+
return subject.kind === "occurrence" ? {
|
|
15115
|
+
kind: "occurrence",
|
|
15116
|
+
occurrenceId: subject.occurrenceId,
|
|
15117
|
+
attendanceMode: attendanceMode ?? void 0
|
|
15118
|
+
} : {
|
|
15119
|
+
kind: "wholeSeries",
|
|
15120
|
+
eventSeriesId: subject.eventSeriesId,
|
|
15121
|
+
attendanceMode: attendanceMode ?? void 0
|
|
15122
|
+
};
|
|
15123
|
+
}
|
|
15124
|
+
function eventMatchesOccurrenceId(event, occurrenceId) {
|
|
15125
|
+
return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
|
|
15126
|
+
}
|
|
15127
|
+
function findEventByOccurrenceId(events, occurrenceId) {
|
|
15128
|
+
return events.find((event) => eventMatchesOccurrenceId(event, occurrenceId)) ?? null;
|
|
15129
|
+
}
|
|
15130
|
+
function findPreSelectedEvent(input) {
|
|
15131
|
+
const occurrenceContext = input.occurrenceContext;
|
|
15132
|
+
if (!occurrenceContext) return input.scopedEvents.length === 1 ? input.scopedEvents[0] ?? null : null;
|
|
15133
|
+
const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
|
|
15134
|
+
startsAt: occurrenceContext.startsAt,
|
|
15135
|
+
timeZone: occurrenceContext.timeZone
|
|
15261
15136
|
}));
|
|
15137
|
+
return input.scopedEvents.find((event) => eventMatchesOccurrenceId(event, occurrenceContext.id) || getBookingLocalDateKey(toScheduledBookingDateTime({
|
|
15138
|
+
startsAt: event.startsAt,
|
|
15139
|
+
timeZone: event.timeZone
|
|
15140
|
+
})) === contextDate) ?? null;
|
|
15262
15141
|
}
|
|
15263
|
-
function
|
|
15264
|
-
|
|
15142
|
+
function resolveRegistrationTarget(input) {
|
|
15143
|
+
const subject = input.occurrenceContext ? {
|
|
15144
|
+
kind: "occurrence",
|
|
15145
|
+
occurrenceId: input.occurrenceContext.id
|
|
15146
|
+
} : input.selectedEvent?.registrationSubject ?? null;
|
|
15147
|
+
if (!subject) return null;
|
|
15148
|
+
return {
|
|
15149
|
+
subject,
|
|
15150
|
+
selectedEventId: input.selectedEvent?.selectionId ?? null
|
|
15151
|
+
};
|
|
15265
15152
|
}
|
|
15266
|
-
function
|
|
15267
|
-
|
|
15268
|
-
|
|
15153
|
+
function resolveEventRequiresPayment(input) {
|
|
15154
|
+
if (input.eligibility) return input.eligibility.requiresPayment;
|
|
15155
|
+
if (input.selectedTicketType) return input.selectedTicketType.priceAmount > 0;
|
|
15156
|
+
if (!input.event) return false;
|
|
15157
|
+
return publicEventPricingType(input.event.pricing) === "paid";
|
|
15269
15158
|
}
|
|
15270
|
-
function
|
|
15271
|
-
|
|
15272
|
-
if (input.
|
|
15273
|
-
|
|
15274
|
-
|
|
15159
|
+
function resolveDiscountContext(input) {
|
|
15160
|
+
const selection = input.paymentSelection.method ? input.paymentSelection : null;
|
|
15161
|
+
if (!input.event) return null;
|
|
15162
|
+
if (selection?.method === "pass_bundle" && selection.bundlePassId) return {
|
|
15163
|
+
type: "pass",
|
|
15164
|
+
passId: selection.bundlePassId
|
|
15165
|
+
};
|
|
15166
|
+
if (selection?.method === "membership_bundle" && selection.bundleMembershipId) return {
|
|
15167
|
+
type: "membership",
|
|
15168
|
+
membershipId: selection.bundleMembershipId
|
|
15169
|
+
};
|
|
15170
|
+
if (!input.eventRequiresPayment) return null;
|
|
15171
|
+
if (input.ticketsCount <= 0) return null;
|
|
15172
|
+
if (selection?.method && selection.method !== "stripe") return null;
|
|
15173
|
+
return {
|
|
15174
|
+
type: "event",
|
|
15175
|
+
eventSeriesId: input.event.seriesId,
|
|
15176
|
+
eventCategoryId: input.event.eventCategory?.id ?? null,
|
|
15177
|
+
ticketsCount: input.ticketsCount
|
|
15178
|
+
};
|
|
15275
15179
|
}
|
|
15276
15180
|
//#endregion
|
|
15277
15181
|
//#region ../blocks/src/system/runtime/nodes/event-registration/hooks.state.ts
|
|
@@ -15391,17 +15295,6 @@ function usePortalAuthWithDeps(deps) {
|
|
|
15391
15295
|
logout
|
|
15392
15296
|
};
|
|
15393
15297
|
}
|
|
15394
|
-
function toRegistrationOptionsSubject(subject, attendanceMode) {
|
|
15395
|
-
return subject.kind === "occurrence" ? {
|
|
15396
|
-
kind: "occurrence",
|
|
15397
|
-
occurrenceId: subject.occurrenceId,
|
|
15398
|
-
attendanceMode: attendanceMode ?? void 0
|
|
15399
|
-
} : {
|
|
15400
|
-
kind: "wholeSeries",
|
|
15401
|
-
eventSeriesId: subject.eventSeriesId,
|
|
15402
|
-
attendanceMode: attendanceMode ?? void 0
|
|
15403
|
-
};
|
|
15404
|
-
}
|
|
15405
15298
|
function useEligibility(params) {
|
|
15406
15299
|
return useEligibilityWithDeps(params, eventRegistrationHooksDeps);
|
|
15407
15300
|
}
|
|
@@ -15442,7 +15335,7 @@ function useEligibilityWithDeps(params, deps) {
|
|
|
15442
15335
|
requestIdRef.current = requestId;
|
|
15443
15336
|
dispatch({ type: "loading-started" });
|
|
15444
15337
|
try {
|
|
15445
|
-
const subject =
|
|
15338
|
+
const subject = toRegistrationRequestSubject(params.subject, params.attendanceMode);
|
|
15446
15339
|
const result = await api.getRegistrationOptions({
|
|
15447
15340
|
subject,
|
|
15448
15341
|
selections: ticketSelections.map((selection) => ({
|
|
@@ -15679,9 +15572,9 @@ const eventRegistrationErrors = {
|
|
|
15679
15572
|
message: "Booking is currently closed for this event. Please contact the organiser if you’d like to find out more.",
|
|
15680
15573
|
action: "none"
|
|
15681
15574
|
},
|
|
15682
|
-
|
|
15683
|
-
message: "We’
|
|
15684
|
-
action: "
|
|
15575
|
+
paymentInvestigationRequired: {
|
|
15576
|
+
message: "We still can’t confirm your payment. Please don’t make another payment. Contact the organiser so they can check your booking.",
|
|
15577
|
+
action: "none"
|
|
15685
15578
|
},
|
|
15686
15579
|
paymentProviderUnavailable: {
|
|
15687
15580
|
message: "We couldn’t reach the payment provider. Please try again in a minute.",
|
|
@@ -16179,7 +16072,30 @@ function checkoutReturnCommand(params) {
|
|
|
16179
16072
|
};
|
|
16180
16073
|
return null;
|
|
16181
16074
|
}
|
|
16182
|
-
|
|
16075
|
+
function handleCheckoutReturnOutcome(options, deps, context, outcome) {
|
|
16076
|
+
const { pending, params } = context;
|
|
16077
|
+
if (outcome.kind === "resolved") {
|
|
16078
|
+
deps.clearReturnParams();
|
|
16079
|
+
options.setPendingRegistrationReference(outcome.reference);
|
|
16080
|
+
options.setStep("verifying-payment");
|
|
16081
|
+
return "settled";
|
|
16082
|
+
}
|
|
16083
|
+
if (outcome.kind === "abandoned") {
|
|
16084
|
+
deps.clearReturnParams();
|
|
16085
|
+
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
16086
|
+
options.setStep("select-payment");
|
|
16087
|
+
return "settled";
|
|
16088
|
+
}
|
|
16089
|
+
if (outcome.kind === "notFound" && params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
|
|
16090
|
+
deps.clearReturnParams();
|
|
16091
|
+
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
16092
|
+
options.setStep("select-payment");
|
|
16093
|
+
return "settled";
|
|
16094
|
+
}
|
|
16095
|
+
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.");
|
|
16096
|
+
return outcome.kind === "notFound" ? "settled" : "retryable";
|
|
16097
|
+
}
|
|
16098
|
+
async function handleCheckoutReturn(options, deps, returnContextRef) {
|
|
16183
16099
|
deps.cleanupStaleRegistrations();
|
|
16184
16100
|
const params = deps.readReturnParams();
|
|
16185
16101
|
if (params.registration !== "cancelled" && params.registration !== "success") return "settled";
|
|
@@ -16193,34 +16109,15 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
|
|
|
16193
16109
|
}
|
|
16194
16110
|
const { checkoutAttemptId } = command;
|
|
16195
16111
|
const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
|
|
16196
|
-
|
|
16112
|
+
returnContextRef.current = { checkoutAttemptId };
|
|
16197
16113
|
if (pending) restorePendingPresentation(options, pending);
|
|
16198
16114
|
options.setStep("verifying-payment");
|
|
16199
16115
|
try {
|
|
16200
16116
|
const outcome = await options.api.resolveEventCheckoutReturn(command);
|
|
16201
|
-
|
|
16202
|
-
|
|
16203
|
-
|
|
16204
|
-
|
|
16205
|
-
options.setStep("verifying-payment");
|
|
16206
|
-
return "settled";
|
|
16207
|
-
case "abandoned":
|
|
16208
|
-
deps.clearReturnParams();
|
|
16209
|
-
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
16210
|
-
options.setStep("select-payment");
|
|
16211
|
-
return "settled";
|
|
16212
|
-
case "notFound":
|
|
16213
|
-
if (params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
|
|
16214
|
-
deps.clearReturnParams();
|
|
16215
|
-
options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
|
|
16216
|
-
options.setStep("select-payment");
|
|
16217
|
-
return "settled";
|
|
16218
|
-
}
|
|
16219
|
-
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.");
|
|
16220
|
-
return "settled";
|
|
16221
|
-
case "reconciliationRequired": break;
|
|
16222
|
-
}
|
|
16223
|
-
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.");
|
|
16117
|
+
return handleCheckoutReturnOutcome(options, deps, {
|
|
16118
|
+
pending,
|
|
16119
|
+
params
|
|
16120
|
+
}, outcome);
|
|
16224
16121
|
} catch {
|
|
16225
16122
|
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.");
|
|
16226
16123
|
}
|
|
@@ -16229,9 +16126,16 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
|
|
|
16229
16126
|
function useEventRegistrationStripeReturn(options) {
|
|
16230
16127
|
return useEventRegistrationStripeReturnWithDeps(options, eventRegistrationStripeReturnDeps);
|
|
16231
16128
|
}
|
|
16129
|
+
function completeVerifiedRegistration(options, deps, returnContext) {
|
|
16130
|
+
const siteId = options.api.config.siteId;
|
|
16131
|
+
const checkoutAttemptId = returnContext?.checkoutAttemptId;
|
|
16132
|
+
if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
|
|
16133
|
+
options.setRegistrationResult({ status: "confirmed" });
|
|
16134
|
+
options.setStep("success");
|
|
16135
|
+
}
|
|
16232
16136
|
function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
16233
16137
|
const { api, pendingRegistrationReference, setErrorMessage, setRegistrationResult, setStep, step } = options;
|
|
16234
|
-
const
|
|
16138
|
+
const returnContextRef = useRef(null);
|
|
16235
16139
|
const lookupInFlightRef = useRef(false);
|
|
16236
16140
|
const [lookupState, setLookupState] = useState("settled");
|
|
16237
16141
|
const resolveReturn = useCallback(async () => {
|
|
@@ -16239,7 +16143,7 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
|
16239
16143
|
lookupInFlightRef.current = true;
|
|
16240
16144
|
setLookupState("loading");
|
|
16241
16145
|
try {
|
|
16242
|
-
setLookupState(await handleCheckoutReturn(options, deps,
|
|
16146
|
+
setLookupState(await handleCheckoutReturn(options, deps, returnContextRef));
|
|
16243
16147
|
} finally {
|
|
16244
16148
|
lookupInFlightRef.current = false;
|
|
16245
16149
|
}
|
|
@@ -16262,13 +16166,8 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
|
16262
16166
|
resolveReturn();
|
|
16263
16167
|
}, []);
|
|
16264
16168
|
useEffect(() => {
|
|
16265
|
-
if (verification.status === "completed")
|
|
16266
|
-
|
|
16267
|
-
const checkoutAttemptId = checkoutAttemptIdRef.current;
|
|
16268
|
-
if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
|
|
16269
|
-
setRegistrationResult({ status: "confirmed" });
|
|
16270
|
-
setStep("success");
|
|
16271
|
-
} else if (verification.status === "failed") {
|
|
16169
|
+
if (verification.status === "completed") completeVerifiedRegistration(options, deps, returnContextRef.current);
|
|
16170
|
+
else if (verification.status === "failed") {
|
|
16272
16171
|
setErrorMessage("Please try again or choose another payment option. If this keeps happening, contact the organiser for help.");
|
|
16273
16172
|
setStep("payment-failed");
|
|
16274
16173
|
} else if (verification.status === "timeout") setStep("verifying-timeout");
|
|
@@ -16297,7 +16196,10 @@ function registrationErrorPresentation(error) {
|
|
|
16297
16196
|
const reason = error instanceof BlockApiError ? parseEventRegistrationErrorReason(error.tag) : null;
|
|
16298
16197
|
if (reason) return eventRegistrationErrors[reason];
|
|
16299
16198
|
if (error instanceof BlockApiError && error.status < 500) return eventRegistrationErrors.invalidCommitInput;
|
|
16300
|
-
return
|
|
16199
|
+
return {
|
|
16200
|
+
message: "Something went wrong. Please try again.",
|
|
16201
|
+
action: "retry"
|
|
16202
|
+
};
|
|
16301
16203
|
}
|
|
16302
16204
|
//#endregion
|
|
16303
16205
|
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.ts
|
|
@@ -16326,26 +16228,6 @@ function useEventRegistrationSubmit(options) {
|
|
|
16326
16228
|
* and the balance left, which the block's copy cannot. Every other method keeps
|
|
16327
16229
|
* whatever success message the site configured.
|
|
16328
16230
|
*/
|
|
16329
|
-
function toRegistrationResult(result) {
|
|
16330
|
-
if (result.alreadyRegistered) {
|
|
16331
|
-
const waitlisted = result.status === "waitlist";
|
|
16332
|
-
return {
|
|
16333
|
-
status: result.status,
|
|
16334
|
-
variant: "info",
|
|
16335
|
-
title: waitlisted ? "Already waitlisted" : "Already registered",
|
|
16336
|
-
message: result.message ?? (waitlisted ? "You are already on the waitlist for this event." : "You are already registered for this event.")
|
|
16337
|
-
};
|
|
16338
|
-
}
|
|
16339
|
-
if (result.status === "waitlist") return {
|
|
16340
|
-
status: "waitlist",
|
|
16341
|
-
title: "Added to waitlist",
|
|
16342
|
-
message: result.message ?? (typeof result.waitlistPosition === "number" ? `You've been added to the waitlist (position ${result.waitlistPosition}).` : "You've been added to the waitlist.")
|
|
16343
|
-
};
|
|
16344
|
-
return {
|
|
16345
|
-
status: result.status,
|
|
16346
|
-
message: result.paymentMethod === "pass" ? result.message : void 0
|
|
16347
|
-
};
|
|
16348
|
-
}
|
|
16349
16231
|
function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
16350
16232
|
/**
|
|
16351
16233
|
* The command identity for the submission currently in progress.
|
|
@@ -16359,7 +16241,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
16359
16241
|
* Identical retries retain the command after a lost response. Changed form
|
|
16360
16242
|
* details get a new command so the server applies the new booking intent.
|
|
16361
16243
|
*/
|
|
16362
|
-
const commandRef =
|
|
16244
|
+
const { commandRef } = options;
|
|
16363
16245
|
const inFlightRef = useRef(null);
|
|
16364
16246
|
const submit = async (method, passId, membershipId, selection, submitOptions) => {
|
|
16365
16247
|
const target = options.registrationTarget;
|
|
@@ -16372,19 +16254,15 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
16372
16254
|
const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
|
|
16373
16255
|
try {
|
|
16374
16256
|
let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
|
|
16375
|
-
|
|
16376
|
-
|
|
16377
|
-
|
|
16257
|
+
let request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
|
|
16258
|
+
const intentKey = registrationRequestIntentKey(request);
|
|
16259
|
+
if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) {
|
|
16260
|
+
prepared = {
|
|
16378
16261
|
...prepared,
|
|
16379
|
-
|
|
16380
|
-
}
|
|
16262
|
+
registrationCommandId: deps.createClientCommandId()
|
|
16263
|
+
};
|
|
16264
|
+
request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
|
|
16381
16265
|
}
|
|
16382
|
-
const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
|
|
16383
|
-
const intentKey = registrationRequestIntentKey(request);
|
|
16384
|
-
if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
|
|
16385
|
-
...prepared,
|
|
16386
|
-
registrationCommandId: deps.createClientCommandId()
|
|
16387
|
-
};
|
|
16388
16266
|
commandRef.current = {
|
|
16389
16267
|
id: prepared.registrationCommandId,
|
|
16390
16268
|
intentKey
|
|
@@ -16393,8 +16271,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
16393
16271
|
...request,
|
|
16394
16272
|
registrationCommandId: prepared.registrationCommandId
|
|
16395
16273
|
});
|
|
16396
|
-
|
|
16397
|
-
return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
|
|
16274
|
+
return await completeRegistrationSubmission(options, deps, prepared, result, submitOptions);
|
|
16398
16275
|
} catch (error) {
|
|
16399
16276
|
if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
|
|
16400
16277
|
const { message, action } = registrationErrorPresentation(error);
|
|
@@ -16418,9 +16295,40 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
16418
16295
|
return pending;
|
|
16419
16296
|
};
|
|
16420
16297
|
}
|
|
16421
|
-
async function completeRegistrationSubmission(options, deps, prepared, result,
|
|
16422
|
-
|
|
16423
|
-
|
|
16298
|
+
async function completeRegistrationSubmission(options, deps, prepared, result, submitOptions) {
|
|
16299
|
+
switch (result.kind) {
|
|
16300
|
+
case "paymentStatusRequired":
|
|
16301
|
+
options.setPaymentStatusRecovery({
|
|
16302
|
+
kind: "ready",
|
|
16303
|
+
subject: result.subject
|
|
16304
|
+
});
|
|
16305
|
+
options.setStep("payment-status");
|
|
16306
|
+
return {
|
|
16307
|
+
ok: true,
|
|
16308
|
+
outcome: { kind: "payment_status" }
|
|
16309
|
+
};
|
|
16310
|
+
case "checkoutRequired":
|
|
16311
|
+
options.setPendingRegistrationReference(result.reference);
|
|
16312
|
+
savePendingCheckout(options, deps, prepared, result.submissionId, result.reference);
|
|
16313
|
+
options.setStep("redirecting");
|
|
16314
|
+
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
16315
|
+
case "waitlisted":
|
|
16316
|
+
options.setRegistrationResult({
|
|
16317
|
+
status: "waitlist",
|
|
16318
|
+
title: "Added to waitlist",
|
|
16319
|
+
message: result.waitlist.message
|
|
16320
|
+
});
|
|
16321
|
+
break;
|
|
16322
|
+
case "bookingComplete":
|
|
16323
|
+
case "paymentDeferred":
|
|
16324
|
+
options.setPendingRegistrationReference(result.reference);
|
|
16325
|
+
options.setRegistrationResult({
|
|
16326
|
+
status: "confirmed",
|
|
16327
|
+
message: result.summary.paymentMethod === "pass" ? result.summary.message : void 0
|
|
16328
|
+
});
|
|
16329
|
+
break;
|
|
16330
|
+
}
|
|
16331
|
+
options.commandRef.current = null;
|
|
16424
16332
|
options.setStep("success");
|
|
16425
16333
|
return {
|
|
16426
16334
|
ok: true,
|
|
@@ -16451,15 +16359,7 @@ function prepareSubmitContext(options, registrationCommandId, target, method, pa
|
|
|
16451
16359
|
email: guest.email?.trim().toLowerCase() || void 0,
|
|
16452
16360
|
phone: guest.phone?.trim() || void 0
|
|
16453
16361
|
})) : void 0,
|
|
16454
|
-
subject: target.subject.
|
|
16455
|
-
kind: "occurrence",
|
|
16456
|
-
occurrenceId: target.subject.occurrenceId,
|
|
16457
|
-
attendanceMode: options.selectedAttendanceMode ?? void 0
|
|
16458
|
-
} : {
|
|
16459
|
-
kind: "wholeSeries",
|
|
16460
|
-
eventSeriesId: target.subject.eventSeriesId,
|
|
16461
|
-
attendanceMode: options.selectedAttendanceMode ?? void 0
|
|
16462
|
-
}
|
|
16362
|
+
subject: toRegistrationRequestSubject(target.subject, options.selectedAttendanceMode)
|
|
16463
16363
|
};
|
|
16464
16364
|
}
|
|
16465
16365
|
function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId, selection) {
|
|
@@ -16483,85 +16383,6 @@ function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId,
|
|
|
16483
16383
|
if (method === "free") return { method };
|
|
16484
16384
|
throw new Error("Choose an available payment option.");
|
|
16485
16385
|
}
|
|
16486
|
-
async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions) {
|
|
16487
|
-
options.setStep("redirecting");
|
|
16488
|
-
if (prepared.selectionSnapshot.method !== "stripe") throw new Error("Choose an available payment option.");
|
|
16489
|
-
const checkoutAttemptId = deps.createClientCommandId();
|
|
16490
|
-
const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
|
|
16491
|
-
const result = await options.api.createEventCheckout({
|
|
16492
|
-
subject: prepared.subject,
|
|
16493
|
-
ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
|
|
16494
|
-
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
16495
|
-
email: options.formData.email.trim().toLowerCase(),
|
|
16496
|
-
name: options.formData.name.trim(),
|
|
16497
|
-
phone: options.formData.phone.trim() || void 0,
|
|
16498
|
-
formData: options.formData,
|
|
16499
|
-
consentAccepted: options.formData.consentAccepted,
|
|
16500
|
-
altchaSolution: options.altchaSolution,
|
|
16501
|
-
guests: prepared.guestsPayload,
|
|
16502
|
-
claimToken: options.claimToken ?? void 0,
|
|
16503
|
-
waitlistEntryId: options.waitlistEntryId ?? void 0,
|
|
16504
|
-
discountCode: options.discountCode.trim() || void 0,
|
|
16505
|
-
collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
|
|
16506
|
-
checkoutAttemptId,
|
|
16507
|
-
...urls
|
|
16508
|
-
});
|
|
16509
|
-
if (result.scope !== "wholeSeries") throw new Error("Unexpected registration scope for event checkout.");
|
|
16510
|
-
if ("waitlistEntryId" in result) {
|
|
16511
|
-
options.setRegistrationResult({
|
|
16512
|
-
status: "waitlist",
|
|
16513
|
-
variant: result.alreadyRegistered ? "info" : void 0,
|
|
16514
|
-
title: result.alreadyRegistered ? "Already waitlisted" : "Added to waitlist",
|
|
16515
|
-
message: result.alreadyRegistered ? "You are already on the waitlist for this event." : "You've been added to the waitlist."
|
|
16516
|
-
});
|
|
16517
|
-
options.setStep("success");
|
|
16518
|
-
return {
|
|
16519
|
-
ok: true,
|
|
16520
|
-
outcome: { kind: "completed" }
|
|
16521
|
-
};
|
|
16522
|
-
}
|
|
16523
|
-
if (result.bypassed) return completeBypassedCheckout(options);
|
|
16524
|
-
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
16525
|
-
savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
|
|
16526
|
-
scope: "wholeSeries",
|
|
16527
|
-
registrationId: result.registrationId
|
|
16528
|
-
});
|
|
16529
|
-
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
16530
|
-
}
|
|
16531
|
-
function needsOccurrenceCheckout(result, method) {
|
|
16532
|
-
return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
|
|
16533
|
-
"stripe",
|
|
16534
|
-
"pass_bundle",
|
|
16535
|
-
"membership_bundle"
|
|
16536
|
-
].includes(method);
|
|
16537
|
-
}
|
|
16538
|
-
async function submitOccurrenceCheckout(options, deps, prepared, registration, method, submitOptions) {
|
|
16539
|
-
const reference = {
|
|
16540
|
-
scope: "occurrence",
|
|
16541
|
-
attendeeId: registration.attendeeId
|
|
16542
|
-
};
|
|
16543
|
-
options.setPendingRegistrationReference(reference);
|
|
16544
|
-
options.setStep("redirecting");
|
|
16545
|
-
const checkoutAttemptId = deps.createClientCommandId();
|
|
16546
|
-
const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
|
|
16547
|
-
const result = await options.api.createEventCheckout({
|
|
16548
|
-
subject: {
|
|
16549
|
-
kind: "occurrence",
|
|
16550
|
-
attendeeId: registration.attendeeId
|
|
16551
|
-
},
|
|
16552
|
-
registrationCommandId: prepared.registrationCommandId,
|
|
16553
|
-
checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
|
|
16554
|
-
productId: prepared.bundleProductId,
|
|
16555
|
-
discountCode: options.discountCode.trim() || void 0,
|
|
16556
|
-
collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0,
|
|
16557
|
-
...urls
|
|
16558
|
-
});
|
|
16559
|
-
if (result.scope !== "occurrence") throw new Error("Unexpected registration scope for event checkout.");
|
|
16560
|
-
if (result.bypassed) return completeBypassedCheckout(options);
|
|
16561
|
-
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
16562
|
-
if (prepared.subject.kind === "occurrence") savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference);
|
|
16563
|
-
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
16564
|
-
}
|
|
16565
16386
|
function savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference) {
|
|
16566
16387
|
const siteId = options.api.config.siteId;
|
|
16567
16388
|
if (!siteId) return;
|
|
@@ -16574,14 +16395,6 @@ function savePendingCheckout(options, deps, prepared, checkoutAttemptId, referen
|
|
|
16574
16395
|
paymentSelection: prepared.selectionSnapshot
|
|
16575
16396
|
});
|
|
16576
16397
|
}
|
|
16577
|
-
function completeBypassedCheckout(options) {
|
|
16578
|
-
options.setRegistrationResult({ status: "confirmed" });
|
|
16579
|
-
options.setStep("success");
|
|
16580
|
-
return {
|
|
16581
|
-
ok: true,
|
|
16582
|
-
outcome: { kind: "completed" }
|
|
16583
|
-
};
|
|
16584
|
-
}
|
|
16585
16398
|
function redirectToCheckout(checkoutUrl, submitOptions) {
|
|
16586
16399
|
if (submitOptions?.redirect !== "manual") window.location.href = checkoutUrl;
|
|
16587
16400
|
return {
|
|
@@ -16593,12 +16406,23 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
|
|
|
16593
16406
|
};
|
|
16594
16407
|
}
|
|
16595
16408
|
function registrationRequestIntentKey(request) {
|
|
16596
|
-
const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
|
|
16597
|
-
return JSON.stringify(
|
|
16409
|
+
const { registrationCommandId: _command, altchaSolution: _proof, checkout, ...intent } = request;
|
|
16410
|
+
return JSON.stringify({
|
|
16411
|
+
...intent,
|
|
16412
|
+
checkout: checkout ? {
|
|
16413
|
+
discountCode: checkout.discountCode,
|
|
16414
|
+
collectionOptionKind: checkout.collectionOptionKind
|
|
16415
|
+
} : void 0
|
|
16416
|
+
});
|
|
16598
16417
|
}
|
|
16599
|
-
function
|
|
16418
|
+
function buildRegistrationRequest(options, prepared, method, passId, membershipId) {
|
|
16600
16419
|
return {
|
|
16601
16420
|
registrationCommandId: prepared.registrationCommandId,
|
|
16421
|
+
checkout: {
|
|
16422
|
+
...buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: prepared.registrationCommandId }),
|
|
16423
|
+
discountCode: options.discountCode.trim() || void 0,
|
|
16424
|
+
collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0
|
|
16425
|
+
},
|
|
16602
16426
|
subject: prepared.subject,
|
|
16603
16427
|
ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
|
|
16604
16428
|
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
@@ -16618,64 +16442,6 @@ function buildOccurrenceRegistrationRequest(options, prepared, method, passId, m
|
|
|
16618
16442
|
};
|
|
16619
16443
|
}
|
|
16620
16444
|
//#endregion
|
|
16621
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
|
|
16622
|
-
function eventMatchesOccurrenceId(event, occurrenceId) {
|
|
16623
|
-
return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
|
|
16624
|
-
}
|
|
16625
|
-
function findEventByOccurrenceId(events, occurrenceId) {
|
|
16626
|
-
return events.find((event) => eventMatchesOccurrenceId(event, occurrenceId)) ?? null;
|
|
16627
|
-
}
|
|
16628
|
-
function findPreSelectedEvent(input) {
|
|
16629
|
-
const occurrenceContext = input.occurrenceContext;
|
|
16630
|
-
if (!occurrenceContext) return input.scopedEvents.length === 1 ? input.scopedEvents[0] ?? null : null;
|
|
16631
|
-
const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
|
|
16632
|
-
startsAt: occurrenceContext.startsAt,
|
|
16633
|
-
timeZone: occurrenceContext.timeZone
|
|
16634
|
-
}));
|
|
16635
|
-
return input.scopedEvents.find((event) => eventMatchesOccurrenceId(event, occurrenceContext.id) || getBookingLocalDateKey(toScheduledBookingDateTime({
|
|
16636
|
-
startsAt: event.startsAt,
|
|
16637
|
-
timeZone: event.timeZone
|
|
16638
|
-
})) === contextDate) ?? null;
|
|
16639
|
-
}
|
|
16640
|
-
function resolveRegistrationTarget(input) {
|
|
16641
|
-
const subject = input.occurrenceContext ? {
|
|
16642
|
-
kind: "occurrence",
|
|
16643
|
-
occurrenceId: input.occurrenceContext.id
|
|
16644
|
-
} : input.selectedEvent?.registrationSubject ?? null;
|
|
16645
|
-
if (!subject) return null;
|
|
16646
|
-
return {
|
|
16647
|
-
subject,
|
|
16648
|
-
selectedEventId: input.selectedEvent?.selectionId ?? null
|
|
16649
|
-
};
|
|
16650
|
-
}
|
|
16651
|
-
function resolveEventRequiresPayment(input) {
|
|
16652
|
-
if (input.eligibility) return input.eligibility.requiresPayment;
|
|
16653
|
-
if (input.selectedTicketType) return input.selectedTicketType.priceAmount > 0;
|
|
16654
|
-
if (!input.event) return false;
|
|
16655
|
-
return publicEventPricingType(input.event.pricing) === "paid";
|
|
16656
|
-
}
|
|
16657
|
-
function resolveDiscountContext(input) {
|
|
16658
|
-
const selection = input.paymentSelection.method ? input.paymentSelection : null;
|
|
16659
|
-
if (!input.event) return null;
|
|
16660
|
-
if (selection?.method === "pass_bundle" && selection.bundlePassId) return {
|
|
16661
|
-
type: "pass",
|
|
16662
|
-
passId: selection.bundlePassId
|
|
16663
|
-
};
|
|
16664
|
-
if (selection?.method === "membership_bundle" && selection.bundleMembershipId) return {
|
|
16665
|
-
type: "membership",
|
|
16666
|
-
membershipId: selection.bundleMembershipId
|
|
16667
|
-
};
|
|
16668
|
-
if (!input.eventRequiresPayment) return null;
|
|
16669
|
-
if (input.ticketsCount <= 0) return null;
|
|
16670
|
-
if (selection?.method && selection.method !== "stripe") return null;
|
|
16671
|
-
return {
|
|
16672
|
-
type: "event",
|
|
16673
|
-
eventSeriesId: input.event.seriesId,
|
|
16674
|
-
eventCategoryId: input.event.eventCategory?.id ?? null,
|
|
16675
|
-
ticketsCount: input.ticketsCount
|
|
16676
|
-
};
|
|
16677
|
-
}
|
|
16678
|
-
//#endregion
|
|
16679
16445
|
//#region ../blocks/src/system/runtime/nodes/event-registration/useSettledCommerceView.ts
|
|
16680
16446
|
function buildCandidate(input) {
|
|
16681
16447
|
if (!input.eligibilityIsSettled || !input.eligibility || !input.currentEvent) return null;
|
|
@@ -16896,7 +16662,7 @@ function computeAutoSelection(input) {
|
|
|
16896
16662
|
return { method: null };
|
|
16897
16663
|
}
|
|
16898
16664
|
function computeDirectPaymentSelection(eligibility) {
|
|
16899
|
-
if (!eligibility?.
|
|
16665
|
+
if (!eligibility?.requiresPayment) return { method: null };
|
|
16900
16666
|
const approvedKinds = getApprovedDirectPaymentCollectionOptionKinds(eligibility.paymentOptions);
|
|
16901
16667
|
const collectionOptionKind = approvedKinds.includes("upfront") ? "upfront" : approvedKinds[0];
|
|
16902
16668
|
return collectionOptionKind ? {
|
|
@@ -16910,7 +16676,7 @@ function isSelectionValid(input) {
|
|
|
16910
16676
|
if (!eligibility) return selection.method === "stripe" || selection.method === "pass_bundle" || selection.method === "membership_bundle";
|
|
16911
16677
|
switch (selection.method) {
|
|
16912
16678
|
case "free": return eligibility.isFree;
|
|
16913
|
-
case "stripe": return Boolean(eligibility.
|
|
16679
|
+
case "stripe": return Boolean(eligibility.requiresPayment && eligibility.price);
|
|
16914
16680
|
case "pass": return isAuthenticated && ticketsCount === 1 && !!selection.passId && eligibility.eligiblePasses.some((pass) => pass.id === selection.passId);
|
|
16915
16681
|
case "membership": return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some((membership) => membership.id === selection.membershipId);
|
|
16916
16682
|
case "pass_bundle": return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some((pass) => pass.id === selection.bundlePassId);
|
|
@@ -16929,7 +16695,7 @@ function normalizeRegistrationFlowState(state) {
|
|
|
16929
16695
|
ticketsCount: state.ticketsCount,
|
|
16930
16696
|
passOptOut: nextPassOptOut
|
|
16931
16697
|
});
|
|
16932
|
-
const canKeepManualSelection = state.step
|
|
16698
|
+
const canKeepManualSelection = state.step !== "select-tickets" && state.selectionSource === "manual" && isSelectionValid({
|
|
16933
16699
|
selection: state.paymentSelection,
|
|
16934
16700
|
isAuthenticated: state.isAuthenticated,
|
|
16935
16701
|
eligibility: state.eligibility,
|
|
@@ -16995,6 +16761,24 @@ function requiresPaymentStep(params) {
|
|
|
16995
16761
|
if (!params.eventRequiresPayment) return false;
|
|
16996
16762
|
return !isEntitlementSelection(params.paymentSelection);
|
|
16997
16763
|
}
|
|
16764
|
+
//#endregion
|
|
16765
|
+
//#region ../blocks/src/system/runtime/nodes/events/domain/destination.ts
|
|
16766
|
+
function isRecord$1(value) {
|
|
16767
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
16768
|
+
}
|
|
16769
|
+
function isRuntimeEventDestination(value) {
|
|
16770
|
+
if (!isRecord$1(value) || typeof value.kind !== "string") return false;
|
|
16771
|
+
if (value.kind === "native") return (value.mode === "cms-managed" || value.mode === "system-managed") && typeof value.path === "string";
|
|
16772
|
+
return value.kind === "external" && typeof value.url === "string" && typeof value.label === "string";
|
|
16773
|
+
}
|
|
16774
|
+
function resolveRuntimeEventDestination(event) {
|
|
16775
|
+
if (isRuntimeEventDestination(event.destination)) return event.destination;
|
|
16776
|
+
return {
|
|
16777
|
+
kind: "native",
|
|
16778
|
+
mode: event.eventDestinationMode === "system-managed" ? "system-managed" : "cms-managed",
|
|
16779
|
+
path: typeof event.path === "string" ? event.path : ""
|
|
16780
|
+
};
|
|
16781
|
+
}
|
|
16998
16782
|
const unsupportedEventRegistrationPageSurfaceSubjectSchema = z.object({
|
|
16999
16783
|
kind: z.literal("unsupported"),
|
|
17000
16784
|
reason: z.enum([
|
|
@@ -17237,7 +17021,7 @@ function resolveEventRegistrationSubmitPlan(input) {
|
|
|
17237
17021
|
const selection = input.paymentSelection.method ? input.paymentSelection : void 0;
|
|
17238
17022
|
if (input.canJoinWaitlist) return {
|
|
17239
17023
|
ok: true,
|
|
17240
|
-
args:
|
|
17024
|
+
args: { method: "free" }
|
|
17241
17025
|
};
|
|
17242
17026
|
switch (input.paymentSelection.method) {
|
|
17243
17027
|
case "pass": return input.paymentSelection.passId ? {
|
|
@@ -17288,6 +17072,10 @@ function resolveHeadlessEventRegistrationStatus(wizard) {
|
|
|
17288
17072
|
case "redirecting": return { tag: "redirecting" };
|
|
17289
17073
|
case "verifying-payment": return { tag: "verifying-payment" };
|
|
17290
17074
|
case "verifying-timeout": return { tag: "verifying-timeout" };
|
|
17075
|
+
case "payment-status": return wizard.paymentStatusRecovery ? {
|
|
17076
|
+
tag: "payment-status",
|
|
17077
|
+
state: wizard.paymentStatusRecovery
|
|
17078
|
+
} : { tag: "ready" };
|
|
17291
17079
|
case "payment-failed": return {
|
|
17292
17080
|
tag: "payment-failed",
|
|
17293
17081
|
message: wizard.errorMessage
|
|
@@ -17334,6 +17122,10 @@ function resolveHeadlessEventRegistrationView(wizard) {
|
|
|
17334
17122
|
kind: "verifying",
|
|
17335
17123
|
message: "Your booking is not confirmed yet. Please don’t make another booking while we check. You can check your payment status again in a moment."
|
|
17336
17124
|
};
|
|
17125
|
+
case "payment-status": return wizard.paymentStatusRecovery ? {
|
|
17126
|
+
kind: "payment-status",
|
|
17127
|
+
state: wizard.paymentStatusRecovery
|
|
17128
|
+
} : { kind: "form" };
|
|
17337
17129
|
case "select-event":
|
|
17338
17130
|
case "select-tickets":
|
|
17339
17131
|
case "enter-details":
|
|
@@ -17600,20 +17392,124 @@ function useWaitlistClaimRestoration(input) {
|
|
|
17600
17392
|
}
|
|
17601
17393
|
//#endregion
|
|
17602
17394
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationCompletion.ts
|
|
17395
|
+
function isSelectionSoldOut(availability) {
|
|
17396
|
+
return availability?.kind === "unavailable" && availability.reason === "full";
|
|
17397
|
+
}
|
|
17603
17398
|
function resolveRegistrationAvailabilityBlocker(input) {
|
|
17604
17399
|
if (input.hasWaitlistClaim) return null;
|
|
17605
17400
|
if (input.eligibilityError) return input.eligibilityError;
|
|
17606
17401
|
if (!input.eligibility) return "Registration is not available for this event.";
|
|
17402
|
+
if (input.eligibility.registration.kind === "pending_payment") return null;
|
|
17403
|
+
if (isSelectionSoldOut(input.eligibility.availability)) return null;
|
|
17607
17404
|
if (input.eligibility.availability.kind === "unavailable" && input.eligibility.availability.reason === "paymentUnavailable") return "Payment options are not available for this event.";
|
|
17608
|
-
if (input.eligibility.availability.kind === "unavailable" ||
|
|
17405
|
+
if (input.eligibility.availability.kind === "unavailable" || input.eligibility.registration.kind === "waitlisted") return "Registration is not available for this event.";
|
|
17609
17406
|
return null;
|
|
17610
17407
|
}
|
|
17611
17408
|
function resolvePricingSelectionBlocker(input) {
|
|
17612
17409
|
if (input.selectionRequired && !input.hasValidSelection) return "Choose at least one available ticket to continue.";
|
|
17613
17410
|
return input.slidingScaleSelectionMessage;
|
|
17614
17411
|
}
|
|
17615
|
-
|
|
17616
|
-
|
|
17412
|
+
//#endregion
|
|
17413
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.ts
|
|
17414
|
+
function isCheckableRecovery(state) {
|
|
17415
|
+
return state.kind === "ready" || state.kind === "processing" || state.kind === "temporarilyUnavailable";
|
|
17416
|
+
}
|
|
17417
|
+
function assistanceRequired(recovery) {
|
|
17418
|
+
return {
|
|
17419
|
+
kind: "assistanceRequired",
|
|
17420
|
+
subject: recovery.subject
|
|
17421
|
+
};
|
|
17422
|
+
}
|
|
17423
|
+
function applyStatusOutcome(outcome, recovery, setters, setRecovery) {
|
|
17424
|
+
if (outcome.kind === "resolved") {
|
|
17425
|
+
setters.setPendingRegistrationReference(outcome.reference);
|
|
17426
|
+
setters.setRegistrationResult({ status: "confirmed" });
|
|
17427
|
+
setRecovery(null);
|
|
17428
|
+
setters.setStep("success");
|
|
17429
|
+
return;
|
|
17430
|
+
}
|
|
17431
|
+
switch (outcome.kind) {
|
|
17432
|
+
case "paymentProcessing":
|
|
17433
|
+
setRecovery({
|
|
17434
|
+
...recovery,
|
|
17435
|
+
kind: "processing"
|
|
17436
|
+
});
|
|
17437
|
+
return;
|
|
17438
|
+
case "paymentAvailable":
|
|
17439
|
+
setRecovery({
|
|
17440
|
+
...recovery,
|
|
17441
|
+
kind: "paymentAvailable",
|
|
17442
|
+
checkoutUrl: outcome.checkoutUrl
|
|
17443
|
+
});
|
|
17444
|
+
return;
|
|
17445
|
+
case "paymentCheckUnavailable":
|
|
17446
|
+
setRecovery({
|
|
17447
|
+
...recovery,
|
|
17448
|
+
kind: "temporarilyUnavailable"
|
|
17449
|
+
});
|
|
17450
|
+
return;
|
|
17451
|
+
case "paymentRetryAvailable":
|
|
17452
|
+
setRecovery({
|
|
17453
|
+
...recovery,
|
|
17454
|
+
kind: "retryAvailable"
|
|
17455
|
+
});
|
|
17456
|
+
return;
|
|
17457
|
+
case "abandoned":
|
|
17458
|
+
case "notFound":
|
|
17459
|
+
case "reconciliationRequired":
|
|
17460
|
+
case "paymentAssistanceRequired":
|
|
17461
|
+
setRecovery(assistanceRequired(recovery));
|
|
17462
|
+
return;
|
|
17463
|
+
}
|
|
17464
|
+
}
|
|
17465
|
+
function usePaymentStatusRecovery(options) {
|
|
17466
|
+
const [recovery, setRecovery] = useState(null);
|
|
17467
|
+
const checkRef = useRef(null);
|
|
17468
|
+
return {
|
|
17469
|
+
recovery,
|
|
17470
|
+
showRecovery: useCallback((next) => setRecovery(next), []),
|
|
17471
|
+
check: useCallback(() => {
|
|
17472
|
+
if (!recovery || !isCheckableRecovery(recovery) || checkRef.current) return;
|
|
17473
|
+
const pending = (async () => {
|
|
17474
|
+
setRecovery({
|
|
17475
|
+
...recovery,
|
|
17476
|
+
kind: "checking"
|
|
17477
|
+
});
|
|
17478
|
+
try {
|
|
17479
|
+
applyStatusOutcome(await options.api.resolveEventCheckoutReturn({
|
|
17480
|
+
kind: "checkStatus",
|
|
17481
|
+
subject: recovery.subject
|
|
17482
|
+
}), recovery, options, setRecovery);
|
|
17483
|
+
} catch {
|
|
17484
|
+
setRecovery({
|
|
17485
|
+
...recovery,
|
|
17486
|
+
kind: "temporarilyUnavailable"
|
|
17487
|
+
});
|
|
17488
|
+
}
|
|
17489
|
+
})();
|
|
17490
|
+
checkRef.current = pending;
|
|
17491
|
+
pending.finally(() => {
|
|
17492
|
+
if (checkRef.current === pending) checkRef.current = null;
|
|
17493
|
+
});
|
|
17494
|
+
}, [options, recovery]),
|
|
17495
|
+
continuePayment: useCallback(() => {
|
|
17496
|
+
if (recovery?.kind === "paymentAvailable") window.location.assign(recovery.checkoutUrl);
|
|
17497
|
+
}, [recovery]),
|
|
17498
|
+
returnToPayment: useCallback(() => {
|
|
17499
|
+
if (recovery?.kind !== "retryAvailable") return;
|
|
17500
|
+
options.beginNewSubmission();
|
|
17501
|
+
setRecovery(null);
|
|
17502
|
+
options.setOptionsRefreshKey((value) => value + 1);
|
|
17503
|
+
options.setStep("select-payment");
|
|
17504
|
+
}, [options, recovery]),
|
|
17505
|
+
returnToBooking: useCallback(() => {
|
|
17506
|
+
if (recovery?.kind !== "assistanceRequired") return;
|
|
17507
|
+
options.beginNewSubmission();
|
|
17508
|
+
setRecovery(null);
|
|
17509
|
+
options.setOptionsRefreshKey((value) => value + 1);
|
|
17510
|
+
options.setStep("select-tickets");
|
|
17511
|
+
}, [options, recovery])
|
|
17512
|
+
};
|
|
17617
17513
|
}
|
|
17618
17514
|
//#endregion
|
|
17619
17515
|
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
|
|
@@ -17671,6 +17567,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17671
17567
|
const [errorAction, setErrorAction] = useState("retry");
|
|
17672
17568
|
const [optionsRefreshKey, setOptionsRefreshKey] = useState(0);
|
|
17673
17569
|
const [altchaSolution, setAltchaSolution] = useState(null);
|
|
17570
|
+
const [checkingNextStep, setCheckingNextStep] = useState(false);
|
|
17674
17571
|
const { authState: portalAuthState, profile: portalProfile } = deps.usePortalAuth();
|
|
17675
17572
|
const waitlistClaim = deps.useWaitlistClaim();
|
|
17676
17573
|
const [showMagicLinkModal, setShowMagicLinkModal] = useState(false);
|
|
@@ -17697,28 +17594,29 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17697
17594
|
}), [options.occurrenceContext, selectedEvent]);
|
|
17698
17595
|
const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
|
|
17699
17596
|
const currentEvent = selectedEvent ?? preSelectedEvent;
|
|
17597
|
+
const commandRef = useRef(null);
|
|
17700
17598
|
const setStep = useCallback((nextStep) => {
|
|
17701
17599
|
dispatchFlow({
|
|
17702
17600
|
type: "set-step",
|
|
17703
17601
|
step: nextStep
|
|
17704
17602
|
});
|
|
17705
17603
|
}, []);
|
|
17706
|
-
const {
|
|
17707
|
-
|
|
17708
|
-
|
|
17709
|
-
|
|
17604
|
+
const { recovery: paymentStatusRecovery, showRecovery: setPaymentStatusRecovery, check: handleCheckPaymentStatus, continuePayment: handleContinueExistingPayment, returnToPayment: handleReturnToPayment, returnToBooking: handleReturnToBooking } = usePaymentStatusRecovery({
|
|
17605
|
+
api,
|
|
17606
|
+
beginNewSubmission: () => {
|
|
17607
|
+
commandRef.current = null;
|
|
17608
|
+
},
|
|
17609
|
+
setPendingRegistrationReference,
|
|
17610
|
+
setRegistrationResult,
|
|
17611
|
+
setOptionsRefreshKey,
|
|
17612
|
+
setStep
|
|
17613
|
+
});
|
|
17614
|
+
const usesTicketTypeSelections = usesTieredPricing(currentEvent);
|
|
17710
17615
|
const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
|
|
17711
17616
|
event: currentEvent,
|
|
17712
17617
|
eligibility: null,
|
|
17713
17618
|
selectedAttendanceMode
|
|
17714
|
-
})
|
|
17715
|
-
...option,
|
|
17716
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
17717
|
-
} : option), [
|
|
17718
|
-
currentEvent,
|
|
17719
|
-
selectedAttendanceMode,
|
|
17720
|
-
checkoutRecovery
|
|
17721
|
-
]);
|
|
17619
|
+
}), [currentEvent, selectedAttendanceMode]);
|
|
17722
17620
|
const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
|
|
17723
17621
|
const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
|
|
17724
17622
|
const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
|
|
@@ -17756,7 +17654,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17756
17654
|
isAuthenticated: portalAuthState === "authenticated",
|
|
17757
17655
|
occurrenceId: registrationOccurrenceId
|
|
17758
17656
|
});
|
|
17759
|
-
const eligibility =
|
|
17657
|
+
const eligibility = eligibilityResult.eligibility;
|
|
17760
17658
|
const eligibilityLoading = eligibilityResult.isLoading;
|
|
17761
17659
|
const eligibilityError = eligibilityResult.error;
|
|
17762
17660
|
const portalCreditState = eligibilityResult.creditState;
|
|
@@ -17868,14 +17766,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17868
17766
|
event: currentEvent,
|
|
17869
17767
|
eligibility,
|
|
17870
17768
|
selectedAttendanceMode
|
|
17871
|
-
})
|
|
17872
|
-
...option,
|
|
17873
|
-
availability: checkoutRecoveryOptionAvailability(option.availability)
|
|
17874
|
-
} : option), [
|
|
17769
|
+
}), [
|
|
17875
17770
|
currentEvent,
|
|
17876
17771
|
selectedAttendanceMode,
|
|
17877
|
-
eligibility
|
|
17878
|
-
checkoutRecovery
|
|
17772
|
+
eligibility
|
|
17879
17773
|
]);
|
|
17880
17774
|
const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
|
|
17881
17775
|
const selectedTicketType = useMemo(() => findSelectedTicketType({
|
|
@@ -17899,12 +17793,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17899
17793
|
const event = currentEvent;
|
|
17900
17794
|
if (!usesTieredPricing(event)) return false;
|
|
17901
17795
|
if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
|
|
17902
|
-
return
|
|
17903
|
-
}, [
|
|
17904
|
-
currentEvent,
|
|
17905
|
-
selectedAttendanceMode,
|
|
17906
|
-
checkoutRecovery
|
|
17907
|
-
]);
|
|
17796
|
+
return true;
|
|
17797
|
+
}, [currentEvent, selectedAttendanceMode]);
|
|
17908
17798
|
const hasValidTicketSelection = hasValidPricingOptionSelection({
|
|
17909
17799
|
selectionRequired: ticketTypeSelectionRequired,
|
|
17910
17800
|
lines: normalizedSelectedTicketLines,
|
|
@@ -17915,8 +17805,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17915
17805
|
if (selectedTicketLines.length > 0) setSelectedTicketLines([]);
|
|
17916
17806
|
return;
|
|
17917
17807
|
}
|
|
17918
|
-
const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => ticketType.availability
|
|
17919
|
-
const implicitTicketType =
|
|
17808
|
+
const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => canRequestTicketOption(ticketType.availability));
|
|
17809
|
+
const implicitTicketType = getImplicitSingleTicketType(eventTicketTypesForSelection);
|
|
17920
17810
|
if (implicitTicketType && normalizedSelectedTicketLines.length === 0) {
|
|
17921
17811
|
setSelectedTicketLines([{
|
|
17922
17812
|
pricingOptionId: implicitTicketType.pricingOptionId,
|
|
@@ -17983,6 +17873,26 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17983
17873
|
selectedEventSlidingScale,
|
|
17984
17874
|
selectedSlidingAmount
|
|
17985
17875
|
]);
|
|
17876
|
+
const checkDetailsNextStep = async () => {
|
|
17877
|
+
if (portalAuthState === "authenticated" || waitlistClaim.claim || eligibility?.availability.kind === "available" || !registrationTarget) return { kind: canRecoverToWaitlist(eligibility) ? "waitlist" : "continue" };
|
|
17878
|
+
setCheckingNextStep(true);
|
|
17879
|
+
try {
|
|
17880
|
+
return await api.checkRegistrationNextStep({
|
|
17881
|
+
subject: toRegistrationRequestSubject(registrationTarget.subject, selectedAttendanceMode),
|
|
17882
|
+
selections: ticketSelections,
|
|
17883
|
+
selectedSlidingAmount: selectedSlidingAmount ?? void 0,
|
|
17884
|
+
email: formData.email,
|
|
17885
|
+
altchaSolution
|
|
17886
|
+
});
|
|
17887
|
+
} catch {
|
|
17888
|
+
return {
|
|
17889
|
+
kind: "unavailable",
|
|
17890
|
+
message: "We could not check availability. Please try again."
|
|
17891
|
+
};
|
|
17892
|
+
} finally {
|
|
17893
|
+
setCheckingNextStep(false);
|
|
17894
|
+
}
|
|
17895
|
+
};
|
|
17986
17896
|
const handleDetailsComplete = async () => {
|
|
17987
17897
|
const blockDetailsCompletion = (message) => {
|
|
17988
17898
|
setErrorAction("places");
|
|
@@ -18014,11 +17924,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18014
17924
|
message: "Check the highlighted fields and try again."
|
|
18015
17925
|
};
|
|
18016
17926
|
}
|
|
18017
|
-
|
|
18018
|
-
|
|
18019
|
-
|
|
18020
|
-
|
|
18021
|
-
if (!eligibility?.canJoinWaitlist && requiresPaymentStep({
|
|
17927
|
+
const next = await checkDetailsNextStep();
|
|
17928
|
+
if (next.kind === "unavailable") return blockDetailsCompletion(next.message);
|
|
17929
|
+
const canJoinWaitlist = next.kind === "waitlist";
|
|
17930
|
+
if (!canJoinWaitlist && requiresPaymentStep({
|
|
18022
17931
|
eventRequiresPayment,
|
|
18023
17932
|
paymentSelection
|
|
18024
17933
|
})) {
|
|
@@ -18031,7 +17940,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18031
17940
|
const submitPlan = resolveEventRegistrationSubmitPlan({
|
|
18032
17941
|
paymentSelection,
|
|
18033
17942
|
eventRequiresPayment,
|
|
18034
|
-
canJoinWaitlist
|
|
17943
|
+
canJoinWaitlist
|
|
18035
17944
|
});
|
|
18036
17945
|
if (!submitPlan.ok) return blockDetailsCompletion(submitPlan.message);
|
|
18037
17946
|
const submitResult = await handleSubmit(submitPlan.args.method, submitPlan.args.passId, submitPlan.args.membershipId, submitPlan.args.selection);
|
|
@@ -18049,7 +17958,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18049
17958
|
const submitPlan = resolveEventRegistrationSubmitPlan({
|
|
18050
17959
|
paymentSelection,
|
|
18051
17960
|
eventRequiresPayment,
|
|
18052
|
-
canJoinWaitlist:
|
|
17961
|
+
canJoinWaitlist: false
|
|
18053
17962
|
});
|
|
18054
17963
|
if (!submitPlan.ok) {
|
|
18055
17964
|
setErrorMessage(submitPlan.message);
|
|
@@ -18081,6 +17990,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18081
17990
|
const selectionMethod = paymentSelection.method;
|
|
18082
17991
|
const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
|
|
18083
17992
|
const handleSubmit = deps.useEventRegistrationSubmit({
|
|
17993
|
+
commandRef,
|
|
18084
17994
|
setErrorAction,
|
|
18085
17995
|
api,
|
|
18086
17996
|
registrationTarget,
|
|
@@ -18097,7 +18007,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18097
18007
|
setPendingRegistrationReference,
|
|
18098
18008
|
setStep,
|
|
18099
18009
|
setRegistrationResult: (result) => setRegistrationResult(result),
|
|
18100
|
-
setErrorMessage
|
|
18010
|
+
setErrorMessage,
|
|
18011
|
+
setPaymentStatusRecovery
|
|
18101
18012
|
});
|
|
18102
18013
|
const handleEventSelect = (event) => {
|
|
18103
18014
|
setSelectedEvent(event);
|
|
@@ -18156,8 +18067,6 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18156
18067
|
scopedEvents,
|
|
18157
18068
|
preSelectedEvent,
|
|
18158
18069
|
hasPreSelectedContext,
|
|
18159
|
-
checkoutRecovery,
|
|
18160
|
-
startCheckoutRecovery,
|
|
18161
18070
|
step,
|
|
18162
18071
|
setStep,
|
|
18163
18072
|
selectedEvent,
|
|
@@ -18211,7 +18120,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18211
18120
|
waitlistClaim,
|
|
18212
18121
|
eligibility,
|
|
18213
18122
|
registrationOptionsState: eligibilityResult.state,
|
|
18214
|
-
eligibilityLoading,
|
|
18123
|
+
eligibilityLoading: eligibilityLoading || checkingNextStep,
|
|
18215
18124
|
eligibilityError,
|
|
18216
18125
|
existingRegistration: existingRegistrationResult.registration,
|
|
18217
18126
|
existingRegistrationLoading: existingRegistrationResult.isLoading || portalAuthState === "authenticated" && eligibilityLoading,
|
|
@@ -18231,6 +18140,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
18231
18140
|
discountContext,
|
|
18232
18141
|
shouldShowDiscountToggle,
|
|
18233
18142
|
verification,
|
|
18143
|
+
paymentStatusRecovery,
|
|
18144
|
+
handleCheckPaymentStatus,
|
|
18145
|
+
handleContinueExistingPayment,
|
|
18146
|
+
handleReturnToPayment,
|
|
18147
|
+
handleReturnToBooking,
|
|
18234
18148
|
handleDetailsComplete,
|
|
18235
18149
|
handlePaymentSelect,
|
|
18236
18150
|
handleUseCardInsteadOfPass,
|
|
@@ -18283,7 +18197,7 @@ function useEventRegistrationControllerWithDeps(options, deps) {
|
|
|
18283
18197
|
selection: wizard.paymentSelection
|
|
18284
18198
|
}),
|
|
18285
18199
|
eventRequiresPayment: wizard.eventRequiresPayment,
|
|
18286
|
-
canJoinWaitlist: wizard.eligibility?.
|
|
18200
|
+
canJoinWaitlist: wizard.step !== "select-payment" && wizard.eligibility?.availability.kind === "waitlist" && wizard.eligibility.registration.kind !== "pending_payment"
|
|
18287
18201
|
});
|
|
18288
18202
|
if (!plan.ok) return {
|
|
18289
18203
|
ok: false,
|
|
@@ -18328,6 +18242,7 @@ function useEventRegistrationControllerWithDeps(options, deps) {
|
|
|
18328
18242
|
case "redirecting":
|
|
18329
18243
|
case "verifying-payment":
|
|
18330
18244
|
case "verifying-timeout":
|
|
18245
|
+
case "payment-status":
|
|
18331
18246
|
case "payment-failed": return {
|
|
18332
18247
|
ok: false,
|
|
18333
18248
|
reason: "blocked",
|
|
@@ -18335,27 +18250,7 @@ function useEventRegistrationControllerWithDeps(options, deps) {
|
|
|
18335
18250
|
};
|
|
18336
18251
|
}
|
|
18337
18252
|
}, [submit, wizard]);
|
|
18338
|
-
const back =
|
|
18339
|
-
switch (wizard.step) {
|
|
18340
|
-
case "enter-details":
|
|
18341
|
-
wizard.setStep("select-tickets");
|
|
18342
|
-
return;
|
|
18343
|
-
case "select-payment":
|
|
18344
|
-
wizard.setStep("enter-details");
|
|
18345
|
-
return;
|
|
18346
|
-
case "select-tickets":
|
|
18347
|
-
if (!wizard.hasPreSelectedContext) wizard.setStep("select-event");
|
|
18348
|
-
return;
|
|
18349
|
-
case "select-event":
|
|
18350
|
-
case "error":
|
|
18351
|
-
case "success":
|
|
18352
|
-
case "submitting":
|
|
18353
|
-
case "redirecting":
|
|
18354
|
-
case "verifying-payment":
|
|
18355
|
-
case "verifying-timeout":
|
|
18356
|
-
case "payment-failed": return;
|
|
18357
|
-
}
|
|
18358
|
-
}, [wizard]);
|
|
18253
|
+
const back = useEventRegistrationBack(wizard);
|
|
18359
18254
|
const updateAttendee = useCallback((values) => {
|
|
18360
18255
|
wizard.setFormData(values);
|
|
18361
18256
|
}, [wizard]);
|
|
@@ -18442,7 +18337,8 @@ function useEventRegistrationControllerWithDeps(options, deps) {
|
|
|
18442
18337
|
terminal: {
|
|
18443
18338
|
result: wizard.registrationResult,
|
|
18444
18339
|
errorMessage: wizard.errorMessage,
|
|
18445
|
-
verification: wizard.verification
|
|
18340
|
+
verification: wizard.verification,
|
|
18341
|
+
paymentStatusRecovery: wizard.paymentStatusRecovery
|
|
18446
18342
|
},
|
|
18447
18343
|
actions: {
|
|
18448
18344
|
selectEvent: wizard.handleEventSelect,
|
|
@@ -18466,12 +18362,40 @@ function useEventRegistrationControllerWithDeps(options, deps) {
|
|
|
18466
18362
|
next,
|
|
18467
18363
|
back,
|
|
18468
18364
|
submit,
|
|
18469
|
-
retry: wizard.handleRetry
|
|
18365
|
+
retry: wizard.handleRetry,
|
|
18366
|
+
checkPaymentStatus: wizard.handleCheckPaymentStatus,
|
|
18367
|
+
continueExistingPayment: wizard.handleContinueExistingPayment,
|
|
18368
|
+
returnToPayment: wizard.handleReturnToPayment,
|
|
18369
|
+
returnToBooking: wizard.handleReturnToBooking
|
|
18470
18370
|
}
|
|
18471
18371
|
},
|
|
18472
18372
|
wizard
|
|
18473
18373
|
};
|
|
18474
18374
|
}
|
|
18375
|
+
function useEventRegistrationBack(wizard) {
|
|
18376
|
+
return useCallback(() => {
|
|
18377
|
+
switch (wizard.step) {
|
|
18378
|
+
case "enter-details":
|
|
18379
|
+
wizard.setStep("select-tickets");
|
|
18380
|
+
return;
|
|
18381
|
+
case "select-payment":
|
|
18382
|
+
wizard.setStep("enter-details");
|
|
18383
|
+
return;
|
|
18384
|
+
case "select-tickets":
|
|
18385
|
+
if (!wizard.hasPreSelectedContext) wizard.setStep("select-event");
|
|
18386
|
+
return;
|
|
18387
|
+
case "select-event":
|
|
18388
|
+
case "error":
|
|
18389
|
+
case "success":
|
|
18390
|
+
case "submitting":
|
|
18391
|
+
case "redirecting":
|
|
18392
|
+
case "verifying-payment":
|
|
18393
|
+
case "verifying-timeout":
|
|
18394
|
+
case "payment-status":
|
|
18395
|
+
case "payment-failed": return;
|
|
18396
|
+
}
|
|
18397
|
+
}, [wizard]);
|
|
18398
|
+
}
|
|
18475
18399
|
function useEventRegistrationWizardControllerWithDeps(options, deps) {
|
|
18476
18400
|
const maxTicketsNum = normalizeEventRegistrationMaxTickets(options.maxTickets);
|
|
18477
18401
|
return { wizard: deps.useEventRegistrationWizard({
|
|
@@ -18527,7 +18451,7 @@ function resolvePaymentModel(wizard, directPaymentOptions) {
|
|
|
18527
18451
|
}
|
|
18528
18452
|
function resolveHeadlessDirectPaymentOptions(wizard) {
|
|
18529
18453
|
const eligibility = wizard.eligibility;
|
|
18530
|
-
if (!eligibility?.
|
|
18454
|
+
if (!eligibility?.requiresPayment || !eligibility.price) return [];
|
|
18531
18455
|
const event = wizard.selectedEvent ?? wizard.preSelectedEvent;
|
|
18532
18456
|
return buildEventRegistrationPaymentOptionsViewModel({
|
|
18533
18457
|
eventTitle: event?.title ?? "Event",
|