@riverbankcms/sdk 0.151.0 → 0.152.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/CHANGELOG.md +37 -0
- package/dist/{EventEmbeddedCheckoutStep-BBHbM22D.mjs → EventEmbeddedCheckoutStep-DVQXWFm6.mjs} +10 -9
- package/dist/{PreviewEditorSidebar-BHplI9HE.mjs → PreviewEditorSidebar-Dr4NJi3Q.mjs} +4 -3
- package/dist/{PreviewEditorUI-DuyN8nsD.mjs → PreviewEditorUI-DSZXQbyh.mjs} +5 -4
- package/dist/{SdkPreviewModeRuntime-CR5ypwxJ.mjs → SdkPreviewModeRuntime-Dl4GyMc3.mjs} +124 -53
- package/dist/{SiteChromeCustomizeContext-D5t6joF_.mjs → SiteChromeCustomizeContext-DgBe-FlM.mjs} +20418 -32298
- package/dist/ThemedButton-B8ViBnLK.mjs +16350 -0
- package/dist/_dts/api/src/bookingOperations.d.ts +5 -3
- package/dist/_dts/api/src/commercePortalEndpoints.d.ts +4 -0
- package/dist/_dts/api/src/endpoints.d.ts +7 -0
- package/dist/_dts/api/src/index.d.ts +1 -1
- package/dist/_dts/api/src/navigation/types.d.ts +7 -0
- package/dist/_dts/api/src/navigation.d.ts +1 -1
- package/dist/_dts/api/src/publicAppointmentBookingContracts.d.ts +10 -1
- package/dist/_dts/api/src/siteAssets.d.ts +1 -0
- package/dist/_dts/blocks/src/definitions.d.ts +1 -1
- package/dist/_dts/blocks/src/index.d.ts +1 -0
- package/dist/_dts/blocks/src/pageRenderPreparation.d.ts +1 -0
- package/dist/_dts/blocks/src/pageRendererContracts.d.ts +1 -1
- package/dist/_dts/blocks/src/primitives/content/utils/sanitizeHref.d.ts +1 -1
- package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +4 -4
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +16 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +5 -0
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +2 -0
- package/dist/_dts/blocks/src/system/helpers/normalizeMailingListBlockContent.d.ts +2 -0
- package/dist/_dts/blocks/src/system/registry.d.ts +14 -2
- package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +0 -5
- package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/api/schemas/events.d.ts +971 -0
- package/dist/_dts/blocks/src/system/runtime/api/schemas/waitlist-claims.d.ts +42 -0
- package/dist/_dts/blocks/src/system/runtime/api/types/appointments.d.ts +10 -2
- package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +10 -136
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +48 -6
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -3
- package/dist/_dts/blocks/src/system/runtime/hooks/useBookingSubmission.state.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +3 -1
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +23 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +6 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/carousel.client.hooks.d.ts +6 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/carousel.client.state.d.ts +7 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/BookingEntryViews.d.ts +42 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventEmbeddedCheckoutStep.d.ts +4 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationBookingLayer.d.ts +19 -9
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationPayment.d.ts +4 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +24 -9
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizardContent.d.ts +4 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventSelectionStep.d.ts +5 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/GuestDetailsSection.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SingleTicketEntitlementNote.d.ts +11 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SuccessStep.d.ts +4 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +5 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/VerifyingTimeoutStep.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/bookingCardDisplay.d.ts +31 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/bookingEntry.d.ts +154 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/bookingFocus.d.ts +12 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -2
- 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/eventSourceRecovery.d.ts +9 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/finishedBooking.d.ts +77 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/index.d.ts +0 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/offeringNoun.d.ts +12 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/paymentResponse.d.ts +2 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationCompletion.d.ts +33 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDerivations.d.ts +11 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDisplay.d.ts +31 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDraft.state.d.ts +60 -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/registrationEventAdapter.d.ts +3 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationStateMachine.d.ts +58 -10
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationSurface.d.ts +17 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +23 -7
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useBookingBarFacts.d.ts +12 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationRecoveryRequest.d.ts +3 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +4 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +4 -11
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +1563 -31
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventSourceRecovery.d.ts +2 -12
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.d.ts +147 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +50 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/waitlistClaimRestoration.d.ts +6 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/wizardSteps.d.ts +85 -15
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +53 -8
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/MonthLookView.d.ts +10 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +16 -0
- package/dist/_dts/blocks/src/system/runtime/shared/bookingPaymentOptionCopy.d.ts +5 -1
- package/dist/_dts/blocks/src/system/runtime/shared/bookingPaymentOptions.d.ts +37 -1
- package/dist/_dts/blocks/src/system/runtime/shared/components/ModalShell.d.ts +9 -2
- package/dist/_dts/blocks/src/system/runtime/shared/components/PaymentChoiceRows.d.ts +28 -0
- package/dist/_dts/blocks/src/system/runtime/shared/components/StepIndicator.d.ts +6 -8
- package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +9 -12
- package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +15 -0
- package/dist/_dts/blocks/src/system/runtime/shared/utils/themePortalRoot.d.ts +10 -15
- package/dist/_dts/blocks/src/system/transforms/registry/index.d.ts +1 -0
- package/dist/_dts/blocks/src/system/transforms/registry/links.d.ts +3 -1
- package/dist/_dts/commerce/src/purchase/bookingInstalmentSchedule.d.ts +2 -0
- package/dist/_dts/commerce/src/purchase/bookingPaymentSelection.d.ts +6 -0
- package/dist/_dts/commerce/src/purchase/confirmationEmailPayment.d.ts +14 -14
- package/dist/_dts/commerce/src/purchase/confirmationPayment.d.ts +65 -0
- package/dist/_dts/commerce/src/purchase/confirmationPaymentSchema.d.ts +66 -0
- package/dist/_dts/commerce/src/purchase/index.d.ts +2 -0
- package/dist/_dts/commerce/src/purchase/orderPaymentState.d.ts +8 -0
- package/dist/_dts/content-model/src/templates/defaults.d.ts +2 -2
- package/dist/_dts/core/src/appointment-booking-terms.d.ts +20 -0
- package/dist/_dts/core/src/booking-payment-schemas.d.ts +70 -0
- package/dist/_dts/core/src/branded.d.ts +0 -2
- package/dist/_dts/core/src/demo-claim-access.d.ts +1 -1
- package/dist/_dts/core/src/demo-claim-readiness.d.ts +18 -0
- package/dist/_dts/core/src/demo-lifecycle-status.d.ts +1 -1
- package/dist/_dts/core/src/demo-warm-pool-target.d.ts +1 -1
- package/dist/_dts/core/src/index.d.ts +4 -0
- package/dist/_dts/core/src/mailing-list-targeting-availability.d.ts +68 -0
- package/dist/_dts/core/src/mailing-list-targeting.d.ts +2 -0
- package/dist/_dts/core/src/ticket-quantity.d.ts +13 -0
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +51 -32
- package/dist/_dts/editor/src/chrome/chromeLayers.d.ts +7 -0
- package/dist/_dts/editor/src/index.d.ts +1 -0
- package/dist/_dts/editor-blocks/src/widgets/link/LinkAddressInput.d.ts +8 -0
- package/dist/_dts/editor-blocks/src/widgets/link/LinkContentList.d.ts +12 -0
- package/dist/_dts/editor-blocks/src/widgets/link/LinkPicker.d.ts +5 -1
- package/dist/_dts/editor-blocks/src/widgets/link/LinkPickerDialog.d.ts +3 -3
- package/dist/_dts/editor-blocks/src/widgets/link/LinkSummary.d.ts +8 -2
- package/dist/_dts/editor-blocks/src/widgets/link/LinkWidget.d.ts +4 -3
- package/dist/_dts/editor-blocks/src/widgets/link/LinkWidgetContext.d.ts +2 -1
- package/dist/_dts/editor-blocks/src/widgets/link/draft.d.ts +44 -0
- package/dist/_dts/editor-blocks/src/widgets/link/presentation.d.ts +13 -0
- package/dist/_dts/editor-blocks/src/widgets/link/types.d.ts +14 -0
- package/dist/_dts/editor-blocks/src/widgets/link/useRoutableContent.d.ts +2 -0
- package/dist/_dts/editor-blocks/src/widgets/link/utils.d.ts +5 -4
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/MailingListTargetingField.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/widgets/mailing-list-targeting/targetingState.d.ts +13 -8
- package/dist/_dts/media-core/src/fileStorage.d.ts +4 -3
- package/dist/_dts/media-core/src/index.d.ts +1 -0
- package/dist/_dts/media-core/src/storageObjectKey.d.ts +12 -0
- package/dist/_dts/media-react/src/hooks/useSupabaseMediaUploader.d.ts +1 -1
- package/dist/_dts/media-react/src/internal/supabaseResumableUpload.d.ts +13 -0
- package/dist/_dts/preview-next/src/client/preview/previewModeRootAttribute.d.ts +11 -0
- package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +0 -1
- package/dist/_dts/sdk/src/rendering/image.d.ts +10 -0
- package/dist/_dts/sdk/src/rendering/index.d.ts +3 -1
- package/dist/_dts/sdk/src/rendering/link.d.ts +9 -0
- package/dist/_dts/sdk/src/rendering/overrides.d.ts +1 -0
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/theme-core/src/blocks/opaquePanels.d.ts +3 -3
- package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
- package/dist/client/BookingMailingListNote-CBuMKN0w.mjs +386 -0
- package/dist/client/{CardListItem-ZDLYh6dL.mjs → CardListItem-Dc9XTXhB.mjs} +3 -4
- package/dist/client/CheckIcon-CpyXr-Kg.mjs +35 -0
- package/dist/client/{CheckboxChoice-M-3HycLw.mjs → CheckboxChoice-CIqx_o0E.mjs} +1 -1
- package/dist/client/{DemoBookingPortalAccess-BMtvPTWE.mjs → DemoBookingPortalAccess-D3VQ_kLj.mjs} +85 -85
- package/dist/client/{EventCombined.client-DUm_DOxW.mjs → EventCombined.client-BHGEKise.mjs} +8 -9
- package/dist/client/{EventEmbeddedCheckoutStep-DsNNzgRm.mjs → EventEmbeddedCheckoutStep-Bo1Cm23R.mjs} +11 -10
- package/dist/client/{EventListing.client-DjNYGUVm.mjs → EventListing.client-D5OQgVPr.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-DuFiOHq_.mjs → LeafletStaticMap-CLL5cWrr.mjs} +1 -1
- package/dist/client/{ModalShell-CqkBvBIC.mjs → ModalShell-BXzucfR6.mjs} +83 -12
- package/dist/client/{RichText-LjPCUGGi.mjs → RichText-BoDmnopf.mjs} +6 -3
- package/dist/client/{ThemedButton-DZKjtaDD.mjs → ThemedButton-Ciltp0IK.mjs} +2 -2
- package/dist/client/{accordion-Qe--SILD.mjs → accordion-DOkRS64-.mjs} +1 -1
- package/dist/client/aspectTransforms-D-TnDdq4.mjs +93 -0
- package/dist/client/{bookingForm-3BCl4g_f.mjs → bookingForm-wlMVwo9h.mjs} +289 -149
- package/dist/client/bookings.mjs +12212 -10832
- package/dist/client/{carousel-h2YjKOS2.mjs → carousel-CGWk-Z0u.mjs} +2 -2
- package/dist/client/{carousel.client-BLrd4hmY.mjs → carousel.client-kX5mN1Eg.mjs} +46 -41
- package/dist/client/{cart-5NeiigVd.mjs → cart-OBBPlaH4.mjs} +3 -3
- package/dist/client/{checkout-G4UWjOEw.mjs → checkout-Bmw2WjQX.mjs} +3 -3
- package/dist/client/client.mjs +9541 -6039
- package/dist/client/{colorStyles-DTunOThj.mjs → colorStyles-ECDNPE_P.mjs} +23 -86
- package/dist/client/{context-GK4-AVAh.mjs → context-BI77UFAn.mjs} +275 -10
- package/dist/client/{eventCalendar-Prw3Yo_L.mjs → eventCalendar-qkej2Edn.mjs} +19 -17
- package/dist/client/{eventCombined-BUugi6__.mjs → eventCombined-DApKHvat.mjs} +4 -4
- package/dist/client/{eventDetails-CBHUda-R.mjs → eventDetails-BQyUDPH0.mjs} +3 -4
- package/dist/client/{eventListing-CQeG45Dg.mjs → eventListing-CeAnshlZ.mjs} +4 -4
- package/dist/client/{eventRegistration-Dif3p3oJ.mjs → eventRegistration-C3A3NyBO.mjs} +2209 -2144
- package/dist/client/{form-Cf0WMtfG.mjs → form-DW8rU7jO.mjs} +6 -6
- package/dist/client/{headerSection-Bqdr3JWp.mjs → headerSection-CkIhsoNm.mjs} +9 -9
- package/dist/client/hooks.mjs +1289 -380
- package/dist/client/{locationMap-BVvPou4O.mjs → locationMap-D4O8wbli.mjs} +4 -4
- package/dist/client/{media-47fcnhzD.mjs → media-C5K_0xPd.mjs} +2 -2
- package/dist/client/{newsletterForm-Cx-1dnic.mjs → newsletterForm-B7IxSPuz.mjs} +5 -5
- package/dist/client/{productDetail-DaUMaJYk.mjs → productDetail-Bqxpwy5N.mjs} +3 -3
- package/dist/client/{productList-BKQlWEKE.mjs → productList-u9Lz8V15.mjs} +3 -3
- package/dist/client/{propsDecoder-DO5iXphQ.mjs → propsDecoder-Bf1jucUp.mjs} +17333 -14489
- package/dist/client/rendering/client.mjs +58216 -55133
- package/dist/client/rendering/islands.mjs +19 -19
- package/dist/client/rendering.mjs +9099 -5636
- package/dist/client/{routeIslandApiConfig-BNm0Z3-g.mjs → routeIslandApiConfig-BgP-aPMl.mjs} +1 -1
- package/dist/client/{shop-D7ytcFBC.mjs → shop-B_eykR-_.mjs} +16 -14
- package/dist/client/{shop-commerce-D68-hHy2.mjs → shop-commerce-CT0APkFV.mjs} +9 -9
- package/dist/client/{shop-commerce-store-Cu7X2lyu.mjs → shop-commerce-store-DcvZxdEK.mjs} +1 -1
- package/dist/client/{shopShared-D12rxE69.mjs → shopShared-BVJOiUiJ.mjs} +5 -5
- package/dist/client/themePortalRoot-DS92SRVZ.mjs +47 -0
- package/dist/client/{TerminalPanel-DOTSUCO0.mjs → useDiscountCodeUi-DPmYDunz.mjs} +60 -77
- package/dist/client/{useEventPagination-jgKa67KV.mjs → useEventPagination-8-U55vH5.mjs} +7 -8
- package/dist/preview-next/before-render.mjs +7 -0
- package/dist/preview-next/client/runtime.mjs +3 -3
- package/dist/preview-next/keepAlive.mjs +7 -0
- package/dist/preview-next/middleware.mjs +7 -0
- package/dist/{sdk-runtime-4cCWO_3i.mjs → sdk-runtime-C5jPdSrk.mjs} +1 -1
- package/dist/server/components.mjs +3138 -1373
- package/dist/server/config-validation.mjs +1395 -486
- package/dist/server/config.mjs +1395 -486
- package/dist/server/data.mjs +1289 -380
- package/dist/server/index.mjs +8 -1
- package/dist/server/next.mjs +3362 -1538
- package/dist/server/page-converter.mjs +1357 -453
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +2335 -1044
- package/dist/server/rendering.mjs +3152 -1370
- package/dist/server/routing.mjs +1437 -490
- package/dist/server/server.mjs +1297 -381
- package/dist/server/theme-bridge.mjs +1135 -795
- package/dist/{spinner-tSdG9YvG.mjs → spinner-B-ab2rJp.mjs} +1 -1
- package/dist/styles/index.css +1088 -721
- package/package.json +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/OrderSummary.d.ts +0 -15
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.d.ts +0 -22
- package/dist/_dts/blocks/src/system/runtime/shared/components/SelectableOptionCard.d.ts +0 -30
- package/dist/client/BookingMailingListNote-DlDSs5Vm.mjs +0 -567
- package/dist/client/pricing-CMD0kADd.mjs +0 -314
- package/dist/client/result-DRW7JWXz.mjs +0 -30
- package/dist/client/scrollToBlock-C86BYkyV.mjs +0 -17
- package/dist/client/themePortalRoot-AGs4cE7t.mjs +0 -30
- package/dist/spinner-BL3kW9Uh.mjs +0 -803
package/dist/server/server.mjs
CHANGED
|
@@ -1975,6 +1975,29 @@ function canonicalEventPricingDisplay(pricing) {
|
|
|
1975
1975
|
default: return assertNever$6(pricing);
|
|
1976
1976
|
}
|
|
1977
1977
|
}
|
|
1978
|
+
/**
|
|
1979
|
+
* The single renderer for a precomputed booking price `display` ADT. This is
|
|
1980
|
+
* the one place booking price variants map to user-facing strings — every call
|
|
1981
|
+
* site (booking entry, events calendar, event/course details, listings, portal)
|
|
1982
|
+
* should route through here so labels never drift. Adding a variant to the ADT
|
|
1983
|
+
* breaks compilation here (via `assertNever`) until it is handled.
|
|
1984
|
+
*/
|
|
1985
|
+
function formatBookingPriceDisplay(display, options = {}) {
|
|
1986
|
+
switch (display.kind) {
|
|
1987
|
+
case "free": return "Free";
|
|
1988
|
+
case "exact": return formatCurrencyAmount(display.amount, display.currency, options);
|
|
1989
|
+
case "from": return `From ${formatCurrencyAmount(display.amount, display.currency, options)}`;
|
|
1990
|
+
case "range": return `${formatCurrencyAmount(display.minAmount, display.currency, options)} - ${formatCurrencyAmount(display.maxAmount, display.currency, options)}`;
|
|
1991
|
+
case "mixed": return display.paidToAmount > display.paidFromAmount ? `Free / ${formatCurrencyAmount(display.paidFromAmount, display.currency, options)} - ${formatCurrencyAmount(display.paidToAmount, display.currency, options)}` : `Free / ${formatCurrencyAmount(display.paidFromAmount, display.currency, options)}`;
|
|
1992
|
+
case "unavailable": return "Pricing unavailable";
|
|
1993
|
+
case "external": return display.label;
|
|
1994
|
+
default: return assertNever$6(display);
|
|
1995
|
+
}
|
|
1996
|
+
}
|
|
1997
|
+
/** Render an event's price directly from its pricing value. */
|
|
1998
|
+
function formatEventPricing(pricing, options = {}) {
|
|
1999
|
+
return formatBookingPriceDisplay(publicEventPricingDisplay(pricing), options);
|
|
2000
|
+
}
|
|
1978
2001
|
//#endregion
|
|
1979
2002
|
//#region ../core/src/event-page-surface-subject.ts
|
|
1980
2003
|
function createEventSeriesPageSurfaceSubject(eventSeriesId, bookingScope, eventDestinationMode) {
|
|
@@ -2118,6 +2141,7 @@ function parseBookingTimeZone(timeZone) {
|
|
|
2118
2141
|
}
|
|
2119
2142
|
//#endregion
|
|
2120
2143
|
//#region ../core/src/booking-date-time.ts
|
|
2144
|
+
const DEFAULT_LOCALE = "en-US";
|
|
2121
2145
|
const FALLBACK_TIMEZONE = "UTC";
|
|
2122
2146
|
const START_OF_DAY = {
|
|
2123
2147
|
hour: 0,
|
|
@@ -2240,6 +2264,34 @@ function toScheduledBookingDateTime(input) {
|
|
|
2240
2264
|
if (result.ok) return result.value;
|
|
2241
2265
|
throw new Error(formatParseError(result));
|
|
2242
2266
|
}
|
|
2267
|
+
function formatBookingInstant(isoString, options) {
|
|
2268
|
+
const date = new Date(isoString);
|
|
2269
|
+
if (Number.isNaN(date.getTime())) return isoString;
|
|
2270
|
+
return getCachedDateTimeFormatter(options.locale ?? DEFAULT_LOCALE, getSafeTimeZone(options.timeZone), options.format).format(date);
|
|
2271
|
+
}
|
|
2272
|
+
function formatBookingDate(input, format = {
|
|
2273
|
+
weekday: "long",
|
|
2274
|
+
year: "numeric",
|
|
2275
|
+
month: "long",
|
|
2276
|
+
day: "numeric"
|
|
2277
|
+
}) {
|
|
2278
|
+
return formatBookingInstant(input.startsAt, {
|
|
2279
|
+
locale: input.locale,
|
|
2280
|
+
timeZone: input.timeZone,
|
|
2281
|
+
format
|
|
2282
|
+
});
|
|
2283
|
+
}
|
|
2284
|
+
function formatBookingTime(input, format = {
|
|
2285
|
+
hour: "numeric",
|
|
2286
|
+
minute: "2-digit",
|
|
2287
|
+
hour12: true
|
|
2288
|
+
}) {
|
|
2289
|
+
return formatBookingInstant(input.startsAt, {
|
|
2290
|
+
locale: input.locale,
|
|
2291
|
+
timeZone: input.timeZone,
|
|
2292
|
+
format
|
|
2293
|
+
});
|
|
2294
|
+
}
|
|
2243
2295
|
function getBookingLocalDateKey(input) {
|
|
2244
2296
|
return formatDateKey$1(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
|
|
2245
2297
|
}
|
|
@@ -2501,6 +2553,14 @@ function formError(field) {
|
|
|
2501
2553
|
}
|
|
2502
2554
|
//#endregion
|
|
2503
2555
|
//#region ../core/src/mailing-list-targeting.ts
|
|
2556
|
+
const DEFAULT_MAILING_LIST_TARGETING = { mode: "default" };
|
|
2557
|
+
function mailingListTargetingChoiceIds(targeting) {
|
|
2558
|
+
switch (targeting.provider) {
|
|
2559
|
+
case "native": return targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
|
|
2560
|
+
case "brevo": return targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
|
|
2561
|
+
case "mailchimp": return targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2504
2564
|
function planMailingListChoicePresentation(targeting) {
|
|
2505
2565
|
if (targeting.mode === "default" || targeting.selection.tag === "fixed") return { tag: "hidden" };
|
|
2506
2566
|
switch (targeting.provider) {
|
|
@@ -2540,6 +2600,103 @@ function planMailingListChoicePresentation(targeting) {
|
|
|
2540
2600
|
}
|
|
2541
2601
|
}
|
|
2542
2602
|
//#endregion
|
|
2603
|
+
//#region ../core/src/mailing-list-targeting-availability.ts
|
|
2604
|
+
function resolveMailingListDefaultDestination(provider) {
|
|
2605
|
+
switch (provider.provider) {
|
|
2606
|
+
case "native": return provider.topics.find((item) => item.id === provider.defaultTopicId) ?? null;
|
|
2607
|
+
case "brevo": return provider.lists.find((item) => item.id === provider.defaultListId) ?? null;
|
|
2608
|
+
case "mailchimp": return provider.audiences.find((item) => item.id === provider.defaultAudienceId) ?? null;
|
|
2609
|
+
}
|
|
2610
|
+
}
|
|
2611
|
+
function assessMailingListTargeting(context, targeting) {
|
|
2612
|
+
if (context?.tag !== "configured") return {
|
|
2613
|
+
tag: "unavailable",
|
|
2614
|
+
reason: "setup_missing",
|
|
2615
|
+
targeting
|
|
2616
|
+
};
|
|
2617
|
+
const catalog = context.provider;
|
|
2618
|
+
if (targeting.mode === "custom") return assessCustomTargeting(catalog, targeting);
|
|
2619
|
+
const destination = resolveMailingListDefaultDestination(catalog);
|
|
2620
|
+
return destination === null ? {
|
|
2621
|
+
tag: "unavailable",
|
|
2622
|
+
reason: "default_missing",
|
|
2623
|
+
targeting
|
|
2624
|
+
} : {
|
|
2625
|
+
tag: "available",
|
|
2626
|
+
value: {
|
|
2627
|
+
mode: "default",
|
|
2628
|
+
targeting,
|
|
2629
|
+
provider: catalog.provider,
|
|
2630
|
+
destination
|
|
2631
|
+
}
|
|
2632
|
+
};
|
|
2633
|
+
}
|
|
2634
|
+
function assessCustomTargeting(catalog, targeting) {
|
|
2635
|
+
switch (targeting.provider) {
|
|
2636
|
+
case "native": return catalog.provider === "native" ? assessMatchedChoices({
|
|
2637
|
+
provider: "native",
|
|
2638
|
+
catalog,
|
|
2639
|
+
targeting
|
|
2640
|
+
}, catalog.topics) : {
|
|
2641
|
+
tag: "unavailable",
|
|
2642
|
+
reason: "provider_mismatch",
|
|
2643
|
+
targeting
|
|
2644
|
+
};
|
|
2645
|
+
case "brevo": return catalog.provider === "brevo" ? assessMatchedChoices({
|
|
2646
|
+
provider: "brevo",
|
|
2647
|
+
catalog,
|
|
2648
|
+
targeting
|
|
2649
|
+
}, catalog.lists) : {
|
|
2650
|
+
tag: "unavailable",
|
|
2651
|
+
reason: "provider_mismatch",
|
|
2652
|
+
targeting
|
|
2653
|
+
};
|
|
2654
|
+
case "mailchimp": {
|
|
2655
|
+
if (catalog.provider !== "mailchimp") return {
|
|
2656
|
+
tag: "unavailable",
|
|
2657
|
+
reason: "provider_mismatch",
|
|
2658
|
+
targeting
|
|
2659
|
+
};
|
|
2660
|
+
const audience = catalog.audiences.find((item) => item.id === targeting.audienceId);
|
|
2661
|
+
return audience === void 0 ? {
|
|
2662
|
+
tag: "unavailable",
|
|
2663
|
+
reason: "audience_missing",
|
|
2664
|
+
value: {
|
|
2665
|
+
mode: "custom",
|
|
2666
|
+
provider: "mailchimp",
|
|
2667
|
+
catalog,
|
|
2668
|
+
targeting
|
|
2669
|
+
}
|
|
2670
|
+
} : assessMatchedChoices({
|
|
2671
|
+
provider: "mailchimp",
|
|
2672
|
+
catalog,
|
|
2673
|
+
targeting,
|
|
2674
|
+
audience
|
|
2675
|
+
}, audience.interests);
|
|
2676
|
+
}
|
|
2677
|
+
}
|
|
2678
|
+
}
|
|
2679
|
+
function assessMatchedChoices(matched, choices) {
|
|
2680
|
+
const selected = new Set(mailingListTargetingChoiceIds(matched.targeting));
|
|
2681
|
+
const available = new Set(choices.map((item) => item.id));
|
|
2682
|
+
const missingIds = [...selected].filter((id) => !available.has(id));
|
|
2683
|
+
const value = {
|
|
2684
|
+
mode: "custom",
|
|
2685
|
+
...matched,
|
|
2686
|
+
choices,
|
|
2687
|
+
selectedChoices: choices.filter((item) => selected.has(item.id))
|
|
2688
|
+
};
|
|
2689
|
+
return missingIds.length > 0 ? {
|
|
2690
|
+
tag: "unavailable",
|
|
2691
|
+
reason: "choices_missing",
|
|
2692
|
+
missingIds,
|
|
2693
|
+
value
|
|
2694
|
+
} : {
|
|
2695
|
+
tag: "available",
|
|
2696
|
+
value
|
|
2697
|
+
};
|
|
2698
|
+
}
|
|
2699
|
+
//#endregion
|
|
2543
2700
|
//#region ../core/src/mailing-list-runtime.ts
|
|
2544
2701
|
function parseMailingListRuntimeContext(value) {
|
|
2545
2702
|
if (!isRecord$15(value)) return invalidRuntimeContext();
|
|
@@ -2604,57 +2761,47 @@ function parseBrevoRuntimeProvider(value) {
|
|
|
2604
2761
|
function parseMailchimpRuntimeProvider(value) {
|
|
2605
2762
|
if (!Array.isArray(value.audiences)) return null;
|
|
2606
2763
|
const defaultAudienceId = parseMailchimpAudienceId(value.defaultAudienceId);
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
for (const audience of value.audiences) {
|
|
2610
|
-
if (!isRecord$15(audience)) return null;
|
|
2611
|
-
const id = parseMailchimpAudienceId(audience.id);
|
|
2612
|
-
const name = parseName(audience.name);
|
|
2613
|
-
if (id === null || name === null || !Array.isArray(audience.interests)) return null;
|
|
2614
|
-
const interests = parseMailchimpInterests(audience.interests);
|
|
2615
|
-
if (interests === null) return null;
|
|
2616
|
-
audiences.push({
|
|
2617
|
-
id,
|
|
2618
|
-
name,
|
|
2619
|
-
interests
|
|
2620
|
-
});
|
|
2621
|
-
}
|
|
2622
|
-
return {
|
|
2764
|
+
const audiences = Array.from(value.audiences, parseMailchimpAudience);
|
|
2765
|
+
return defaultAudienceId !== null && audiences.every((audience) => audience !== null) ? {
|
|
2623
2766
|
provider: "mailchimp",
|
|
2624
2767
|
defaultAudienceId,
|
|
2625
2768
|
audiences
|
|
2626
|
-
};
|
|
2769
|
+
} : null;
|
|
2627
2770
|
}
|
|
2628
|
-
function
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
interests
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2771
|
+
function parseMailchimpAudience(value) {
|
|
2772
|
+
if (!isRecord$15(value) || !Array.isArray(value.interests)) return null;
|
|
2773
|
+
const id = parseMailchimpAudienceId(value.id);
|
|
2774
|
+
const name = parseName(value.name);
|
|
2775
|
+
const interests = Array.from(value.interests, parseMailchimpInterest);
|
|
2776
|
+
return id !== null && name !== null && interests.every((interest) => interest !== null) ? {
|
|
2777
|
+
id,
|
|
2778
|
+
name,
|
|
2779
|
+
interests
|
|
2780
|
+
} : null;
|
|
2781
|
+
}
|
|
2782
|
+
function parseMailchimpInterest(value) {
|
|
2783
|
+
if (!isRecord$15(value)) return null;
|
|
2784
|
+
const id = parseMailchimpInterestId(value.id);
|
|
2785
|
+
const name = parseName(value.name);
|
|
2786
|
+
const categoryName = parseName(value.categoryName);
|
|
2787
|
+
return id !== null && name !== null && categoryName !== null ? {
|
|
2788
|
+
id,
|
|
2789
|
+
name,
|
|
2790
|
+
categoryName
|
|
2791
|
+
} : null;
|
|
2643
2792
|
}
|
|
2644
2793
|
function parseNamedItems(value, parseId) {
|
|
2645
2794
|
if (!Array.isArray(value)) return null;
|
|
2646
|
-
const items =
|
|
2647
|
-
for (const item of value) {
|
|
2795
|
+
const items = Array.from(value, (item) => {
|
|
2648
2796
|
if (!isRecord$15(item)) return null;
|
|
2649
2797
|
const id = parseId(item.id);
|
|
2650
2798
|
const name = parseName(item.name);
|
|
2651
|
-
|
|
2652
|
-
items.push({
|
|
2799
|
+
return id !== null && name !== null ? {
|
|
2653
2800
|
id,
|
|
2654
2801
|
name
|
|
2655
|
-
}
|
|
2656
|
-
}
|
|
2657
|
-
return items;
|
|
2802
|
+
} : null;
|
|
2803
|
+
});
|
|
2804
|
+
return items.every((item) => item !== null) ? items : null;
|
|
2658
2805
|
}
|
|
2659
2806
|
function parseName(value) {
|
|
2660
2807
|
if (typeof value !== "string") return null;
|
|
@@ -2670,6 +2817,7 @@ function invalidRuntimeContext() {
|
|
|
2670
2817
|
//#endregion
|
|
2671
2818
|
//#region ../core/src/mailing-list-targeting-parser.ts
|
|
2672
2819
|
function parseMailingListPlacementTargeting(value) {
|
|
2820
|
+
if (value == null) return ok$1(DEFAULT_MAILING_LIST_TARGETING);
|
|
2673
2821
|
if (!isRecord$14(value)) return targetingError("shape");
|
|
2674
2822
|
if (value.mode === "default") return ok$1({ mode: "default" });
|
|
2675
2823
|
if (value.mode !== "custom") return targetingError("mode");
|
|
@@ -2768,14 +2916,11 @@ function parseNonEmptyUniqueIds(value, parseId) {
|
|
|
2768
2916
|
}
|
|
2769
2917
|
function parseUniqueIds(value, parseId) {
|
|
2770
2918
|
if (!Array.isArray(value)) return targetingError("targets");
|
|
2771
|
-
|
|
2772
|
-
|
|
2919
|
+
return Array.from(value).reduce((parsed, item) => {
|
|
2920
|
+
if (!parsed.ok) return parsed;
|
|
2773
2921
|
const id = parseId(item);
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
parsed.push(id);
|
|
2777
|
-
}
|
|
2778
|
-
return ok$1(parsed);
|
|
2922
|
+
return id === null ? targetingError("targets") : parsed.value.includes(id) ? targetingError("duplicate_target") : ok$1([...parsed.value, id]);
|
|
2923
|
+
}, ok$1([]));
|
|
2779
2924
|
}
|
|
2780
2925
|
function isRecord$14(value) {
|
|
2781
2926
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -3207,6 +3352,45 @@ function resolveSiteVerticalBookingConfig(rawConfig) {
|
|
|
3207
3352
|
};
|
|
3208
3353
|
}
|
|
3209
3354
|
//#endregion
|
|
3355
|
+
//#region ../core/src/event-preset-vocabulary.ts
|
|
3356
|
+
const EVENT_PRESET_VOCABULARY = {
|
|
3357
|
+
event: {
|
|
3358
|
+
label: "Event",
|
|
3359
|
+
pluralLabel: "Events",
|
|
3360
|
+
description: "Any event, repeating or manually dated, that does not fit the other categories."
|
|
3361
|
+
},
|
|
3362
|
+
class: {
|
|
3363
|
+
label: "Class",
|
|
3364
|
+
pluralLabel: "Classes",
|
|
3365
|
+
description: "Regular scheduled classes and group sessions."
|
|
3366
|
+
},
|
|
3367
|
+
course: {
|
|
3368
|
+
label: "Course",
|
|
3369
|
+
pluralLabel: "Courses",
|
|
3370
|
+
description: "A fixed set of dates that people book together."
|
|
3371
|
+
},
|
|
3372
|
+
term: {
|
|
3373
|
+
label: "Term",
|
|
3374
|
+
pluralLabel: "Terms",
|
|
3375
|
+
description: "A fixed term of sessions that people book together."
|
|
3376
|
+
},
|
|
3377
|
+
workshop: {
|
|
3378
|
+
label: "Workshop",
|
|
3379
|
+
pluralLabel: "Workshops",
|
|
3380
|
+
description: "One-off workshops, day sessions, or special events."
|
|
3381
|
+
},
|
|
3382
|
+
retreat: {
|
|
3383
|
+
label: "Retreat",
|
|
3384
|
+
pluralLabel: "Retreats",
|
|
3385
|
+
description: "Multi-day or residential immersive experiences."
|
|
3386
|
+
},
|
|
3387
|
+
performance: {
|
|
3388
|
+
label: "Performance",
|
|
3389
|
+
pluralLabel: "Performances",
|
|
3390
|
+
description: "Audience-facing shows, concerts, recitals, or showcases."
|
|
3391
|
+
}
|
|
3392
|
+
};
|
|
3393
|
+
//#endregion
|
|
3210
3394
|
//#region ../api/src/publicEventEndpointDefinitions.ts
|
|
3211
3395
|
const PUBLIC_EVENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
|
|
3212
3396
|
checkPublicEventRegistrationNextStep: {
|
|
@@ -9457,6 +9641,13 @@ const API_ENDPOINTS$1 = {
|
|
|
9457
9641
|
auth: "public",
|
|
9458
9642
|
responseKind: "json"
|
|
9459
9643
|
},
|
|
9644
|
+
demoClaimReadiness: {
|
|
9645
|
+
path: "/demo/claims/{claimId}/readiness",
|
|
9646
|
+
method: "GET",
|
|
9647
|
+
auth: "user",
|
|
9648
|
+
responseKind: "json",
|
|
9649
|
+
errors: []
|
|
9650
|
+
},
|
|
9460
9651
|
demoClaimMagicLink: {
|
|
9461
9652
|
path: "/demo/auth/send-magic-link",
|
|
9462
9653
|
method: "POST",
|
|
@@ -10362,7 +10553,7 @@ var SimpleCache = class {
|
|
|
10362
10553
|
* 1. This constant
|
|
10363
10554
|
* 2. The "version" field in package.json
|
|
10364
10555
|
*/
|
|
10365
|
-
const SDK_VERSION = "0.
|
|
10556
|
+
const SDK_VERSION = "0.152.0";
|
|
10366
10557
|
//#endregion
|
|
10367
10558
|
//#region src/client/error.ts
|
|
10368
10559
|
let _Symbol$for;
|
|
@@ -40015,6 +40206,15 @@ const formBlockDefinition = {
|
|
|
40015
40206
|
runtime: formBlockRuntime
|
|
40016
40207
|
};
|
|
40017
40208
|
//#endregion
|
|
40209
|
+
//#region ../blocks/src/system/helpers/normalizeMailingListBlockContent.ts
|
|
40210
|
+
/** Fill the declared default without admitting or rewriting invalid custom settings. */
|
|
40211
|
+
function normalizeMailingListBlockContent(record) {
|
|
40212
|
+
return record.targeting == null ? {
|
|
40213
|
+
...record,
|
|
40214
|
+
targeting: DEFAULT_MAILING_LIST_TARGETING
|
|
40215
|
+
} : record;
|
|
40216
|
+
}
|
|
40217
|
+
//#endregion
|
|
40018
40218
|
//#region ../blocks/src/system/blocks/contact-newsletter.ts
|
|
40019
40219
|
const contactNewsletterLayout = styledSection({
|
|
40020
40220
|
children: sectionContainer([el("div", { className: "contact-newsletter-grid" }, [el("div", { className: "contact-newsletter-column contact-newsletter-contact" }, [el("div", { className: "contact-newsletter-copy" }, [text({
|
|
@@ -40178,6 +40378,10 @@ const contactNewsletterBlockDefinition = {
|
|
|
40178
40378
|
],
|
|
40179
40379
|
icon: "MailPlus"
|
|
40180
40380
|
}),
|
|
40381
|
+
contentNormalizer: {
|
|
40382
|
+
fieldIds: ["targeting"],
|
|
40383
|
+
normalize: normalizeMailingListBlockContent
|
|
40384
|
+
},
|
|
40181
40385
|
dataSchemas: { form: formDataSchema.optional() },
|
|
40182
40386
|
dataLoaders: { form: {
|
|
40183
40387
|
endpoint: "getPublicFormById",
|
|
@@ -43866,6 +44070,14 @@ bookingPaymentOptionSchemas.flexibleBalanceConfig;
|
|
|
43866
44070
|
bookingPaymentOptionSchemas.paymentCollectionOption;
|
|
43867
44071
|
const bookingPaymentTermsSchema = bookingPaymentOptionSchemas.paymentTerms;
|
|
43868
44072
|
bookingPaymentOptionSchemas.paymentOptionsChoice;
|
|
44073
|
+
z.strictObject({
|
|
44074
|
+
currency: z.string().trim().length(3),
|
|
44075
|
+
totalCents: nonNegativeIntegerSchema,
|
|
44076
|
+
dueNowCents: nonNegativeIntegerSchema,
|
|
44077
|
+
laterPaymentAmountsCents: z.array(nonNegativeIntegerSchema),
|
|
44078
|
+
paymentOption: z.union([createBookingPaymentOptionSchemas("strict").paymentCollectionOption, z.strictObject({ kind: z.literal("not_required") })]),
|
|
44079
|
+
promisedDiscountId: z.string().min(1).nullable().optional()
|
|
44080
|
+
});
|
|
43869
44081
|
//#endregion
|
|
43870
44082
|
//#region ../blocks/src/system/blocks/shared/bookingPaymentTerms.ts
|
|
43871
44083
|
const blockBookingPaymentTermsSchema = bookingPaymentTermsSchema;
|
|
@@ -44106,6 +44318,10 @@ const publicEventBaseSchema = z.object({
|
|
|
44106
44318
|
eventDestinationMode: eventDestinationModeSchema.optional(),
|
|
44107
44319
|
scheduleScope: eventScheduleScopeSchema$2.optional(),
|
|
44108
44320
|
recurrence: publicEventRecurrenceSchema.optional(),
|
|
44321
|
+
scheduleSummary: z.object({
|
|
44322
|
+
recurrenceDescription: z.string(),
|
|
44323
|
+
startTime: z.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/).nullable()
|
|
44324
|
+
}).nullable().optional(),
|
|
44109
44325
|
id: z.string(),
|
|
44110
44326
|
occurrenceId: z.string(),
|
|
44111
44327
|
seriesId: z.string(),
|
|
@@ -44516,68 +44732,267 @@ const occurrenceContextSchema = z.object({
|
|
|
44516
44732
|
overrides: z.record(z.string(), z.unknown()).nullable().optional()
|
|
44517
44733
|
}).nullable();
|
|
44518
44734
|
//#endregion
|
|
44519
|
-
//#region ../blocks/src/system/runtime/
|
|
44520
|
-
|
|
44521
|
-
|
|
44522
|
-
|
|
44523
|
-
|
|
44524
|
-
|
|
44525
|
-
|
|
44526
|
-
|
|
44527
|
-
|
|
44528
|
-
|
|
44529
|
-
|
|
44530
|
-
|
|
44531
|
-
|
|
44532
|
-
"invalidEventOfferingCatalogue"
|
|
44533
|
-
])
|
|
44534
|
-
});
|
|
44535
|
-
const eventRegistrationPageSurfaceSubjectSchema = z.unknown().transform((value, ctx) => {
|
|
44536
|
-
const unsupported = unsupportedEventRegistrationPageSurfaceSubjectSchema.safeParse(value);
|
|
44537
|
-
if (unsupported.success) return unsupported.data;
|
|
44538
|
-
const parsed = parseEventPageSurfaceSubject(value);
|
|
44539
|
-
if (parsed.ok) return parsed.value;
|
|
44540
|
-
ctx.addIssue({
|
|
44541
|
-
code: z.ZodIssueCode.custom,
|
|
44542
|
-
message: `Invalid event page-surface subject (${parsed.error.kind})`
|
|
44543
|
-
});
|
|
44544
|
-
return z.NEVER;
|
|
44545
|
-
});
|
|
44546
|
-
function resolveEventRegistrationScope(context) {
|
|
44547
|
-
const occurrenceSeriesId = context.occurrenceContext?.seriesId;
|
|
44548
|
-
if (occurrenceSeriesId) return {
|
|
44549
|
-
kind: "occurrenceSeries",
|
|
44550
|
-
seriesId: occurrenceSeriesId
|
|
44735
|
+
//#region ../blocks/src/system/runtime/nodes/events/domain/capacity.ts
|
|
44736
|
+
/**
|
|
44737
|
+
* Compute remaining spots for an event from `availableSpots` with a fallback
|
|
44738
|
+
* to `capacity - registeredCount`. Returns `{ available: null, isFull: false }`
|
|
44739
|
+
* for uncapped events so call sites can render no capacity indicator at all.
|
|
44740
|
+
*
|
|
44741
|
+
* The single source of truth for capacity math across event cards, agenda
|
|
44742
|
+
* rows, and timetable cells — keep wording variations in the call sites.
|
|
44743
|
+
*/
|
|
44744
|
+
function getEventAvailability(event) {
|
|
44745
|
+
if (event.capacity == null) return {
|
|
44746
|
+
available: null,
|
|
44747
|
+
isFull: false
|
|
44551
44748
|
};
|
|
44552
|
-
|
|
44553
|
-
|
|
44554
|
-
|
|
44749
|
+
const available = event.availableSpots ?? event.capacity - event.registeredCount;
|
|
44750
|
+
if (available <= 0) return {
|
|
44751
|
+
available: 0,
|
|
44752
|
+
isFull: true
|
|
44555
44753
|
};
|
|
44556
|
-
|
|
44557
|
-
|
|
44558
|
-
|
|
44559
|
-
seriesIds: context.subject.catalogueEventSeriesIds
|
|
44754
|
+
return {
|
|
44755
|
+
available,
|
|
44756
|
+
isFull: false
|
|
44560
44757
|
};
|
|
44561
|
-
|
|
44562
|
-
|
|
44563
|
-
|
|
44758
|
+
}
|
|
44759
|
+
/**
|
|
44760
|
+
* Pick the capacity row a booking decision should read: the selected
|
|
44761
|
+
* attendance mode's availability when the visitor has chosen one and the
|
|
44762
|
+
* event publishes it, otherwise the event-level aggregate.
|
|
44763
|
+
*
|
|
44764
|
+
* The mode row is used wholesale. A mode with `capacity: null` on a capped
|
|
44765
|
+
* event is uncapped *by design*: the registration write path applies the
|
|
44766
|
+
* same rule via `getEffectiveOccurrenceCapacityForAttendanceMode`, so falling
|
|
44767
|
+
* back to the event's `availableSpots` here would block bookings the server
|
|
44768
|
+
* accepts. (Waitlist claims are still occurrence-scoped; see issue 1377.)
|
|
44769
|
+
*/
|
|
44770
|
+
function selectEventCapacitySource(event, attendanceMode) {
|
|
44771
|
+
if (!attendanceMode) return event;
|
|
44772
|
+
return (event.attendanceModes ?? []).find((mode) => mode.mode === attendanceMode) ?? event;
|
|
44773
|
+
}
|
|
44774
|
+
/**
|
|
44775
|
+
* Whether the visitor's next step is the waitlist: the source is full *and*
|
|
44776
|
+
* a waitlist is open. The one place this is decided — cards, rows, the
|
|
44777
|
+
* wizard's steps and its action bar all route through here so they agree,
|
|
44778
|
+
* including for producers that omit `availableSpots` and rely on the
|
|
44779
|
+
* `capacity - registeredCount` fallback.
|
|
44780
|
+
*/
|
|
44781
|
+
function canJoinEventWaitlist(event, options) {
|
|
44782
|
+
const source = selectEventCapacitySource(event, options?.attendanceMode);
|
|
44783
|
+
return getEventAvailability(source).isFull && source.waitlistEnabled === true;
|
|
44784
|
+
}
|
|
44785
|
+
/**
|
|
44786
|
+
* Remaining places at or below which an event reads as scarce and the exact
|
|
44787
|
+
* count is worth showing. Above it, no number is shown at all: "147 places
|
|
44788
|
+
* left" is not something a visitor acts on, and it is the figure most likely
|
|
44789
|
+
* to be stale on a cached page.
|
|
44790
|
+
*
|
|
44791
|
+
* max( min(3, ceil(capacity * 0.25)), ceil(capacity * 0.05) )
|
|
44792
|
+
*
|
|
44793
|
+
* The 25% arm stops small groups shouting early (3 of 4 is not urgency); the
|
|
44794
|
+
* 5% floor stops large events staying silent until three remain.
|
|
44795
|
+
* capacity 4 -> 1, 12 -> 3, 40 -> 3, 100 -> 5, 200 -> 10.
|
|
44796
|
+
*/
|
|
44797
|
+
function lowCapacityThreshold(capacity) {
|
|
44798
|
+
return Math.max(Math.min(3, Math.ceil(capacity * .25)), Math.ceil(capacity * .05));
|
|
44799
|
+
}
|
|
44800
|
+
function getRemainingPlaces(source) {
|
|
44801
|
+
const { available, isFull } = getEventAvailability(source);
|
|
44802
|
+
if (available === null || source.capacity === null) return { kind: "unlimited" };
|
|
44803
|
+
if (isFull) return {
|
|
44804
|
+
kind: "full",
|
|
44805
|
+
waitlist: canJoinEventWaitlist(source)
|
|
44564
44806
|
};
|
|
44565
|
-
|
|
44807
|
+
if (available <= lowCapacityThreshold(source.capacity)) return {
|
|
44808
|
+
kind: "low",
|
|
44809
|
+
remaining: available
|
|
44810
|
+
};
|
|
44811
|
+
return { kind: "open" };
|
|
44566
44812
|
}
|
|
44567
|
-
|
|
44568
|
-
|
|
44569
|
-
|
|
44570
|
-
|
|
44571
|
-
|
|
44572
|
-
|
|
44573
|
-
|
|
44574
|
-
|
|
44575
|
-
|
|
44576
|
-
case "
|
|
44577
|
-
case "
|
|
44813
|
+
/**
|
|
44814
|
+
* The one place a remaining-places count becomes text. Returns `null` when
|
|
44815
|
+
* nothing should be shown: uncapped events, and capped events above the
|
|
44816
|
+
* scarcity threshold. Surfaces that need their own full-state wording pass
|
|
44817
|
+
* it in rather than re-deriving the count.
|
|
44818
|
+
*/
|
|
44819
|
+
function formatRemainingPlaces(source, wording = {}) {
|
|
44820
|
+
const remaining = getRemainingPlaces(source);
|
|
44821
|
+
switch (remaining.kind) {
|
|
44822
|
+
case "unlimited":
|
|
44823
|
+
case "open": return null;
|
|
44824
|
+
case "low": return formatPlacesLeft(remaining.remaining, wording.compact === true);
|
|
44825
|
+
case "full": return remaining.waitlist ? wording.waitlist ?? "Waitlist" : wording.full ?? "Full";
|
|
44826
|
+
}
|
|
44827
|
+
}
|
|
44828
|
+
function formatPlacesLeft(count, compact) {
|
|
44829
|
+
if (compact) return `${count} left`;
|
|
44830
|
+
return count === 1 ? "1 place left" : `${count} places left`;
|
|
44831
|
+
}
|
|
44832
|
+
function formatTicketTypeRemaining(remainingCapacity) {
|
|
44833
|
+
if (remainingCapacity === null || remainingCapacity > 3) return null;
|
|
44834
|
+
if (remainingCapacity <= 0) return "None left for this ticket type";
|
|
44835
|
+
return `${formatPlacesLeft(remainingCapacity, false)} for this ticket type`;
|
|
44836
|
+
}
|
|
44837
|
+
/**
|
|
44838
|
+
* Which capacity figure wins when they disagree.
|
|
44839
|
+
*
|
|
44840
|
+
* For a hybrid event that publishes both attendance-mode rows, **the mode
|
|
44841
|
+
* rows are authoritative and the event-level aggregate is only a summary**.
|
|
44842
|
+
* The registration write path admits or refuses per mode
|
|
44843
|
+
* (`getEffectiveOccurrenceCapacityForAttendanceMode` on the server), so the
|
|
44844
|
+
* aggregate can read full while a mode still has room, and can read open
|
|
44845
|
+
* while the mode the visitor wants is full. Believing the aggregate on a
|
|
44846
|
+
* card is how a "places available" event turns into a dead end at step two.
|
|
44847
|
+
*
|
|
44848
|
+
* Everything else — single-mode events, events that publish no rows, and the
|
|
44849
|
+
* aggregate-only helpers {@link getEventAvailability} /
|
|
44850
|
+
* {@link getRemainingPlaces} that existing callers rely on — keeps reading
|
|
44851
|
+
* the aggregate, unchanged.
|
|
44852
|
+
*/
|
|
44853
|
+
function findHybridModeRows(event) {
|
|
44854
|
+
if (event.deliveryMode !== "hybrid") return null;
|
|
44855
|
+
const rows = event.attendanceModes ?? [];
|
|
44856
|
+
const inPerson = rows.find((row) => row.mode === "in_person");
|
|
44857
|
+
const online = rows.find((row) => row.mode === "online");
|
|
44858
|
+
return inPerson && online ? {
|
|
44859
|
+
inPerson,
|
|
44860
|
+
online
|
|
44861
|
+
} : null;
|
|
44862
|
+
}
|
|
44863
|
+
/** Openness rank; higher means more room. A full mode with a waitlist beats one without. */
|
|
44864
|
+
function remainingPlacesRank(remaining) {
|
|
44865
|
+
switch (remaining.kind) {
|
|
44866
|
+
case "unlimited": return 4;
|
|
44867
|
+
case "open": return 3;
|
|
44868
|
+
case "low": return 2;
|
|
44869
|
+
case "full": return remaining.waitlist ? 1 : 0;
|
|
44870
|
+
}
|
|
44871
|
+
}
|
|
44872
|
+
function isMoreOpen(candidate, than) {
|
|
44873
|
+
const rank = remainingPlacesRank(candidate);
|
|
44874
|
+
const otherRank = remainingPlacesRank(than);
|
|
44875
|
+
if (rank !== otherRank) return rank > otherRank;
|
|
44876
|
+
return candidate.kind === "low" && than.kind === "low" ? candidate.remaining > than.remaining : false;
|
|
44877
|
+
}
|
|
44878
|
+
/** True when `candidate` has less room left than `than`. */
|
|
44879
|
+
function isScarcer(candidate, than) {
|
|
44880
|
+
return isMoreOpen(than, candidate);
|
|
44881
|
+
}
|
|
44882
|
+
const ATTENDANCE_MODE_LABEL = {
|
|
44883
|
+
in_person: "In person",
|
|
44884
|
+
online: "Online"
|
|
44885
|
+
};
|
|
44886
|
+
/** Wording for a mode with room to spare, where the count is deliberately withheld. */
|
|
44887
|
+
const PLACES_AVAILABLE = "Places available";
|
|
44888
|
+
/**
|
|
44889
|
+
* The browse-surface label for an event's remaining places. Single-mode
|
|
44890
|
+
* events get exactly the aggregate label {@link formatRemainingPlaces}
|
|
44891
|
+
* produces, and so does a hybrid event whose two modes tell the same story.
|
|
44892
|
+
* When the modes differ, both sides are named: "available" on a card is a
|
|
44893
|
+
* promise the registration wizard would otherwise have to break.
|
|
44894
|
+
*
|
|
44895
|
+
* Hybrid examples, in person full with 3 online places left:
|
|
44896
|
+
* default -> "Online: 3 places left · In person: Full"
|
|
44897
|
+
* { full: 'Sold out' } -> "Online: 3 places left · In person: Sold out"
|
|
44898
|
+
* { compact: true } -> "Online: 3 left"
|
|
44899
|
+
*/
|
|
44900
|
+
function formatEventRemainingPlaces(event, wording = {}) {
|
|
44901
|
+
const rows = findHybridModeRows(event);
|
|
44902
|
+
if (!rows) return formatRemainingPlaces(event, wording);
|
|
44903
|
+
const inPerson = formatRemainingPlaces(rows.inPerson, wording);
|
|
44904
|
+
const online = formatRemainingPlaces(rows.online, wording);
|
|
44905
|
+
if (inPerson === online) return inPerson;
|
|
44906
|
+
if (wording.compact === true) return formatCompactHybridPlaces(rows, wording);
|
|
44907
|
+
return formatBothHybridSides(rows, {
|
|
44908
|
+
inPerson,
|
|
44909
|
+
online
|
|
44910
|
+
});
|
|
44911
|
+
}
|
|
44912
|
+
/**
|
|
44913
|
+
* Both sides, the one with room first: that is the half a visitor can act on,
|
|
44914
|
+
* and it should not arrive after a full stop's worth of bad news.
|
|
44915
|
+
*/
|
|
44916
|
+
function formatBothHybridSides(rows, labels) {
|
|
44917
|
+
return (isMoreOpen(getRemainingPlaces(rows.online), getRemainingPlaces(rows.inPerson)) ? [["online", labels.online], ["in_person", labels.inPerson]] : [["in_person", labels.inPerson], ["online", labels.online]]).map(([mode, label]) => namedModePlaces(mode, label)).join(" · ");
|
|
44918
|
+
}
|
|
44919
|
+
function namedModePlaces(mode, label) {
|
|
44920
|
+
return `${ATTENDANCE_MODE_LABEL[mode]}: ${label ?? PLACES_AVAILABLE}`;
|
|
44921
|
+
}
|
|
44922
|
+
/**
|
|
44923
|
+
* Pills and timetable cells have room for one short phrase, so they name the
|
|
44924
|
+
* single mode that carries news rather than listing both: the scarce side
|
|
44925
|
+
* when there is a count to show, and otherwise the side that has closed —
|
|
44926
|
+
* "In person: Full", never "Online only", which reads as a statement about
|
|
44927
|
+
* how the event is delivered rather than about its remaining places.
|
|
44928
|
+
*/
|
|
44929
|
+
function formatCompactHybridPlaces(rows, wording) {
|
|
44930
|
+
const inPerson = getRemainingPlaces(rows.inPerson);
|
|
44931
|
+
const online = getRemainingPlaces(rows.online);
|
|
44932
|
+
if (inPerson.kind === "full" && online.kind === "full") return formatRemainingPlaces(inPerson.waitlist ? rows.inPerson : rows.online, wording);
|
|
44933
|
+
if (inPerson.kind === "full" || online.kind === "full") {
|
|
44934
|
+
const fullSide = inPerson.kind === "full" ? "in_person" : "online";
|
|
44935
|
+
const openSide = inPerson.kind === "full" ? "online" : "in_person";
|
|
44936
|
+
const openLabel = formatRemainingPlaces(rowFor(rows, openSide), wording);
|
|
44937
|
+
return openLabel !== null ? namedModePlaces(openSide, openLabel) : namedModePlaces(fullSide, formatRemainingPlaces(rowFor(rows, fullSide), wording));
|
|
44578
44938
|
}
|
|
44939
|
+
const scarcerSide = isScarcer(online, inPerson) ? "online" : "in_person";
|
|
44940
|
+
return namedModePlaces(scarcerSide, formatRemainingPlaces(rowFor(rows, scarcerSide), wording));
|
|
44941
|
+
}
|
|
44942
|
+
function rowFor(rows, mode) {
|
|
44943
|
+
return mode === "online" ? rows.online : rows.inPerson;
|
|
44579
44944
|
}
|
|
44580
44945
|
//#endregion
|
|
44946
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationDisplay.ts
|
|
44947
|
+
const registrationDisplaySchema = z.object({
|
|
44948
|
+
venue: z.enum(["shown", "hidden"]),
|
|
44949
|
+
placesLeft: z.enum(["shown", "hidden"])
|
|
44950
|
+
});
|
|
44951
|
+
function resolveRegistrationDisplay(source) {
|
|
44952
|
+
return {
|
|
44953
|
+
venue: source.showVenue === false ? "hidden" : "shown",
|
|
44954
|
+
placesLeft: source.showCapacity === false ? "hidden" : "shown"
|
|
44955
|
+
};
|
|
44956
|
+
}
|
|
44957
|
+
/** Venue stays in domain data; views receive only the permitted presentation. */
|
|
44958
|
+
function shownVenue(event, display) {
|
|
44959
|
+
return display.venue === "shown" ? event.venue?.name ?? null : null;
|
|
44960
|
+
}
|
|
44961
|
+
/** Full/waitlist explanations remain visible even when optional counts are hidden. */
|
|
44962
|
+
function placesLeftLabel(source, display, wording = {}) {
|
|
44963
|
+
if ("kind" in source) return ticketPlacesLabel(source.remaining, display);
|
|
44964
|
+
if (source.deliveryMode === "hybrid" && source.attendanceModes?.length) return hybridPlacesLabel(source, display, wording);
|
|
44965
|
+
return capacityPlacesLabel(source, display, wording);
|
|
44966
|
+
}
|
|
44967
|
+
function capacityPlacesLabel(source, display, wording) {
|
|
44968
|
+
const remaining = getRemainingPlaces(source);
|
|
44969
|
+
if (display.placesLeft === "hidden" && remaining.kind !== "full") return null;
|
|
44970
|
+
switch (remaining.kind) {
|
|
44971
|
+
case "full": return formatRemainingPlaces(source, wording);
|
|
44972
|
+
case "low": return formatRemainingPlaces(source, wording);
|
|
44973
|
+
case "unlimited": return wording.unlimited ?? null;
|
|
44974
|
+
case "open": return wording.open ?? null;
|
|
44975
|
+
default: return assertNever$6(remaining);
|
|
44976
|
+
}
|
|
44977
|
+
}
|
|
44978
|
+
function hybridPlacesLabel(event, display, wording) {
|
|
44979
|
+
if (display.placesLeft === "shown") return formatEventRemainingPlaces(event, wording);
|
|
44980
|
+
return (event.attendanceModes ?? []).flatMap((mode) => {
|
|
44981
|
+
const label = placesLeftLabel(mode, display, wording);
|
|
44982
|
+
return label ? [`${mode.mode === "online" ? "Online" : "In person"}: ${label}`] : [];
|
|
44983
|
+
}).join(" · ") || null;
|
|
44984
|
+
}
|
|
44985
|
+
function ticketPlacesLabel(remaining, display) {
|
|
44986
|
+
if (remaining !== null && remaining > 0 && display.placesLeft === "hidden") return null;
|
|
44987
|
+
return formatTicketTypeRemaining(remaining);
|
|
44988
|
+
}
|
|
44989
|
+
//#endregion
|
|
44990
|
+
//#region ../blocks/src/system/runtime/api/readAuthority.ts
|
|
44991
|
+
const browserReadAuthoritySchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("published") }).strict(), z.object({
|
|
44992
|
+
kind: z.literal("preview"),
|
|
44993
|
+
token: z.string().min(1)
|
|
44994
|
+
}).strict()]);
|
|
44995
|
+
//#endregion
|
|
44581
44996
|
//#region ../calendar/src/grid.ts
|
|
44582
44997
|
const MONTH_NAMES = [
|
|
44583
44998
|
"January",
|
|
@@ -44664,6 +45079,11 @@ function buildCalendarViewport(input) {
|
|
|
44664
45079
|
//#endregion
|
|
44665
45080
|
//#region ../blocks/src/system/runtime/nodes/events/domain/dates.ts
|
|
44666
45081
|
/**
|
|
45082
|
+
* Date and time presentation for events: the single place an event's
|
|
45083
|
+
* timestamps become strings or date buckets. Calendar-grid primitives are
|
|
45084
|
+
* re-exported from @riverbankcms/calendar so block code has one import.
|
|
45085
|
+
*/
|
|
45086
|
+
/**
|
|
44667
45087
|
* The English locale a site's public dates are written in, read from the
|
|
44668
45088
|
* site's own time zone (Will, 2026-09-26: "date style from site time zone").
|
|
44669
45089
|
*
|
|
@@ -44683,6 +45103,28 @@ function eventDateLocale(siteTimeZone) {
|
|
|
44683
45103
|
if (siteTimeZone === "Pacific/Auckland" || siteTimeZone === "Pacific/Chatham") return "en-NZ";
|
|
44684
45104
|
return "en-US";
|
|
44685
45105
|
}
|
|
45106
|
+
function formatEventCompactDateRail(isoTimestamp, options, letterCase = "capitals") {
|
|
45107
|
+
const locale = options?.locale ?? "en-US";
|
|
45108
|
+
const dateTime = toScheduledBookingDateTime({
|
|
45109
|
+
startsAt: isoTimestamp,
|
|
45110
|
+
timeZone: toBookingTimeZone(options?.timeZone ?? "UTC"),
|
|
45111
|
+
locale
|
|
45112
|
+
});
|
|
45113
|
+
const cased = (value) => letterCase === "capitals" ? value.toLocaleUpperCase(locale) : value;
|
|
45114
|
+
const weekday = cased(formatBookingDate(dateTime, { weekday: "short" }));
|
|
45115
|
+
const month = cased(formatBookingDate(dateTime, { month: "short" }).slice(0, 3));
|
|
45116
|
+
return {
|
|
45117
|
+
weekday,
|
|
45118
|
+
day: formatBookingDate(dateTime, { day: "numeric" }),
|
|
45119
|
+
month,
|
|
45120
|
+
label: formatBookingDate(dateTime, {
|
|
45121
|
+
weekday: "long",
|
|
45122
|
+
year: "numeric",
|
|
45123
|
+
month: "long",
|
|
45124
|
+
day: "numeric"
|
|
45125
|
+
})
|
|
45126
|
+
};
|
|
45127
|
+
}
|
|
44686
45128
|
//#endregion
|
|
44687
45129
|
//#region ../blocks/src/system/runtime/nodes/events/domain/destination.ts
|
|
44688
45130
|
function isRecord$8(value) {
|
|
@@ -44702,6 +45144,15 @@ function resolveRuntimeEventDestination(event) {
|
|
|
44702
45144
|
};
|
|
44703
45145
|
}
|
|
44704
45146
|
//#endregion
|
|
45147
|
+
//#region ../blocks/src/system/runtime/nodes/events/domain/pricing.ts
|
|
45148
|
+
/**
|
|
45149
|
+
* Format an event's price directly from its pricing value (without the full
|
|
45150
|
+
* event). Same output as {@link formatEventPrice}.
|
|
45151
|
+
*/
|
|
45152
|
+
function formatEventPriceDisplay(pricing) {
|
|
45153
|
+
return formatEventPricing(pricing, { decimals: "auto" });
|
|
45154
|
+
}
|
|
45155
|
+
//#endregion
|
|
44705
45156
|
//#region ../blocks/src/system/runtime/nodes/events/domain/listWeek.ts
|
|
44706
45157
|
/** Civil weeks use the site zone, including weeks containing a clock change. */
|
|
44707
45158
|
function buildEventListWeek(anchor, startOfWeek, timeZone) {
|
|
@@ -44736,52 +45187,6 @@ function eventListWindowEvents(events, window) {
|
|
|
44736
45187
|
});
|
|
44737
45188
|
}
|
|
44738
45189
|
//#endregion
|
|
44739
|
-
//#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
|
|
44740
|
-
const previewStageSchema = z.enum(["preview", "published"]);
|
|
44741
|
-
const registrationButtonVariantSchema = blockButtonRoleSchema;
|
|
44742
|
-
const eventButtonVariantSchema = blockButtonRoleSchema;
|
|
44743
|
-
const eventLayoutSchema = z.enum(eventCalendarListLayoutValues);
|
|
44744
|
-
const eventCalendarDisplayModeSchema = z.enum(eventCalendarDisplayModeValues);
|
|
44745
|
-
const eventCalendarDefaultViewSchema = z.enum(eventCalendarDefaultViewValues);
|
|
44746
|
-
const columnOptionSchema = z.enum([
|
|
44747
|
-
"2",
|
|
44748
|
-
"3",
|
|
44749
|
-
"4"
|
|
44750
|
-
]);
|
|
44751
|
-
const weekStartSchema = z.enum(["sunday", "monday"]);
|
|
44752
|
-
const filterAutoShowSchema = z.enum([
|
|
44753
|
-
"auto",
|
|
44754
|
-
"always",
|
|
44755
|
-
"never"
|
|
44756
|
-
]);
|
|
44757
|
-
const calendarTabViewsSchema = z.enum([
|
|
44758
|
-
"both",
|
|
44759
|
-
"month",
|
|
44760
|
-
"week"
|
|
44761
|
-
]);
|
|
44762
|
-
//#endregion
|
|
44763
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
|
|
44764
|
-
/**
|
|
44765
|
-
* Determine which wizard steps to show based on context and payment requirements.
|
|
44766
|
-
*
|
|
44767
|
-
* @param hasPreSelectedContext - Whether event is pre-selected (skips event selection)
|
|
44768
|
-
* @param needsPaymentStep - Whether user must complete payment method selection
|
|
44769
|
-
* @returns Array of wizard steps to display
|
|
44770
|
-
*/
|
|
44771
|
-
function getWizardStepsForContext(hasPreSelectedContext, needsPaymentStep, paymentActive = false) {
|
|
44772
|
-
const baseSteps = hasPreSelectedContext ? ["select-tickets", "enter-details"] : [
|
|
44773
|
-
"select-event",
|
|
44774
|
-
"select-tickets",
|
|
44775
|
-
"enter-details"
|
|
44776
|
-
];
|
|
44777
|
-
if (!needsPaymentStep) return baseSteps;
|
|
44778
|
-
return paymentActive ? [
|
|
44779
|
-
...baseSteps,
|
|
44780
|
-
"select-payment",
|
|
44781
|
-
"payment"
|
|
44782
|
-
] : [...baseSteps, "select-payment"];
|
|
44783
|
-
}
|
|
44784
|
-
//#endregion
|
|
44785
45190
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
|
|
44786
45191
|
function eventMatchesOccurrenceId(event, occurrenceId) {
|
|
44787
45192
|
return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
|
|
@@ -44805,6 +45210,424 @@ function resolveEventRequiresPayment(input) {
|
|
|
44805
45210
|
return publicEventPricingType(input.event.pricing) === "paid";
|
|
44806
45211
|
}
|
|
44807
45212
|
//#endregion
|
|
45213
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
|
|
45214
|
+
/**
|
|
45215
|
+
* The locale a site's booking dates are written in: the one the site's time
|
|
45216
|
+
* zone places it in (`eventDateLocale`, shared with event cards), or British
|
|
45217
|
+
* English when the site names no zone.
|
|
45218
|
+
*/
|
|
45219
|
+
function bookingDateLocale(siteTimeZone) {
|
|
45220
|
+
return siteTimeZone ? eventDateLocale(siteTimeZone) : "en-GB";
|
|
45221
|
+
}
|
|
45222
|
+
function bookingInstant(startsAt, input) {
|
|
45223
|
+
return toScheduledBookingDateTime({
|
|
45224
|
+
startsAt,
|
|
45225
|
+
timeZone: toBookingTimeZone(input.timeZone),
|
|
45226
|
+
locale: bookingDateLocale(input.siteTimeZone)
|
|
45227
|
+
});
|
|
45228
|
+
}
|
|
45229
|
+
/** "7:00pm": a twelve-hour clock with a lowercase, unspaced day period. */
|
|
45230
|
+
function bookingClock(startsAt, input) {
|
|
45231
|
+
return formatBookingTime(bookingInstant(startsAt, input), {
|
|
45232
|
+
hour: "numeric",
|
|
45233
|
+
minute: "2-digit",
|
|
45234
|
+
hour12: true
|
|
45235
|
+
}).replace(/\s*([ap])\.?\s?m\.?$/i, (_match, period) => `${period.toLowerCase()}m`);
|
|
45236
|
+
}
|
|
45237
|
+
/** "7:00pm – 8:15pm", or just the start when there's no distinct end. */
|
|
45238
|
+
function clockRange(input) {
|
|
45239
|
+
const start = bookingClock(input.startsAt, input);
|
|
45240
|
+
const end = input.endsAt ? bookingClock(input.endsAt, input) : null;
|
|
45241
|
+
return end && end !== start ? `${start} – ${end}` : start;
|
|
45242
|
+
}
|
|
45243
|
+
/** A stored local clock has no date or DST offset; UTC preserves its digits. */
|
|
45244
|
+
function formatBookingScheduleSummary(event) {
|
|
45245
|
+
const summary = event.scheduleSummary;
|
|
45246
|
+
if (!summary) return null;
|
|
45247
|
+
const time = summary.startTime ? formatBookingWhen({
|
|
45248
|
+
startsAt: `1970-01-01T${summary.startTime}:00Z`,
|
|
45249
|
+
timeZone: "UTC",
|
|
45250
|
+
siteTimeZone: event.siteTimeZone
|
|
45251
|
+
}, "time") : null;
|
|
45252
|
+
return [summary.recurrenceDescription, time].filter(Boolean).join(" · ");
|
|
45253
|
+
}
|
|
45254
|
+
/** The one booking date formatter; every variant derives from it. */
|
|
45255
|
+
function formatBookingWhen(input, variant) {
|
|
45256
|
+
const instant = bookingInstant(input.startsAt, input);
|
|
45257
|
+
const day = formatBookingDate(instant, {
|
|
45258
|
+
weekday: "short",
|
|
45259
|
+
day: "numeric",
|
|
45260
|
+
month: "short"
|
|
45261
|
+
});
|
|
45262
|
+
switch (variant) {
|
|
45263
|
+
case "day": return day;
|
|
45264
|
+
case "dayLong": return formatBookingDate(instant, {
|
|
45265
|
+
weekday: "long",
|
|
45266
|
+
day: "numeric",
|
|
45267
|
+
month: "long"
|
|
45268
|
+
});
|
|
45269
|
+
case "month": return formatBookingDate(instant, { month: "long" });
|
|
45270
|
+
case "monthYear": return formatBookingDate(instant, {
|
|
45271
|
+
month: "long",
|
|
45272
|
+
year: "numeric"
|
|
45273
|
+
});
|
|
45274
|
+
case "time": return bookingClock(input.startsAt, input);
|
|
45275
|
+
case "timeRange": return clockRange(input);
|
|
45276
|
+
case "short": return `${day}, ${bookingClock(input.startsAt, input)}`;
|
|
45277
|
+
case "long": return `${day} · ${clockRange(input)}`;
|
|
45278
|
+
}
|
|
45279
|
+
}
|
|
45280
|
+
/** A single instant in the short form, e.g. "Mon 5 Oct, 7:00pm". */
|
|
45281
|
+
function formatEventDateTime(isoTimestamp, options) {
|
|
45282
|
+
return formatBookingWhen({
|
|
45283
|
+
startsAt: isoTimestamp,
|
|
45284
|
+
timeZone: options?.timeZone,
|
|
45285
|
+
siteTimeZone: options?.siteTimeZone
|
|
45286
|
+
}, "short");
|
|
45287
|
+
}
|
|
45288
|
+
/** The title an occurrence was given on its own, when it overrides the event's. */
|
|
45289
|
+
function occurrenceTitleOverride(occurrence) {
|
|
45290
|
+
const title = occurrence?.overrides?.title;
|
|
45291
|
+
return typeof title === "string" && title.trim() ? title.trim() : null;
|
|
45292
|
+
}
|
|
45293
|
+
/** The event as this page names it: an occurrence's own title wins. */
|
|
45294
|
+
function withOccurrenceTitle(event, occurrence) {
|
|
45295
|
+
const title = occurrenceTitleOverride(occurrence);
|
|
45296
|
+
return event && title ? {
|
|
45297
|
+
...event,
|
|
45298
|
+
title
|
|
45299
|
+
} : event;
|
|
45300
|
+
}
|
|
45301
|
+
function courseSchedule(sessions, siteTimeZone) {
|
|
45302
|
+
const first = sessions[0];
|
|
45303
|
+
if (!first) return null;
|
|
45304
|
+
const last = sessions[sessions.length - 1] ?? first;
|
|
45305
|
+
const firstLabel = formatEventDateTime(first.startsAt, {
|
|
45306
|
+
timeZone: first.timeZone,
|
|
45307
|
+
siteTimeZone
|
|
45308
|
+
});
|
|
45309
|
+
if (last.startsAt === first.startsAt) return `${sessions.length} session${sessions.length === 1 ? "" : "s"} · ${firstLabel}`;
|
|
45310
|
+
const lastLabel = formatEventDateTime(last.startsAt, {
|
|
45311
|
+
timeZone: last.timeZone,
|
|
45312
|
+
siteTimeZone
|
|
45313
|
+
});
|
|
45314
|
+
return `${sessions.length} sessions · ${firstLabel} – ${lastLabel}`;
|
|
45315
|
+
}
|
|
45316
|
+
/**
|
|
45317
|
+
* When a booking happens, in one line: the occurrence's date and time, or a
|
|
45318
|
+
* course's session count and first and last dates. `short` by default (bar,
|
|
45319
|
+
* confirmation); `long` adds the end time (card, panel header).
|
|
45320
|
+
*/
|
|
45321
|
+
function formatRegistrationSchedule(event, occurrence, variant = "short") {
|
|
45322
|
+
if (event.registrationSubject.kind === "wholeSeries") return courseSchedule(event.registrationSubject.sessions, event.siteTimeZone);
|
|
45323
|
+
const input = scheduleInput(event, occurrence ?? null);
|
|
45324
|
+
return input ? formatBookingWhen(input, variant) : null;
|
|
45325
|
+
}
|
|
45326
|
+
/** The occurrence's own times when the page names one, otherwise the event's. */
|
|
45327
|
+
function scheduleInput(event, occurrence) {
|
|
45328
|
+
const times = occurrence?.startsAt ? {
|
|
45329
|
+
startsAt: occurrence.startsAt,
|
|
45330
|
+
endsAt: occurrence.endsAt ?? null
|
|
45331
|
+
} : {
|
|
45332
|
+
startsAt: event.startsAt,
|
|
45333
|
+
endsAt: event.endsAt
|
|
45334
|
+
};
|
|
45335
|
+
if (!times.startsAt) return null;
|
|
45336
|
+
return {
|
|
45337
|
+
...times,
|
|
45338
|
+
timeZone: occurrence?.timeZone ?? event.timeZone ?? null,
|
|
45339
|
+
siteTimeZone: event.siteTimeZone
|
|
45340
|
+
};
|
|
45341
|
+
}
|
|
45342
|
+
//#endregion
|
|
45343
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
|
|
45344
|
+
function registrationRoute(input) {
|
|
45345
|
+
const base = input.chooseEvent ? [
|
|
45346
|
+
"select-event",
|
|
45347
|
+
"select-tickets",
|
|
45348
|
+
"enter-details"
|
|
45349
|
+
] : ["select-tickets", "enter-details"];
|
|
45350
|
+
switch (input.payment) {
|
|
45351
|
+
case "none": return base;
|
|
45352
|
+
case "options": return [...base, "select-payment"];
|
|
45353
|
+
case "optionsAndPayment": return [
|
|
45354
|
+
...base,
|
|
45355
|
+
"select-payment",
|
|
45356
|
+
"payment"
|
|
45357
|
+
];
|
|
45358
|
+
}
|
|
45359
|
+
}
|
|
45360
|
+
const REGISTRATION_STEP_LABELS = [
|
|
45361
|
+
"Event",
|
|
45362
|
+
"Date",
|
|
45363
|
+
"Tickets",
|
|
45364
|
+
"Places",
|
|
45365
|
+
"Your details",
|
|
45366
|
+
"How you’ll pay",
|
|
45367
|
+
"Payment"
|
|
45368
|
+
];
|
|
45369
|
+
/** Several dates of one series are a date choice; anything else is an event choice. */
|
|
45370
|
+
function getEventSelectionMode(events) {
|
|
45371
|
+
const firstSeriesId = events[0]?.seriesId;
|
|
45372
|
+
return events.length > 1 && firstSeriesId && events.every((event) => event.seriesId === firstSeriesId) ? "date" : "event";
|
|
45373
|
+
}
|
|
45374
|
+
/** The label facts for a surface: what the visitor chooses from, and what they book. */
|
|
45375
|
+
function registrationStepLabelContext(scopedEvents, bookedEvent) {
|
|
45376
|
+
return {
|
|
45377
|
+
eventSelection: getEventSelectionMode(scopedEvents),
|
|
45378
|
+
booksWholeSeries: bookedEvent?.registrationSubject.kind === "wholeSeries"
|
|
45379
|
+
};
|
|
45380
|
+
}
|
|
45381
|
+
/** One label owner for the live progress and the server placeholder. */
|
|
45382
|
+
function registrationStepLabel(step, context) {
|
|
45383
|
+
switch (step) {
|
|
45384
|
+
case "select-event": return context.eventSelection === "date" ? "Date" : "Event";
|
|
45385
|
+
case "select-tickets": return context.booksWholeSeries ? "Places" : "Tickets";
|
|
45386
|
+
case "enter-details": return "Your details";
|
|
45387
|
+
case "select-payment": return "How you’ll pay";
|
|
45388
|
+
case "payment": return "Payment";
|
|
45389
|
+
}
|
|
45390
|
+
}
|
|
45391
|
+
function bookingButtonText(buttonText) {
|
|
45392
|
+
return buttonText?.trim() || "Book your place";
|
|
45393
|
+
}
|
|
45394
|
+
function placesLabel(event, input, compact) {
|
|
45395
|
+
return placesLeftLabel(selectEventCapacitySource(event, input.attendanceMode), input.display, { compact });
|
|
45396
|
+
}
|
|
45397
|
+
function isFull(event, mode) {
|
|
45398
|
+
return formatRemainingPlaces(selectEventCapacitySource(event, mode), {
|
|
45399
|
+
full: "full",
|
|
45400
|
+
waitlist: "full"
|
|
45401
|
+
}) === "full";
|
|
45402
|
+
}
|
|
45403
|
+
function priceLabel(event) {
|
|
45404
|
+
return formatEventPriceDisplay(event.pricing).trim() || null;
|
|
45405
|
+
}
|
|
45406
|
+
/** The lowest price a display can mean; null when it names no paid amount. */
|
|
45407
|
+
function lowestPaidAmount(display) {
|
|
45408
|
+
switch (display.kind) {
|
|
45409
|
+
case "exact":
|
|
45410
|
+
case "from": return display.amount;
|
|
45411
|
+
case "range": return display.minAmount;
|
|
45412
|
+
case "mixed": return display.paidFromAmount;
|
|
45413
|
+
case "free":
|
|
45414
|
+
case "unavailable":
|
|
45415
|
+
case "external": return null;
|
|
45416
|
+
}
|
|
45417
|
+
}
|
|
45418
|
+
/**
|
|
45419
|
+
* One price for a set of dates: the shared label when every date costs the
|
|
45420
|
+
* same, otherwise "From" the lowest paid amount, through the one formatter.
|
|
45421
|
+
*/
|
|
45422
|
+
function seriesPriceLabel(events) {
|
|
45423
|
+
const firstEvent = events[0];
|
|
45424
|
+
if (!firstEvent) return null;
|
|
45425
|
+
const displays = events.map((event) => publicEventPricingDisplay(event.pricing));
|
|
45426
|
+
const labels = new Set(displays.map((display) => formatBookingPriceDisplay(display, { decimals: "auto" })));
|
|
45427
|
+
if (labels.size === 1) return [...labels][0] || null;
|
|
45428
|
+
const lowest = displays.flatMap((display) => {
|
|
45429
|
+
const amount = lowestPaidAmount(display);
|
|
45430
|
+
return amount === null || !("currency" in display) ? [] : [{
|
|
45431
|
+
amount,
|
|
45432
|
+
currency: display.currency
|
|
45433
|
+
}];
|
|
45434
|
+
}).reduce((best, candidate) => best === null || candidate.amount < best.amount ? candidate : best, null);
|
|
45435
|
+
return lowest ? formatBookingPriceDisplay({
|
|
45436
|
+
kind: "from",
|
|
45437
|
+
amount: lowest.amount,
|
|
45438
|
+
currency: lowest.currency
|
|
45439
|
+
}, { decimals: "auto" }) : priceLabel(firstEvent);
|
|
45440
|
+
}
|
|
45441
|
+
function dateTile(event) {
|
|
45442
|
+
if (event.registrationSubject.kind === "wholeSeries" || !event.startsAt) return null;
|
|
45443
|
+
const rail = formatEventCompactDateRail(event.startsAt, { timeZone: event.timeZone });
|
|
45444
|
+
return {
|
|
45445
|
+
month: rail.month,
|
|
45446
|
+
day: rail.day
|
|
45447
|
+
};
|
|
45448
|
+
}
|
|
45449
|
+
/** "Mon 5 Oct": the compact date the chips and the bar share. */
|
|
45450
|
+
function formatBookingShortDate(event) {
|
|
45451
|
+
return formatBookingWhen(event, "day");
|
|
45452
|
+
}
|
|
45453
|
+
function byStart(left, right) {
|
|
45454
|
+
return Date.parse(left.startsAt) - Date.parse(right.startsAt);
|
|
45455
|
+
}
|
|
45456
|
+
function singleEntry(event, input) {
|
|
45457
|
+
const isCourse = event.registrationSubject.kind === "wholeSeries";
|
|
45458
|
+
return {
|
|
45459
|
+
kind: "single",
|
|
45460
|
+
title: event.title,
|
|
45461
|
+
when: formatRegistrationSchedule(event, null, "long"),
|
|
45462
|
+
shortWhen: formatRegistrationSchedule(event),
|
|
45463
|
+
venue: shownVenue(event, input.display),
|
|
45464
|
+
price: priceLabel(event),
|
|
45465
|
+
places: placesLabel(event, input, false),
|
|
45466
|
+
tile: dateTile(event),
|
|
45467
|
+
action: isCourse ? `Book the ${input.noun.label}` : bookingButtonText(input.buttonText)
|
|
45468
|
+
};
|
|
45469
|
+
}
|
|
45470
|
+
function chooseDateEntry(input) {
|
|
45471
|
+
const ordered = [...input.events].sort(byStart);
|
|
45472
|
+
const first = ordered[0];
|
|
45473
|
+
const shown = ordered.slice(0, 4);
|
|
45474
|
+
return {
|
|
45475
|
+
kind: "chooseDate",
|
|
45476
|
+
title: first?.title ?? "",
|
|
45477
|
+
schedule: (first ? formatBookingScheduleSummary(first) : null) ?? (ordered.length === 1 ? "1 date" : `${ordered.length} dates`),
|
|
45478
|
+
venue: first ? shownVenue(first, input.display) : null,
|
|
45479
|
+
price: seriesPriceLabel(ordered),
|
|
45480
|
+
nextDate: first ? formatBookingShortDate(first) : null,
|
|
45481
|
+
dateCount: ordered.length,
|
|
45482
|
+
dates: shown.map((event) => ({
|
|
45483
|
+
selectionId: event.selectionId,
|
|
45484
|
+
label: formatBookingShortDate(event),
|
|
45485
|
+
places: placesLabel(event, input, true),
|
|
45486
|
+
full: isFull(event, input.attendanceMode)
|
|
45487
|
+
})),
|
|
45488
|
+
moreCount: Math.max(0, ordered.length - shown.length),
|
|
45489
|
+
action: "Choose a date"
|
|
45490
|
+
};
|
|
45491
|
+
}
|
|
45492
|
+
/** The card before a booking starts; the server renders this too. */
|
|
45493
|
+
function idleBookingEntry(input) {
|
|
45494
|
+
if (input.event) return singleEntry(input.event, input);
|
|
45495
|
+
const only = input.events.length === 1 ? input.events[0] : void 0;
|
|
45496
|
+
if (only) return singleEntry(only, input);
|
|
45497
|
+
if (getEventSelectionMode(input.events) === "date") return chooseDateEntry(input);
|
|
45498
|
+
return {
|
|
45499
|
+
kind: "chooseEvent",
|
|
45500
|
+
title: input.events[0]?.title ?? "",
|
|
45501
|
+
count: input.events.length,
|
|
45502
|
+
noun: input.noun.pluralLabel,
|
|
45503
|
+
action: "Choose an event"
|
|
45504
|
+
};
|
|
45505
|
+
}
|
|
45506
|
+
//#endregion
|
|
45507
|
+
//#region ../blocks/src/system/blocks/offerings-preview/model.ts
|
|
45508
|
+
const OFFERINGS_PREVIEW_DEFAULT_BUTTON_TEXT = "Book";
|
|
45509
|
+
const OFFERINGS_PREVIEW_DEFAULT_EMPTY_MESSAGE = "Nothing scheduled just yet.";
|
|
45510
|
+
const OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS = [
|
|
45511
|
+
{
|
|
45512
|
+
preset: "class",
|
|
45513
|
+
sourceKey: "eventPreset:class",
|
|
45514
|
+
dataKey: "classEvents",
|
|
45515
|
+
label: "Classes"
|
|
45516
|
+
},
|
|
45517
|
+
{
|
|
45518
|
+
preset: "workshop",
|
|
45519
|
+
sourceKey: "eventPreset:workshop",
|
|
45520
|
+
dataKey: "workshopEvents",
|
|
45521
|
+
label: "Workshops"
|
|
45522
|
+
},
|
|
45523
|
+
{
|
|
45524
|
+
preset: "retreat",
|
|
45525
|
+
sourceKey: "eventPreset:retreat",
|
|
45526
|
+
dataKey: "retreatEvents",
|
|
45527
|
+
label: "Retreats"
|
|
45528
|
+
},
|
|
45529
|
+
{
|
|
45530
|
+
preset: "performance",
|
|
45531
|
+
sourceKey: "eventPreset:performance",
|
|
45532
|
+
dataKey: "performanceEvents",
|
|
45533
|
+
label: "Performances"
|
|
45534
|
+
}
|
|
45535
|
+
];
|
|
45536
|
+
const OFFERINGS_PREVIEW_EVENT_PRESETS = OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.preset);
|
|
45537
|
+
const OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS = [...OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.sourceKey), "course"];
|
|
45538
|
+
const OFFERINGS_PREVIEW_SOURCE_KEYS = OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS;
|
|
45539
|
+
Object.fromEntries(OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.sourceKey, {
|
|
45540
|
+
kind: "eventPreset",
|
|
45541
|
+
preset: definition.preset
|
|
45542
|
+
}]));
|
|
45543
|
+
function isOfferingsPreviewSourceKey(value) {
|
|
45544
|
+
return typeof value === "string" && OFFERINGS_PREVIEW_SOURCE_KEYS.includes(value);
|
|
45545
|
+
}
|
|
45546
|
+
function normalizeOfferingsPreviewGroupOrder(value) {
|
|
45547
|
+
if (value == null) return { kind: "legacy" };
|
|
45548
|
+
if (value.length === 0) return { kind: "default" };
|
|
45549
|
+
const keys = uniqueOfferingsPreviewSourceKeys(value);
|
|
45550
|
+
return keys.length > 0 ? {
|
|
45551
|
+
kind: "custom",
|
|
45552
|
+
keys
|
|
45553
|
+
} : { kind: "default" };
|
|
45554
|
+
}
|
|
45555
|
+
function inferLegacyOfferingsPreviewGroupOrder(overrides) {
|
|
45556
|
+
const keys = uniqueOfferingsPreviewSourceKeys((overrides ?? []).map((override) => override.sourceKey));
|
|
45557
|
+
return keys.length >= 2 ? keys : [];
|
|
45558
|
+
}
|
|
45559
|
+
function normalizeOfferingsPreviewContentForWrite(value) {
|
|
45560
|
+
if (!isRecord$7(value)) return null;
|
|
45561
|
+
const groupOrderValue = value.groupOrder;
|
|
45562
|
+
if (Array.isArray(groupOrderValue)) {
|
|
45563
|
+
const normalized = normalizeOfferingsPreviewGroupOrder(groupOrderValue);
|
|
45564
|
+
return {
|
|
45565
|
+
...value,
|
|
45566
|
+
groupOrder: normalized.kind === "custom" ? normalized.keys : []
|
|
45567
|
+
};
|
|
45568
|
+
}
|
|
45569
|
+
if (groupOrderValue != null) return {
|
|
45570
|
+
...value,
|
|
45571
|
+
groupOrder: []
|
|
45572
|
+
};
|
|
45573
|
+
const legacyOrder = inferLegacyOfferingsPreviewGroupOrder(Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord$7) : []);
|
|
45574
|
+
return legacyOrder.length > 0 ? {
|
|
45575
|
+
...value,
|
|
45576
|
+
groupOrder: legacyOrder
|
|
45577
|
+
} : value;
|
|
45578
|
+
}
|
|
45579
|
+
/** Which offerings a site preset row names; one owner for "the course preset means whole-series runs". */
|
|
45580
|
+
function sourceFromPresetSummary(preset) {
|
|
45581
|
+
if (preset.engine === "event_series" && preset.canonicalBehaviour === "course") return { kind: "wholeSeries" };
|
|
45582
|
+
if (preset.engine !== "event_series") return null;
|
|
45583
|
+
if (isOfferingsPreviewEventPreset(preset.canonicalBehaviour)) return {
|
|
45584
|
+
kind: "eventPreset",
|
|
45585
|
+
preset: preset.canonicalBehaviour
|
|
45586
|
+
};
|
|
45587
|
+
return null;
|
|
45588
|
+
}
|
|
45589
|
+
function uniqueOfferingsPreviewSourceKeys(values) {
|
|
45590
|
+
const keys = [];
|
|
45591
|
+
for (const value of values) {
|
|
45592
|
+
if (!isOfferingsPreviewSourceKey(value)) continue;
|
|
45593
|
+
if (!keys.includes(value)) keys.push(value);
|
|
45594
|
+
}
|
|
45595
|
+
return keys;
|
|
45596
|
+
}
|
|
45597
|
+
function isRecord$7(value) {
|
|
45598
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45599
|
+
}
|
|
45600
|
+
function isOfferingsPreviewEventPreset(value) {
|
|
45601
|
+
return typeof value === "string" && OFFERINGS_PREVIEW_EVENT_PRESETS.includes(value);
|
|
45602
|
+
}
|
|
45603
|
+
//#endregion
|
|
45604
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/offeringNoun.ts
|
|
45605
|
+
function offeringKindForEvent(event) {
|
|
45606
|
+
return event.registrationSubject.kind === "wholeSeries" ? "course" : event.eventPreset ?? "event";
|
|
45607
|
+
}
|
|
45608
|
+
function presetKind(preset) {
|
|
45609
|
+
const source = sourceFromPresetSummary(preset);
|
|
45610
|
+
if (!source) return null;
|
|
45611
|
+
return source.kind === "wholeSeries" ? "course" : source.preset;
|
|
45612
|
+
}
|
|
45613
|
+
/**
|
|
45614
|
+
* What the site calls this kind of offering, in lower case for use mid-sentence
|
|
45615
|
+
* ("Book the course", "3 workshops"). Site preset labels win; the canonical
|
|
45616
|
+
* name stands in when the site has none.
|
|
45617
|
+
*/
|
|
45618
|
+
function offeringNounForEvent(event, presets) {
|
|
45619
|
+
if (!event) return lowerCased(EVENT_PRESET_VOCABULARY.event);
|
|
45620
|
+
const kind = offeringKindForEvent(event);
|
|
45621
|
+
const preset = presets?.find((candidate) => presetKind(candidate) === kind);
|
|
45622
|
+
return lowerCased(preset?.label.trim() && preset.pluralLabel.trim() ? preset : EVENT_PRESET_VOCABULARY[kind]);
|
|
45623
|
+
}
|
|
45624
|
+
function lowerCased(noun) {
|
|
45625
|
+
return {
|
|
45626
|
+
label: noun.label.trim().toLocaleLowerCase(),
|
|
45627
|
+
pluralLabel: noun.pluralLabel.trim().toLocaleLowerCase()
|
|
45628
|
+
};
|
|
45629
|
+
}
|
|
45630
|
+
//#endregion
|
|
44808
45631
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.ts
|
|
44809
45632
|
function toRegistrationEvent(event) {
|
|
44810
45633
|
return {
|
|
@@ -44849,6 +45672,181 @@ function toWholeSeriesRegistrationEvents(events) {
|
|
|
44849
45672
|
return groupPublicEventsByRun(events).map(toWholeSeriesRegistrationEvent).filter((event) => event !== null);
|
|
44850
45673
|
}
|
|
44851
45674
|
//#endregion
|
|
45675
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/bookingCardDisplay.ts
|
|
45676
|
+
/**
|
|
45677
|
+
* The booking card the server renders on CMS pages (issue 1581), and the
|
|
45678
|
+
* offering noun it resolves for the wizard. Kept beside the island contract
|
|
45679
|
+
* so the server and the client agree on one card.
|
|
45680
|
+
*/
|
|
45681
|
+
const bookingHostSchema = z.enum(["overlay", "inPlace"]);
|
|
45682
|
+
const tileSchema = z.object({
|
|
45683
|
+
month: z.string(),
|
|
45684
|
+
day: z.string()
|
|
45685
|
+
}).nullable();
|
|
45686
|
+
const idleBookingEntrySchema = z.discriminatedUnion("kind", [
|
|
45687
|
+
z.object({
|
|
45688
|
+
kind: z.literal("single"),
|
|
45689
|
+
title: z.string(),
|
|
45690
|
+
when: z.string().nullable(),
|
|
45691
|
+
shortWhen: z.string().nullable(),
|
|
45692
|
+
venue: z.string().nullable(),
|
|
45693
|
+
price: z.string().nullable(),
|
|
45694
|
+
places: z.string().nullable(),
|
|
45695
|
+
tile: tileSchema,
|
|
45696
|
+
action: z.string()
|
|
45697
|
+
}),
|
|
45698
|
+
z.object({
|
|
45699
|
+
kind: z.literal("chooseDate"),
|
|
45700
|
+
title: z.string(),
|
|
45701
|
+
schedule: z.string(),
|
|
45702
|
+
venue: z.string().nullable(),
|
|
45703
|
+
price: z.string().nullable(),
|
|
45704
|
+
nextDate: z.string().nullable(),
|
|
45705
|
+
dateCount: z.number(),
|
|
45706
|
+
dates: z.array(z.object({
|
|
45707
|
+
selectionId: z.string(),
|
|
45708
|
+
label: z.string(),
|
|
45709
|
+
places: z.string().nullable(),
|
|
45710
|
+
full: z.boolean()
|
|
45711
|
+
})),
|
|
45712
|
+
moreCount: z.number(),
|
|
45713
|
+
action: z.string()
|
|
45714
|
+
}),
|
|
45715
|
+
z.object({
|
|
45716
|
+
kind: z.literal("chooseEvent"),
|
|
45717
|
+
title: z.string(),
|
|
45718
|
+
count: z.number(),
|
|
45719
|
+
noun: z.string(),
|
|
45720
|
+
action: z.string()
|
|
45721
|
+
})
|
|
45722
|
+
]);
|
|
45723
|
+
function toScopedEventRegistrationEvents(scopedSourceEvents) {
|
|
45724
|
+
return [...toRegistrationEvents(scopedSourceEvents), ...toWholeSeriesRegistrationEvents(scopedSourceEvents)];
|
|
45725
|
+
}
|
|
45726
|
+
function scopedRegistrationEvents(source, scopedSourceEvents) {
|
|
45727
|
+
const scopedEvents = toScopedEventRegistrationEvents(scopedSourceEvents);
|
|
45728
|
+
return {
|
|
45729
|
+
scopedEvents,
|
|
45730
|
+
preSelected: findPreSelectedEvent({
|
|
45731
|
+
scopedEvents,
|
|
45732
|
+
occurrenceContext: source.occurrenceContext
|
|
45733
|
+
})
|
|
45734
|
+
};
|
|
45735
|
+
}
|
|
45736
|
+
function nounFor(scoped, presets) {
|
|
45737
|
+
return offeringNounForEvent(scoped.preSelected ?? scoped.scopedEvents[0] ?? null, presets);
|
|
45738
|
+
}
|
|
45739
|
+
/** What the site calls the offering this block books, from its preset rows. */
|
|
45740
|
+
function resolveOfferingNoun(source, scopedSourceEvents) {
|
|
45741
|
+
return nounFor(scopedRegistrationEvents(source, scopedSourceEvents), source.bookingOfferingPresets);
|
|
45742
|
+
}
|
|
45743
|
+
function idleEntry(source, scopedSourceEvents, display) {
|
|
45744
|
+
const scoped = scopedRegistrationEvents(source, scopedSourceEvents);
|
|
45745
|
+
if (scoped.scopedEvents.length === 0) return null;
|
|
45746
|
+
return idleBookingEntry({
|
|
45747
|
+
events: scoped.scopedEvents,
|
|
45748
|
+
event: withOccurrenceTitle(scoped.preSelected, source.occurrenceContext),
|
|
45749
|
+
display,
|
|
45750
|
+
buttonText: source.buttonText,
|
|
45751
|
+
noun: nounFor(scoped, source.bookingOfferingPresets),
|
|
45752
|
+
attendanceMode: null
|
|
45753
|
+
});
|
|
45754
|
+
}
|
|
45755
|
+
/** The server's card on CMS pages, or null where the shell still applies. */
|
|
45756
|
+
function bookingCardDisplay(source, scopedSourceEvents, display) {
|
|
45757
|
+
if ((source.host ?? "overlay") !== "overlay") return null;
|
|
45758
|
+
const entry = idleEntry(source, scopedSourceEvents, display);
|
|
45759
|
+
if (!entry) return null;
|
|
45760
|
+
return {
|
|
45761
|
+
kind: "event-registration",
|
|
45762
|
+
state: "booking-card",
|
|
45763
|
+
className: source.className ?? null,
|
|
45764
|
+
entry,
|
|
45765
|
+
buttonVariant: source.buttonVariant ?? null,
|
|
45766
|
+
buttonText: source.buttonText?.trim() ?? ""
|
|
45767
|
+
};
|
|
45768
|
+
}
|
|
45769
|
+
const unsupportedEventRegistrationPageSurfaceSubjectSchema = z.object({
|
|
45770
|
+
kind: z.literal("unsupported"),
|
|
45771
|
+
reason: z.enum([
|
|
45772
|
+
"unsupportedSubject",
|
|
45773
|
+
"invalidEventSeriesId",
|
|
45774
|
+
"invalidEventSeriesBookingScope",
|
|
45775
|
+
"invalidEventOfferingId",
|
|
45776
|
+
"invalidEventOfferingBookingScope",
|
|
45777
|
+
"invalidEventOfferingCatalogue"
|
|
45778
|
+
])
|
|
45779
|
+
});
|
|
45780
|
+
const eventRegistrationPageSurfaceSubjectSchema = z.unknown().transform((value, ctx) => {
|
|
45781
|
+
const unsupported = unsupportedEventRegistrationPageSurfaceSubjectSchema.safeParse(value);
|
|
45782
|
+
if (unsupported.success) return unsupported.data;
|
|
45783
|
+
const parsed = parseEventPageSurfaceSubject(value);
|
|
45784
|
+
if (parsed.ok) return parsed.value;
|
|
45785
|
+
ctx.addIssue({
|
|
45786
|
+
code: z.ZodIssueCode.custom,
|
|
45787
|
+
message: `Invalid event page-surface subject (${parsed.error.kind})`
|
|
45788
|
+
});
|
|
45789
|
+
return z.NEVER;
|
|
45790
|
+
});
|
|
45791
|
+
function resolveEventRegistrationScope(context) {
|
|
45792
|
+
const occurrenceSeriesId = context.occurrenceContext?.seriesId;
|
|
45793
|
+
if (occurrenceSeriesId) return {
|
|
45794
|
+
kind: "occurrenceSeries",
|
|
45795
|
+
seriesId: occurrenceSeriesId
|
|
45796
|
+
};
|
|
45797
|
+
if (context.subject?.kind === "eventSeries") return {
|
|
45798
|
+
kind: "pageSurfaceSeries",
|
|
45799
|
+
seriesId: context.subject.eventSeriesId
|
|
45800
|
+
};
|
|
45801
|
+
if (context.subject?.kind === "eventOffering") return {
|
|
45802
|
+
kind: "pageSurfaceOffering",
|
|
45803
|
+
offeringId: context.subject.eventOfferingId,
|
|
45804
|
+
seriesIds: context.subject.catalogueEventSeriesIds
|
|
45805
|
+
};
|
|
45806
|
+
if (context.subject?.kind === "unsupported") return {
|
|
45807
|
+
kind: "unsupportedPageSurfaceSubject",
|
|
45808
|
+
reason: context.subject.reason
|
|
45809
|
+
};
|
|
45810
|
+
return { kind: "unscoped" };
|
|
45811
|
+
}
|
|
45812
|
+
function resolveEventRegistrationScopedEvents(events, context) {
|
|
45813
|
+
const scope = resolveEventRegistrationScope(context);
|
|
45814
|
+
switch (scope.kind) {
|
|
45815
|
+
case "occurrenceSeries":
|
|
45816
|
+
case "pageSurfaceSeries": return events.filter((event) => event.seriesId === scope.seriesId);
|
|
45817
|
+
case "pageSurfaceOffering": {
|
|
45818
|
+
const seriesIds = new Set(scope.seriesIds);
|
|
45819
|
+
return events.filter((event) => seriesIds.has(event.seriesId));
|
|
45820
|
+
}
|
|
45821
|
+
case "unsupportedPageSurfaceSubject": return [];
|
|
45822
|
+
case "unscoped": return [...events];
|
|
45823
|
+
}
|
|
45824
|
+
}
|
|
45825
|
+
//#endregion
|
|
45826
|
+
//#region ../blocks/src/system/runtime/nodes/shared/contract-schemas.ts
|
|
45827
|
+
const previewStageSchema = z.enum(["preview", "published"]);
|
|
45828
|
+
const registrationButtonVariantSchema = blockButtonRoleSchema;
|
|
45829
|
+
const eventButtonVariantSchema = blockButtonRoleSchema;
|
|
45830
|
+
const eventLayoutSchema = z.enum(eventCalendarListLayoutValues);
|
|
45831
|
+
const eventCalendarDisplayModeSchema = z.enum(eventCalendarDisplayModeValues);
|
|
45832
|
+
const eventCalendarDefaultViewSchema = z.enum(eventCalendarDefaultViewValues);
|
|
45833
|
+
const columnOptionSchema = z.enum([
|
|
45834
|
+
"2",
|
|
45835
|
+
"3",
|
|
45836
|
+
"4"
|
|
45837
|
+
]);
|
|
45838
|
+
const weekStartSchema = z.enum(["sunday", "monday"]);
|
|
45839
|
+
const filterAutoShowSchema = z.enum([
|
|
45840
|
+
"auto",
|
|
45841
|
+
"always",
|
|
45842
|
+
"never"
|
|
45843
|
+
]);
|
|
45844
|
+
const calendarTabViewsSchema = z.enum([
|
|
45845
|
+
"both",
|
|
45846
|
+
"month",
|
|
45847
|
+
"week"
|
|
45848
|
+
]);
|
|
45849
|
+
//#endregion
|
|
44852
45850
|
//#region ../blocks/src/system/runtime/nodes/event-registration/eventSourceRecovery.ts
|
|
44853
45851
|
const { limit: _rawLimit, eventSurface: _rawEventSurface, scheduleScope: _rawScheduleScope, detailLevel: _rawDetailLevel, ...stringEventQueryShape } = publicEventLoaderQuerySchemaShape;
|
|
44854
45852
|
const eventRecoveryRequestSchema = z.object({
|
|
@@ -44891,27 +45889,17 @@ function parseEventLoaderRecoveryRequest(value) {
|
|
|
44891
45889
|
const EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS = [
|
|
44892
45890
|
"Date",
|
|
44893
45891
|
"Tickets",
|
|
44894
|
-
"
|
|
44895
|
-
];
|
|
44896
|
-
const EVENT_REGISTRATION_SHELL_STEP_LABELS = [
|
|
44897
|
-
"Event",
|
|
44898
|
-
"Date",
|
|
44899
|
-
"Tickets",
|
|
44900
|
-
"Details",
|
|
44901
|
-
"Payment options",
|
|
44902
|
-
"Payment"
|
|
45892
|
+
"Your details"
|
|
44903
45893
|
];
|
|
44904
45894
|
const eventRegistrationPublicEventSchema = z.preprocess(normalizeEventRegistrationEventInput, publicEventSchema);
|
|
44905
|
-
const
|
|
45895
|
+
const eventRegistrationCommonSchemaShape = {
|
|
44906
45896
|
demoEmailSuppressed: z.boolean().optional(),
|
|
44907
45897
|
occurrenceContext: occurrenceContextSchema.optional(),
|
|
44908
45898
|
subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
|
|
44909
45899
|
maxTickets: z.string().optional(),
|
|
44910
|
-
showVenue: z.boolean().optional(),
|
|
44911
|
-
showCapacity: z.boolean().optional(),
|
|
44912
45900
|
successMessage: z.string().optional(),
|
|
44913
45901
|
buttonVariant: registrationButtonVariantSchema.optional(),
|
|
44914
|
-
|
|
45902
|
+
host: bookingHostSchema.optional(),
|
|
44915
45903
|
spamProtectionEnabled: z.boolean().optional(),
|
|
44916
45904
|
supportEmail: z.string().optional(),
|
|
44917
45905
|
sitePasses: publicPassProductCollectionSchema.nullable().optional(),
|
|
@@ -44936,32 +45924,51 @@ const eventRegistrationSourceSchema = z.object({
|
|
|
44936
45924
|
portalToken: z.string().nullable().optional(),
|
|
44937
45925
|
previewToken: z.string().nullable().optional(),
|
|
44938
45926
|
readAuthority: browserReadAuthoritySchema.optional(),
|
|
44939
|
-
...
|
|
45927
|
+
...eventRegistrationCommonSchemaShape,
|
|
45928
|
+
showVenue: z.boolean().optional(),
|
|
45929
|
+
showCapacity: z.boolean().optional(),
|
|
44940
45930
|
events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
44941
45931
|
wholeSeriesRunEvents: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
44942
45932
|
eventLoaderFailures: z.record(z.string(), z.unknown()).nullable().optional(),
|
|
44943
45933
|
className: z.string().nullable().optional(),
|
|
44944
45934
|
buttonText: z.string().nullable().optional(),
|
|
44945
45935
|
maxTickets: z.string().nullable().optional(),
|
|
44946
|
-
stage: previewStageSchema.optional()
|
|
45936
|
+
stage: previewStageSchema.optional(),
|
|
45937
|
+
bookingOfferingPresets: z.array(z.custom((value) => typeof value === "object" && value !== null && typeof value.label === "string")).nullable().optional()
|
|
44947
45938
|
});
|
|
44948
|
-
const eventRegistrationDisplaySchema = z.discriminatedUnion("state", [
|
|
44949
|
-
|
|
44950
|
-
|
|
44951
|
-
|
|
44952
|
-
|
|
44953
|
-
|
|
44954
|
-
|
|
44955
|
-
|
|
44956
|
-
|
|
44957
|
-
|
|
44958
|
-
|
|
44959
|
-
|
|
44960
|
-
|
|
44961
|
-
|
|
44962
|
-
|
|
45939
|
+
const eventRegistrationDisplaySchema = z.discriminatedUnion("state", [
|
|
45940
|
+
z.object({
|
|
45941
|
+
kind: z.literal("event-registration"),
|
|
45942
|
+
state: z.literal("generic-shell"),
|
|
45943
|
+
className: z.string().nullable(),
|
|
45944
|
+
titleText: z.string(),
|
|
45945
|
+
bodyText: z.string(),
|
|
45946
|
+
stepLabels: z.array(z.enum(REGISTRATION_STEP_LABELS)).min(1),
|
|
45947
|
+
summaryButtonText: z.string()
|
|
45948
|
+
}),
|
|
45949
|
+
z.object({
|
|
45950
|
+
kind: z.literal("event-registration"),
|
|
45951
|
+
state: z.literal("registration-closed"),
|
|
45952
|
+
className: z.string().nullable(),
|
|
45953
|
+
titleText: z.string(),
|
|
45954
|
+
bodyText: z.string()
|
|
45955
|
+
}),
|
|
45956
|
+
z.object({
|
|
45957
|
+
kind: z.literal("event-registration"),
|
|
45958
|
+
state: z.literal("booking-card"),
|
|
45959
|
+
className: z.string().nullable(),
|
|
45960
|
+
entry: idleBookingEntrySchema,
|
|
45961
|
+
buttonVariant: registrationButtonVariantSchema.nullable(),
|
|
45962
|
+
buttonText: z.string()
|
|
45963
|
+
})
|
|
45964
|
+
]);
|
|
44963
45965
|
const eventRegistrationHydrationSchema = z.object({
|
|
44964
|
-
...
|
|
45966
|
+
...eventRegistrationCommonSchemaShape,
|
|
45967
|
+
display: registrationDisplaySchema,
|
|
45968
|
+
offeringNoun: z.object({
|
|
45969
|
+
label: z.string(),
|
|
45970
|
+
pluralLabel: z.string()
|
|
45971
|
+
}).optional(),
|
|
44965
45972
|
eventSource: eventRegistrationEventSourceSchema
|
|
44966
45973
|
});
|
|
44967
45974
|
const eventRegistrationRenderSchema = z.object({
|
|
@@ -44976,7 +45983,7 @@ z.object({
|
|
|
44976
45983
|
readAuthority: browserReadAuthoritySchema.optional(),
|
|
44977
45984
|
stage: previewStageSchema.optional()
|
|
44978
45985
|
});
|
|
44979
|
-
function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents) {
|
|
45986
|
+
function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents, display) {
|
|
44980
45987
|
const selectedRun = resolveSelectedWholeSeriesRun(scopedSourceEvents);
|
|
44981
45988
|
if (selectedRun && (!selectedRun.run.enrollmentOpen || toWholeSeriesRegistrationEvent(selectedRun) === null)) return {
|
|
44982
45989
|
kind: "event-registration",
|
|
@@ -44985,6 +45992,8 @@ function buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvent
|
|
|
44985
45992
|
titleText: "Registration closed",
|
|
44986
45993
|
bodyText: "This run is no longer open for bookings."
|
|
44987
45994
|
};
|
|
45995
|
+
const card = bookingCardDisplay(source, scopedSourceEvents, display);
|
|
45996
|
+
if (card) return card;
|
|
44988
45997
|
const stepLabels = buildEventRegistrationShellStepLabels(source, scopedSourceEvents);
|
|
44989
45998
|
return {
|
|
44990
45999
|
kind: "event-registration",
|
|
@@ -45001,11 +46010,14 @@ function buildEventRegistrationShellStepLabels(source, scopedSourceEvents) {
|
|
|
45001
46010
|
if (selectedRun) {
|
|
45002
46011
|
const selectedEvent = toWholeSeriesRegistrationEvent(selectedRun);
|
|
45003
46012
|
if (!selectedEvent) return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
|
|
45004
|
-
return
|
|
45005
|
-
|
|
45006
|
-
|
|
45007
|
-
|
|
45008
|
-
|
|
46013
|
+
return shellStepLabels(registrationRoute({
|
|
46014
|
+
chooseEvent: false,
|
|
46015
|
+
payment: resolveEventRequiresPayment({
|
|
46016
|
+
eligibility: null,
|
|
46017
|
+
selectedTicketType: null,
|
|
46018
|
+
event: selectedEvent
|
|
46019
|
+
}) ? "optionsAndPayment" : "none"
|
|
46020
|
+
}), registrationStepLabelContext([selectedEvent], selectedEvent));
|
|
45009
46021
|
}
|
|
45010
46022
|
const scopedEvents = toScopedEventRegistrationEvents(scopedSourceEvents);
|
|
45011
46023
|
if (scopedEvents.length === 0) return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
|
|
@@ -45014,14 +46026,15 @@ function buildEventRegistrationShellStepLabels(source, scopedSourceEvents) {
|
|
|
45014
46026
|
occurrenceContext: source.occurrenceContext
|
|
45015
46027
|
});
|
|
45016
46028
|
const hasPreSelectedContext = Boolean(source.occurrenceContext || preSelectedEvent);
|
|
45017
|
-
|
|
46029
|
+
const needsPaymentStep = hasPreSelectedContext && preSelectedEvent ? resolveEventRequiresPayment({
|
|
45018
46030
|
eligibility: null,
|
|
45019
46031
|
selectedTicketType: null,
|
|
45020
46032
|
event: preSelectedEvent
|
|
45021
|
-
}) : false
|
|
45022
|
-
|
|
45023
|
-
|
|
45024
|
-
|
|
46033
|
+
}) : false;
|
|
46034
|
+
return shellStepLabels(registrationRoute({
|
|
46035
|
+
chooseEvent: !hasPreSelectedContext,
|
|
46036
|
+
payment: needsPaymentStep ? "optionsAndPayment" : "none"
|
|
46037
|
+
}), registrationStepLabelContext(scopedEvents, preSelectedEvent));
|
|
45025
46038
|
}
|
|
45026
46039
|
function scopeEventRegistrationSourceEvents(source, eventSource) {
|
|
45027
46040
|
return resolveEventRegistrationScopedEvents(eventSource.kind === "loaded" ? eventSource.events : [], {
|
|
@@ -45037,29 +46050,12 @@ function resolveSelectedWholeSeriesRun(scopedSourceEvents) {
|
|
|
45037
46050
|
const runs = groupPublicEventsByRun(scopedSourceEvents);
|
|
45038
46051
|
return runs.length === 1 ? runs[0] : null;
|
|
45039
46052
|
}
|
|
45040
|
-
function
|
|
45041
|
-
|
|
45042
|
-
case "select-event": return isDateSelection(events) ? "Date" : "Event";
|
|
45043
|
-
case "select-tickets": return "Tickets";
|
|
45044
|
-
case "enter-details": return "Details";
|
|
45045
|
-
case "select-payment": return "Payment options";
|
|
45046
|
-
case "payment": return "Payment";
|
|
45047
|
-
case "error":
|
|
45048
|
-
case "success":
|
|
45049
|
-
case "submitting":
|
|
45050
|
-
case "verifying-payment":
|
|
45051
|
-
case "verifying-timeout":
|
|
45052
|
-
case "payment-status":
|
|
45053
|
-
case "payment-failed": return "Details";
|
|
45054
|
-
}
|
|
45055
|
-
}
|
|
45056
|
-
function isDateSelection(events) {
|
|
45057
|
-
const firstSeriesId = events[0]?.seriesId;
|
|
45058
|
-
return Boolean(events.length > 1 && firstSeriesId && events.every((event) => event.seriesId === firstSeriesId));
|
|
46053
|
+
function shellStepLabels(route, context) {
|
|
46054
|
+
return route.map((step) => registrationStepLabel(step, context));
|
|
45059
46055
|
}
|
|
45060
46056
|
function buildEventRegistrationShellBodyText(stepLabels) {
|
|
45061
|
-
if (stepLabels.includes("
|
|
45062
|
-
if (stepLabels[0] === "Tickets") return "Preparing tickets and booking details.";
|
|
46057
|
+
if (stepLabels.includes("How you’ll pay")) return "Preparing tickets, details, and payment options.";
|
|
46058
|
+
if (stepLabels[0] === "Tickets" || stepLabels[0] === "Places") return "Preparing tickets and booking details.";
|
|
45063
46059
|
return "Preparing dates, tickets, and booking details.";
|
|
45064
46060
|
}
|
|
45065
46061
|
const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
|
|
@@ -45069,6 +46065,7 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
|
|
|
45069
46065
|
render: createZodCodec(eventRegistrationRenderSchema)
|
|
45070
46066
|
},
|
|
45071
46067
|
buildRender: (source) => {
|
|
46068
|
+
const display = resolveRegistrationDisplay(source);
|
|
45072
46069
|
const eventSource = resolveEventRegistrationEventSource({
|
|
45073
46070
|
events: source.events,
|
|
45074
46071
|
wholeSeriesRunEvents: source.wholeSeriesRunEvents,
|
|
@@ -45076,7 +46073,7 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
|
|
|
45076
46073
|
});
|
|
45077
46074
|
const scopedSourceEvents = scopeEventRegistrationSourceEvents(source, eventSource);
|
|
45078
46075
|
return {
|
|
45079
|
-
display: buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents),
|
|
46076
|
+
display: buildEventRegistrationDisplayFromScopedEvents(source, scopedSourceEvents, display),
|
|
45080
46077
|
hydration: {
|
|
45081
46078
|
occurrenceContext: source.occurrenceContext ?? null,
|
|
45082
46079
|
subject: source.subject ?? null,
|
|
@@ -45086,29 +46083,29 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
|
|
|
45086
46083
|
} : eventSource,
|
|
45087
46084
|
demoEmailSuppressed: source.demoEmailSuppressed,
|
|
45088
46085
|
maxTickets: source.maxTickets ?? void 0,
|
|
45089
|
-
|
|
45090
|
-
showCapacity: source.showCapacity,
|
|
46086
|
+
display,
|
|
45091
46087
|
successMessage: source.successMessage,
|
|
45092
46088
|
buttonVariant: source.buttonVariant,
|
|
45093
|
-
|
|
46089
|
+
host: source.host ?? "overlay",
|
|
45094
46090
|
spamProtectionEnabled: source.spamProtectionEnabled,
|
|
45095
46091
|
supportEmail: source.supportEmail,
|
|
45096
46092
|
sitePasses: source.sitePasses ?? null,
|
|
45097
46093
|
siteMemberships: source.siteMemberships ?? null,
|
|
45098
46094
|
mailingList: source.mailingList,
|
|
45099
|
-
siteName: source.siteName
|
|
46095
|
+
siteName: source.siteName,
|
|
46096
|
+
offeringNoun: resolveOfferingNoun(source, scopedSourceEvents)
|
|
45100
46097
|
}
|
|
45101
46098
|
};
|
|
45102
46099
|
}
|
|
45103
46100
|
});
|
|
45104
46101
|
function normalizeEventRegistrationEventInput(value) {
|
|
45105
|
-
if (!isRecord$
|
|
46102
|
+
if (!isRecord$6(value)) return value;
|
|
45106
46103
|
return {
|
|
45107
46104
|
...value,
|
|
45108
46105
|
destination: resolveRuntimeEventDestination(value)
|
|
45109
46106
|
};
|
|
45110
46107
|
}
|
|
45111
|
-
function isRecord$
|
|
46108
|
+
function isRecord$6(value) {
|
|
45112
46109
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
45113
46110
|
}
|
|
45114
46111
|
const eventRegistrationBlockDefinition = {
|
|
@@ -45148,7 +46145,7 @@ const eventRegistrationBlockDefinition = {
|
|
|
45148
46145
|
description: "Main heading for the registration form",
|
|
45149
46146
|
required: false,
|
|
45150
46147
|
multiline: false,
|
|
45151
|
-
defaultValue: "
|
|
46148
|
+
defaultValue: ""
|
|
45152
46149
|
},
|
|
45153
46150
|
{
|
|
45154
46151
|
id: "description",
|
|
@@ -45220,11 +46217,11 @@ const eventRegistrationBlockDefinition = {
|
|
|
45220
46217
|
{
|
|
45221
46218
|
id: "buttonText",
|
|
45222
46219
|
type: "text",
|
|
45223
|
-
label: "
|
|
45224
|
-
description: "Text
|
|
46220
|
+
label: "Button text",
|
|
46221
|
+
description: "Text on the booking button",
|
|
45225
46222
|
required: false,
|
|
45226
46223
|
multiline: false,
|
|
45227
|
-
defaultValue: "
|
|
46224
|
+
defaultValue: "Book your place",
|
|
45228
46225
|
maxLength: 40
|
|
45229
46226
|
},
|
|
45230
46227
|
createButtonVariantField()
|
|
@@ -45256,21 +46253,21 @@ const eventRegistrationBlockDefinition = {
|
|
|
45256
46253
|
successMessage: { $bind: { from: "content.successMessage" } },
|
|
45257
46254
|
buttonText: { $bind: {
|
|
45258
46255
|
from: "content.buttonText",
|
|
45259
|
-
fallback: "
|
|
46256
|
+
fallback: "Book your place"
|
|
45260
46257
|
} },
|
|
45261
46258
|
buttonVariant: { $bind: {
|
|
45262
46259
|
from: "content.buttonVariant",
|
|
45263
46260
|
fallback: "primary"
|
|
45264
46261
|
} },
|
|
45265
|
-
overlayEnabled: { $bind: {
|
|
45266
|
-
from: "$root.eventRegistrationOverlayEnabled",
|
|
45267
|
-
fallback: false
|
|
45268
|
-
} },
|
|
45269
46262
|
events: { $bind: { from: "data.events" } },
|
|
45270
46263
|
wholeSeriesRunEvents: { $bind: { from: "data.wholeSeriesRunEvents" } },
|
|
45271
46264
|
loaderFailures: { $bind: { from: "$root.loaderFailures" } },
|
|
45272
46265
|
mailingList: { $bind: { from: "$root.mailingList" } },
|
|
45273
46266
|
siteName: { $bind: { from: "$root.siteName" } },
|
|
46267
|
+
bookingOfferingPresets: { $bind: {
|
|
46268
|
+
from: "$root.bookingOfferingPresets",
|
|
46269
|
+
fallback: []
|
|
46270
|
+
} },
|
|
45274
46271
|
sitePasses: { $bind: { from: "data.sitePasses" } },
|
|
45275
46272
|
siteMemberships: { $bind: { from: "data.siteMemberships" } },
|
|
45276
46273
|
stage: { $bind: {
|
|
@@ -47931,7 +48928,21 @@ const eventCalendarBlockDefinition = {
|
|
|
47931
48928
|
list: { label: "List" }
|
|
47932
48929
|
}
|
|
47933
48930
|
}, eventCalendarContentShape),
|
|
47934
|
-
|
|
48931
|
+
contentNormalizer: {
|
|
48932
|
+
fieldIds: [
|
|
48933
|
+
"variant",
|
|
48934
|
+
"displayMode",
|
|
48935
|
+
"listLayout",
|
|
48936
|
+
"defaultCalendarView",
|
|
48937
|
+
"eventSurface",
|
|
48938
|
+
"filterEventPresets",
|
|
48939
|
+
"scheduleScope",
|
|
48940
|
+
"filterCategoryIds",
|
|
48941
|
+
"filterStaffMemberId",
|
|
48942
|
+
"filterVenueId"
|
|
48943
|
+
],
|
|
48944
|
+
normalize: normalizeEventCalendarContent
|
|
48945
|
+
},
|
|
47935
48946
|
dataSchemas: {
|
|
47936
48947
|
events: publicEventsArraySchema.optional(),
|
|
47937
48948
|
calendarWindow: calendarWindowPageSchema.optional()
|
|
@@ -48404,90 +49415,6 @@ const recurringScheduleBlockDefinition = {
|
|
|
48404
49415
|
} }
|
|
48405
49416
|
};
|
|
48406
49417
|
//#endregion
|
|
48407
|
-
//#region ../blocks/src/system/blocks/offerings-preview/model.ts
|
|
48408
|
-
const OFFERINGS_PREVIEW_DEFAULT_BUTTON_TEXT = "Book";
|
|
48409
|
-
const OFFERINGS_PREVIEW_DEFAULT_EMPTY_MESSAGE = "Nothing scheduled just yet.";
|
|
48410
|
-
const OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS = [
|
|
48411
|
-
{
|
|
48412
|
-
preset: "class",
|
|
48413
|
-
sourceKey: "eventPreset:class",
|
|
48414
|
-
dataKey: "classEvents",
|
|
48415
|
-
label: "Classes"
|
|
48416
|
-
},
|
|
48417
|
-
{
|
|
48418
|
-
preset: "workshop",
|
|
48419
|
-
sourceKey: "eventPreset:workshop",
|
|
48420
|
-
dataKey: "workshopEvents",
|
|
48421
|
-
label: "Workshops"
|
|
48422
|
-
},
|
|
48423
|
-
{
|
|
48424
|
-
preset: "retreat",
|
|
48425
|
-
sourceKey: "eventPreset:retreat",
|
|
48426
|
-
dataKey: "retreatEvents",
|
|
48427
|
-
label: "Retreats"
|
|
48428
|
-
},
|
|
48429
|
-
{
|
|
48430
|
-
preset: "performance",
|
|
48431
|
-
sourceKey: "eventPreset:performance",
|
|
48432
|
-
dataKey: "performanceEvents",
|
|
48433
|
-
label: "Performances"
|
|
48434
|
-
}
|
|
48435
|
-
];
|
|
48436
|
-
OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.preset);
|
|
48437
|
-
const OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS = [...OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => definition.sourceKey), "course"];
|
|
48438
|
-
const OFFERINGS_PREVIEW_SOURCE_KEYS = OFFERINGS_PREVIEW_AUTHORABLE_SOURCE_KEYS;
|
|
48439
|
-
Object.fromEntries(OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.sourceKey, {
|
|
48440
|
-
kind: "eventPreset",
|
|
48441
|
-
preset: definition.preset
|
|
48442
|
-
}]));
|
|
48443
|
-
function isOfferingsPreviewSourceKey(value) {
|
|
48444
|
-
return typeof value === "string" && OFFERINGS_PREVIEW_SOURCE_KEYS.includes(value);
|
|
48445
|
-
}
|
|
48446
|
-
function normalizeOfferingsPreviewGroupOrder(value) {
|
|
48447
|
-
if (value == null) return { kind: "legacy" };
|
|
48448
|
-
if (value.length === 0) return { kind: "default" };
|
|
48449
|
-
const keys = uniqueOfferingsPreviewSourceKeys(value);
|
|
48450
|
-
return keys.length > 0 ? {
|
|
48451
|
-
kind: "custom",
|
|
48452
|
-
keys
|
|
48453
|
-
} : { kind: "default" };
|
|
48454
|
-
}
|
|
48455
|
-
function inferLegacyOfferingsPreviewGroupOrder(overrides) {
|
|
48456
|
-
const keys = uniqueOfferingsPreviewSourceKeys((overrides ?? []).map((override) => override.sourceKey));
|
|
48457
|
-
return keys.length >= 2 ? keys : [];
|
|
48458
|
-
}
|
|
48459
|
-
function normalizeOfferingsPreviewContentForWrite(value) {
|
|
48460
|
-
if (!isRecord$6(value)) return null;
|
|
48461
|
-
const groupOrderValue = value.groupOrder;
|
|
48462
|
-
if (Array.isArray(groupOrderValue)) {
|
|
48463
|
-
const normalized = normalizeOfferingsPreviewGroupOrder(groupOrderValue);
|
|
48464
|
-
return {
|
|
48465
|
-
...value,
|
|
48466
|
-
groupOrder: normalized.kind === "custom" ? normalized.keys : []
|
|
48467
|
-
};
|
|
48468
|
-
}
|
|
48469
|
-
if (groupOrderValue != null) return {
|
|
48470
|
-
...value,
|
|
48471
|
-
groupOrder: []
|
|
48472
|
-
};
|
|
48473
|
-
const legacyOrder = inferLegacyOfferingsPreviewGroupOrder(Array.isArray(value.groupOverrides) ? value.groupOverrides.filter(isRecord$6) : []);
|
|
48474
|
-
return legacyOrder.length > 0 ? {
|
|
48475
|
-
...value,
|
|
48476
|
-
groupOrder: legacyOrder
|
|
48477
|
-
} : value;
|
|
48478
|
-
}
|
|
48479
|
-
function uniqueOfferingsPreviewSourceKeys(values) {
|
|
48480
|
-
const keys = [];
|
|
48481
|
-
for (const value of values) {
|
|
48482
|
-
if (!isOfferingsPreviewSourceKey(value)) continue;
|
|
48483
|
-
if (!keys.includes(value)) keys.push(value);
|
|
48484
|
-
}
|
|
48485
|
-
return keys;
|
|
48486
|
-
}
|
|
48487
|
-
function isRecord$6(value) {
|
|
48488
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
48489
|
-
}
|
|
48490
|
-
//#endregion
|
|
48491
49418
|
//#region ../blocks/src/system/blocks/offerings-preview/fields.ts
|
|
48492
49419
|
const groupOverrideFields = [
|
|
48493
49420
|
{
|
|
@@ -48851,7 +49778,22 @@ const offeringsPreviewEventDataSchemas = Object.fromEntries(OFFERINGS_PREVIEW_EV
|
|
|
48851
49778
|
const offeringsPreviewEventDataLoaders = Object.fromEntries(OFFERINGS_PREVIEW_EVENT_PRESET_DEFINITIONS.map((definition) => [definition.dataKey, eventPresetLoader(definition.preset)]));
|
|
48852
49779
|
const offeringsPreviewBlockDefinition = {
|
|
48853
49780
|
manifest: offeringsPreviewManifest,
|
|
48854
|
-
|
|
49781
|
+
contentNormalizer: {
|
|
49782
|
+
fieldIds: [
|
|
49783
|
+
"displayMode",
|
|
49784
|
+
"heading",
|
|
49785
|
+
"description",
|
|
49786
|
+
"itemLimit",
|
|
49787
|
+
"groupOrder",
|
|
49788
|
+
"groupOverrides",
|
|
49789
|
+
"_cardStyles",
|
|
49790
|
+
"buttonVariant",
|
|
49791
|
+
"buttonText",
|
|
49792
|
+
"emptyMessage",
|
|
49793
|
+
"_sectionStyles"
|
|
49794
|
+
],
|
|
49795
|
+
normalize: normalizeOfferingsPreviewBlockContent
|
|
49796
|
+
},
|
|
48855
49797
|
dataSchemas: {
|
|
48856
49798
|
...offeringsPreviewEventDataSchemas,
|
|
48857
49799
|
routeCandidates: publicRouteCandidatesSchema.optional(),
|
|
@@ -52449,11 +53391,11 @@ function buildNewsletterDisplay(source) {
|
|
|
52449
53391
|
successMessage: DEFAULT_MAILING_LIST_SUCCESS_MESSAGE,
|
|
52450
53392
|
privacyNote: null
|
|
52451
53393
|
};
|
|
52452
|
-
const
|
|
52453
|
-
const choices = resolveRuntimeChoices(
|
|
53394
|
+
const assessment = assessMailingListTargeting(context, source.targeting ?? { mode: "default" });
|
|
53395
|
+
const choices = resolveRuntimeChoices(assessment);
|
|
52454
53396
|
return {
|
|
52455
53397
|
kind: "newsletter-form",
|
|
52456
|
-
availability:
|
|
53398
|
+
availability: assessment.tag === "available" ? "ready" : "unavailable",
|
|
52457
53399
|
className: source.className ?? null,
|
|
52458
53400
|
buttonLabel: form.buttonLabel,
|
|
52459
53401
|
successMessage: form.successMessage,
|
|
@@ -52510,60 +53452,12 @@ function projectNewsletterFormHydrationTarget(source) {
|
|
|
52510
53452
|
default: return assertNever$6(source);
|
|
52511
53453
|
}
|
|
52512
53454
|
}
|
|
52513
|
-
function resolveRuntimeChoices(
|
|
52514
|
-
if (
|
|
52515
|
-
|
|
52516
|
-
|
|
52517
|
-
|
|
52518
|
-
|
|
52519
|
-
id: item.id,
|
|
52520
|
-
label: item.name
|
|
52521
|
-
})) : [];
|
|
52522
|
-
}
|
|
52523
|
-
case "brevo": {
|
|
52524
|
-
const offered = new Set(targeting.selection.offeredListIds);
|
|
52525
|
-
return context.provider.provider === "brevo" ? context.provider.lists.filter((item) => offered.has(item.id)).map((item) => ({
|
|
52526
|
-
id: String(item.id),
|
|
52527
|
-
label: item.name
|
|
52528
|
-
})) : [];
|
|
52529
|
-
}
|
|
52530
|
-
case "mailchimp": {
|
|
52531
|
-
const offered = new Set(targeting.selection.offeredInterestIds);
|
|
52532
|
-
return (context.provider.provider === "mailchimp" ? context.provider.audiences.find((item) => item.id === targeting.audienceId) : void 0)?.interests.filter((item) => offered.has(item.id)).map((item) => ({
|
|
52533
|
-
id: item.id,
|
|
52534
|
-
label: item.name
|
|
52535
|
-
})) ?? [];
|
|
52536
|
-
}
|
|
52537
|
-
}
|
|
52538
|
-
}
|
|
52539
|
-
function runtimeTargetingIsAvailable(context, targeting, choices) {
|
|
52540
|
-
if (context?.tag !== "configured") return false;
|
|
52541
|
-
const provider = context.provider;
|
|
52542
|
-
if (targeting.mode === "default") switch (provider.provider) {
|
|
52543
|
-
case "native": return provider.topics.some((item) => item.id === provider.defaultTopicId);
|
|
52544
|
-
case "brevo": return provider.lists.some((item) => item.id === provider.defaultListId);
|
|
52545
|
-
case "mailchimp": return provider.audiences.some((item) => item.id === provider.defaultAudienceId);
|
|
52546
|
-
}
|
|
52547
|
-
if (targeting.provider !== provider.provider) return false;
|
|
52548
|
-
switch (targeting.provider) {
|
|
52549
|
-
case "native": return provider.provider === "native" && nativeTargetIsAvailable(provider, targeting, choices);
|
|
52550
|
-
case "brevo": return provider.provider === "brevo" && brevoTargetIsAvailable(provider, targeting, choices);
|
|
52551
|
-
case "mailchimp": return provider.provider === "mailchimp" && mailchimpTargetIsAvailable(provider, targeting, choices);
|
|
52552
|
-
}
|
|
52553
|
-
}
|
|
52554
|
-
function nativeTargetIsAvailable(provider, targeting, choices) {
|
|
52555
|
-
const ids = targeting.selection.tag === "fixed" ? targeting.selection.topicIds : targeting.selection.offeredTopicIds;
|
|
52556
|
-
return ids.every((id) => provider.topics.some((item) => item.id === id)) && (targeting.selection.tag !== "visitor_choice" || choices.length === ids.length);
|
|
52557
|
-
}
|
|
52558
|
-
function brevoTargetIsAvailable(provider, targeting, choices) {
|
|
52559
|
-
const ids = targeting.selection.tag === "fixed" ? targeting.selection.listIds : targeting.selection.offeredListIds;
|
|
52560
|
-
return ids.every((id) => provider.lists.some((item) => item.id === id)) && (targeting.selection.tag !== "visitor_choice" || choices.length === ids.length);
|
|
52561
|
-
}
|
|
52562
|
-
function mailchimpTargetIsAvailable(provider, targeting, choices) {
|
|
52563
|
-
const audience = provider.audiences.find((item) => item.id === targeting.audienceId);
|
|
52564
|
-
if (!audience) return false;
|
|
52565
|
-
const ids = targeting.selection.tag === "fixed" ? targeting.selection.interestIds : targeting.selection.offeredInterestIds;
|
|
52566
|
-
return ids.every((id) => audience.interests.some((item) => item.id === id)) && (targeting.selection.tag !== "visitor_choice" || choices.length === ids.length);
|
|
53455
|
+
function resolveRuntimeChoices(assessment) {
|
|
53456
|
+
if (!("value" in assessment) || assessment.value.mode !== "custom" || !("selectedChoices" in assessment.value) || assessment.value.targeting.selection.tag !== "visitor_choice") return [];
|
|
53457
|
+
return assessment.value.selectedChoices.map((item) => ({
|
|
53458
|
+
id: String(item.id),
|
|
53459
|
+
label: item.name
|
|
53460
|
+
}));
|
|
52567
53461
|
}
|
|
52568
53462
|
function parseRequiredMailingListSignupBlockId(value) {
|
|
52569
53463
|
const parsed = parseMailingListBlockId(value);
|
|
@@ -52672,6 +53566,10 @@ function sanitizeNewsletterSignupPublicContent(content) {
|
|
|
52672
53566
|
}
|
|
52673
53567
|
const newsletterSignupBlockDefinition = {
|
|
52674
53568
|
manifest: newsletterSignupManifest,
|
|
53569
|
+
contentNormalizer: {
|
|
53570
|
+
fieldIds: ["targeting"],
|
|
53571
|
+
normalize: normalizeMailingListBlockContent
|
|
53572
|
+
},
|
|
52675
53573
|
runtime: newsletterFormBlockRuntime
|
|
52676
53574
|
};
|
|
52677
53575
|
//#endregion
|
|
@@ -53404,7 +54302,20 @@ const locationMapBlockDefinition = {
|
|
|
53404
54302
|
})], { gap: "md" })
|
|
53405
54303
|
})
|
|
53406
54304
|
}),
|
|
53407
|
-
|
|
54305
|
+
contentNormalizer: {
|
|
54306
|
+
fieldIds: [
|
|
54307
|
+
"heading",
|
|
54308
|
+
"locationSource",
|
|
54309
|
+
"venueId",
|
|
54310
|
+
"location",
|
|
54311
|
+
"showAddressText",
|
|
54312
|
+
"showDirections",
|
|
54313
|
+
"directionsLabel",
|
|
54314
|
+
"zoom",
|
|
54315
|
+
"heightPx"
|
|
54316
|
+
],
|
|
54317
|
+
normalize: normalizeLocationMapContent
|
|
54318
|
+
}
|
|
53408
54319
|
};
|
|
53409
54320
|
//#endregion
|
|
53410
54321
|
//#region ../blocks/src/system/blocks/index.ts
|
|
@@ -54609,17 +55520,7 @@ const linksTransforms = [{
|
|
|
54609
55520
|
id: "links.resolve",
|
|
54610
55521
|
kind: "formatter",
|
|
54611
55522
|
summary: "Resolve LinkValue objects to href strings using the route map",
|
|
54612
|
-
run: (value, _options, context) =>
|
|
54613
|
-
if (!value || typeof value !== "object") return null;
|
|
54614
|
-
const link = value;
|
|
54615
|
-
const kind = typeof link.kind === "string" ? link.kind : null;
|
|
54616
|
-
if (kind === "internal") return resolveInternalLink(link, context);
|
|
54617
|
-
if (kind === "page") return resolvePageLink(link, context);
|
|
54618
|
-
if (kind === "entry") return resolveEntryLink(link, context);
|
|
54619
|
-
if (kind === "external" || kind === "url") return resolveExternalLink(link);
|
|
54620
|
-
if (!kind && typeof link.href === "string") return resolveExternalLink(link);
|
|
54621
|
-
return null;
|
|
54622
|
-
}
|
|
55523
|
+
run: (value, _options, context) => resolveAuthoredLinkHref(value, context)
|
|
54623
55524
|
}, {
|
|
54624
55525
|
id: "links.label",
|
|
54625
55526
|
kind: "formatter",
|
|
@@ -54646,6 +55547,21 @@ const linksTransforms = [{
|
|
|
54646
55547
|
return null;
|
|
54647
55548
|
}
|
|
54648
55549
|
}];
|
|
55550
|
+
function resolveAuthoredLinkHref(value, context = {}) {
|
|
55551
|
+
if (!value || typeof value !== "object") return null;
|
|
55552
|
+
const link = value;
|
|
55553
|
+
switch (link.kind) {
|
|
55554
|
+
case "internal": return resolveInternalLink(link, context);
|
|
55555
|
+
case "page": return resolvePageLink(link, context);
|
|
55556
|
+
case "entry": return resolveEntryLink(link, context);
|
|
55557
|
+
case "external":
|
|
55558
|
+
case "url": return resolveExternalLink(link);
|
|
55559
|
+
default: return resolvePreResolvedLink(link);
|
|
55560
|
+
}
|
|
55561
|
+
}
|
|
55562
|
+
function resolvePreResolvedLink(link) {
|
|
55563
|
+
return !(typeof link.kind === "string" ? link.kind : null) && typeof link.href === "string" ? resolveExternalLink(link) : null;
|
|
55564
|
+
}
|
|
54649
55565
|
const eventCalendarSelectionParam = {
|
|
54650
55566
|
id: "events.calendarSelectionParam",
|
|
54651
55567
|
kind: "formatter",
|