@riverbankcms/sdk 0.136.0 → 0.138.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 +109 -0
- package/README.md +7 -4
- package/dist/{PreviewEditorSidebar-BU5ZlhQR.mjs → PreviewEditorSidebar-BVPur_CU.mjs} +12 -18
- package/dist/{PreviewEditorUI-9XkHL-bC.mjs → PreviewEditorUI-DLhWX8oh.mjs} +3 -3
- package/dist/{PreviewQueryProvider-wbEpXryy.mjs → PreviewQueryProvider-BguJY1SW.mjs} +1 -1
- package/dist/{SdkPreviewModeRuntime-CnWmj-2B.mjs → SdkPreviewModeRuntime-Tda6qw4z.mjs} +1375 -495
- package/dist/{SiteChromeCustomizeContext-B6d5zkog.mjs → SiteChromeCustomizeContext-BHFgMjde.mjs} +35665 -33602
- package/dist/_dts/ai/src/contracts/proposals.d.ts +7226 -3057
- package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +1223 -811
- package/dist/_dts/ai/src/designer/themePatch.d.ts +5 -10
- package/dist/_dts/api/src/accessAdmin.d.ts +16 -18
- package/dist/_dts/api/src/accountApi.d.ts +49 -2
- package/dist/_dts/api/src/appointmentServiceContracts.d.ts +83 -0
- package/dist/_dts/api/src/appointmentServiceLocation.d.ts +12 -0
- package/dist/_dts/api/src/appointmentServiceVisibility.d.ts +14 -0
- package/dist/_dts/api/src/appointmentSetup.d.ts +8 -0
- package/dist/_dts/api/src/bookingConfig.d.ts +35 -87
- package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +1 -1
- package/dist/_dts/api/src/bookingOperations.d.ts +2 -69
- package/dist/_dts/api/src/bookingRecords.d.ts +2 -2
- package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +2 -2
- package/dist/_dts/api/src/bookingServicePricing.d.ts +47 -0
- package/dist/_dts/api/src/bookings.d.ts +2 -2
- package/dist/_dts/api/src/cache-tags.d.ts +7 -2
- package/dist/_dts/api/src/common/index.d.ts +1 -0
- package/dist/_dts/api/src/common/zodFieldErrors.d.ts +34 -0
- package/dist/_dts/api/src/communications.d.ts +14 -8
- package/dist/_dts/api/src/contentRuntime.d.ts +3 -6
- package/dist/_dts/api/src/domainConnection.d.ts +41 -0
- package/dist/_dts/api/src/endpoints.d.ts +1636 -1637
- package/dist/_dts/api/src/eventAttendanceLabels.d.ts +2 -2
- package/dist/_dts/api/src/eventManagementContracts.d.ts +10 -14
- package/dist/_dts/api/src/index.d.ts +11 -9
- package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
- package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -1
- package/dist/_dts/api/src/media.d.ts +19 -2
- package/dist/_dts/api/src/occurrenceScheduling.d.ts +1 -1
- package/dist/_dts/api/src/participantMessaging.d.ts +3 -3
- package/dist/_dts/api/src/public/endpoints.d.ts +1 -1
- package/dist/_dts/api/src/publicBookingAvailabilityEndpointDefinitions.d.ts +62 -0
- package/dist/_dts/api/src/publicBookingService.d.ts +109 -2
- package/dist/_dts/api/src/publicEventCheckoutEndpointDefinitions.d.ts +27 -0
- package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +7 -0
- package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +2 -1
- package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +30 -148
- package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +8 -26
- package/dist/_dts/api/src/publicExperience/siteEndpoints.d.ts +5 -13
- package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +2 -3
- package/dist/_dts/api/src/schemas/admin-allowed-domains.d.ts +76 -0
- package/dist/_dts/api/src/schemas/admin-observability-logs.d.ts +61 -0
- package/dist/_dts/api/src/schemas/admin-users.d.ts +80 -0
- package/dist/_dts/api/src/schemas/newsletter-memberships.d.ts +98 -0
- package/dist/_dts/api/src/schemas/sdk-entries.d.ts +128 -0
- package/dist/_dts/api/src/schemas/site-api-keys.d.ts +112 -0
- package/dist/_dts/api/src/schemas/support.d.ts +35 -0
- package/dist/_dts/api/src/sdk-event-booking-offer.d.ts +14 -0
- package/dist/_dts/api/src/sdk-event-payment-terms.d.ts +4 -16
- package/dist/_dts/api/src/sdk-event-upsert.d.ts +11 -21
- package/dist/_dts/api/src/sdkContracts.d.ts +8 -23
- package/dist/_dts/api/src/sdkManagedEventContracts.d.ts +37 -0
- package/dist/_dts/api/src/sdkMediaContracts.d.ts +40 -0
- package/dist/_dts/api/src/sdkMediaEndpointDefinitions.d.ts +66 -0
- package/dist/_dts/api/src/sdkThemeWire.d.ts +157 -146
- package/dist/_dts/api/src/siteInfrastructure.d.ts +37 -37
- package/dist/_dts/api/src/siteManagementEndpoints.d.ts +35 -54
- package/dist/_dts/api/src/siteOnboarding.d.ts +3 -3
- package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +38 -16
- package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +37 -17
- package/dist/_dts/api/src/types.d.ts +2 -2
- package/dist/_dts/api/src/{wholeSeriesOfferings.d.ts → wholeSeriesRuns.d.ts} +11 -67
- package/dist/_dts/block-form/src/FormRenderer.d.ts +3 -1
- package/dist/_dts/block-form/src/backend/store-backend.d.ts +2 -1
- package/dist/_dts/block-form/src/backend/types.d.ts +2 -0
- package/dist/_dts/block-form/src/context/FormFocusContext.d.ts +7 -0
- package/dist/_dts/block-form/src/index.d.ts +2 -0
- package/dist/_dts/block-form/src/manifest/ManifestForm.d.ts +2 -1
- package/dist/_dts/block-form/src/utils/promotedFieldBackend.d.ts +8 -0
- package/dist/_dts/block-form/src/utils/promotedFieldPlan.d.ts +18 -0
- package/dist/_dts/block-form/src/utils/resolvePromotedFields.d.ts +8 -1
- package/dist/_dts/blocks/src/BlockErrorBoundary.d.ts +46 -0
- package/dist/_dts/blocks/src/PageRenderer.d.ts +2 -141
- package/dist/_dts/blocks/src/contracts/index.d.ts +2 -0
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +12 -6
- package/dist/_dts/blocks/src/index.d.ts +1 -0
- package/dist/_dts/blocks/src/pageRenderAudience.d.ts +54 -0
- package/dist/_dts/blocks/src/pageRenderDiagnostics.d.ts +26 -0
- package/dist/_dts/blocks/src/pageRenderPlan.d.ts +116 -0
- package/dist/_dts/blocks/src/pageRenderPreparation.d.ts +109 -0
- package/dist/_dts/blocks/src/pageRendererBoundaries.d.ts +1 -0
- package/dist/_dts/blocks/src/pageRendererContracts.d.ts +154 -0
- package/dist/_dts/blocks/src/portal/types.d.ts +1 -1
- package/dist/_dts/blocks/src/server.d.ts +1 -0
- package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +12 -20
- package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +1 -1
- package/dist/_dts/blocks/src/system/blocks/events/eventCalendarDataLoaders.d.ts +3 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/calendarWindow.d.ts +95 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/index.d.ts +1 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/runGrouping.d.ts +37 -0
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +1046 -773
- package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +59 -46
- package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +3 -3
- package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +161 -161
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +13 -6
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/scheduleSummary.d.ts +10 -4
- package/dist/_dts/blocks/src/system/constants/buttonRoles.d.ts +2 -2
- package/dist/_dts/blocks/src/system/constants/events.d.ts +4 -0
- package/dist/_dts/blocks/src/system/customize/facets.d.ts +4 -4
- package/dist/_dts/blocks/src/system/data/loaderEndpoints.d.ts +1 -1
- package/dist/_dts/blocks/src/system/data/publicLoaderCachePolicy.d.ts +5 -9
- package/dist/_dts/blocks/src/system/manifest/schema.d.ts +83 -83
- package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +12 -3
- package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +8 -8
- package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/api/types/core.d.ts +13 -0
- package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +12 -20
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +32 -37
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +15 -18
- package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +11 -8
- package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +38 -22
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessEventRegistrationFlow.d.ts +7 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-details/WholeSeriesPricingDisplay.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +16 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ErrorStep.d.ts +3 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationWizardActions.d.ts +4 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentSelectionStep.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +5 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventScope.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationCompletion.d.ts +15 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDerivations.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorPresentation.d.ts +5 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +25 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.d.ts +14 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationSurface.d.ts +3 -21
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.d.ts +4 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/siteCreditPreview.d.ts +0 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.d.ts +14 -16
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +13 -15
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +7 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +9 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +25 -23
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.d.ts +2 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +11 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +8 -13
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +5 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +11 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/capacity.d.ts +164 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/cta.d.ts +29 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +47 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/index.d.ts +14 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/people.d.ts +6 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/pricing.d.ts +24 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/OfferingTitle.d.ts +11 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekAgendaView.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +1080 -560
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventProductEligibility.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/index.d.ts +3 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listingLayout.d.ts +23 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/offerings-preview.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +7 -7
- package/dist/_dts/blocks/src/system/transforms/registry/eventCalendar.d.ts +11 -0
- package/dist/_dts/commerce/src/moneyReport.d.ts +1 -1
- package/dist/_dts/commerce/src/purchase/checkoutErrorCodes.d.ts +1 -1
- package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +57 -0
- package/dist/_dts/commerce/src/purchase/eventOrderOptionSnapshot.d.ts +3 -0
- package/dist/_dts/commerce/src/purchase/index.d.ts +1 -0
- package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +6 -3
- package/dist/_dts/commerce/src/purchase/types.d.ts +3 -2
- package/dist/_dts/commerce/src/waitlists.d.ts +1 -1
- package/dist/_dts/content-editor/src/controller/EntryControllerProvider.d.ts +4 -0
- package/dist/_dts/content-editor/src/controller/useBlockedPublishPlan.d.ts +11 -0
- package/dist/_dts/content-editor/src/hooks/applyBlockedPublishPlan.d.ts +1 -1
- package/dist/_dts/content-editor/src/hooks/blockedPublishPlan.d.ts +13 -5
- package/dist/_dts/content-editor/src/hooks/useEntryActions.d.ts +5 -1
- package/dist/_dts/content-editor/src/hooks/validateBlocksForPublish.d.ts +34 -2
- package/dist/_dts/content-editor/src/index.d.ts +2 -1
- package/dist/_dts/content-editor/src/ui/blockValidationManifestRegistry.d.ts +2 -0
- package/dist/_dts/content-editor/src/ui/editorUiStore.d.ts +4 -2
- package/dist/_dts/content-editor/src/ui/stores/types.d.ts +27 -5
- package/dist/_dts/content-model/src/content-types/schema.d.ts +3 -3
- package/dist/_dts/content-model/src/templates/defaults.d.ts +11 -0
- package/dist/_dts/core/src/branded.d.ts +28 -9
- package/dist/_dts/core/src/event-booking-offer-parser.d.ts +82 -0
- package/dist/_dts/core/src/event-booking-offer.d.ts +89 -0
- package/dist/_dts/core/src/event-page-surface-subject.d.ts +81 -4
- package/dist/_dts/core/src/event-pricing.d.ts +81 -89
- package/dist/_dts/core/src/index.d.ts +3 -0
- package/dist/_dts/core/src/non-empty-array.d.ts +3 -0
- package/dist/_dts/core/src/whole-series-run-schedule.d.ts +92 -0
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +495 -279
- package/dist/_dts/db/src/index.d.ts +1 -0
- package/dist/_dts/db/src/utils/postgrestFilter.d.ts +2 -0
- package/dist/_dts/editor-blocks/src/BlockForm.d.ts +2 -6
- package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +1 -1
- package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +2 -2
- package/dist/_dts/editor-blocks/src/block-editor/BlockSettingsModal.d.ts +4 -2
- package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockValidationManifests.d.ts +1 -0
- package/dist/_dts/editor-blocks/src/block-editor/types.d.ts +22 -7
- package/dist/_dts/editor-blocks/src/block-editor/useSettingsFieldFocus.d.ts +18 -0
- package/dist/_dts/media-core/src/bulkDeletePlanning.d.ts +4 -0
- package/dist/_dts/media-core/src/fileDomain.d.ts +3 -0
- package/dist/_dts/preview-next/src/client/blocks/previewBatchLoaderParams.d.ts +2 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
- package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +3 -2
- package/dist/_dts/preview-next/src/client/preview/siteChromeBrandPreferences.d.ts +1 -1
- package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +2 -0
- package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlSaveRequest.d.ts +51 -0
- package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +24 -2
- package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +23 -1
- package/dist/_dts/preview-next/src/client/preview/usePersistedHeaderPreferences.d.ts +8 -0
- package/dist/_dts/sdk/src/client/{eventSubrouteReadOperations.d.ts → publicEventReadOperations.d.ts} +4 -3
- package/dist/_dts/sdk/src/client/types.d.ts +6 -10
- package/dist/_dts/sdk/src/config/types.d.ts +1 -1
- package/dist/_dts/sdk/src/config/validation.d.ts +3 -3
- package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +5 -0
- package/dist/_dts/sdk/src/data/prefetchBlockData.d.ts +2 -3
- package/dist/_dts/sdk/src/manifest/passes/pass1-fields.d.ts +8 -8
- package/dist/_dts/sdk/src/next/tags.d.ts +5 -8
- package/dist/_dts/sdk/src/public-api/contracts.d.ts +2 -26
- package/dist/_dts/sdk/src/rendering/helpers/footerPageOutline.d.ts +9 -1
- package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
- package/dist/_dts/sdk/src/rendering/islands/types.d.ts +6 -53
- package/dist/_dts/sdk/src/rendering/server.d.ts +1 -0
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/theme-core/src/accordions/types.d.ts +5 -5
- package/dist/_dts/theme-core/src/buttons/styles/recipes/flatInk.d.ts +25 -25
- package/dist/_dts/theme-core/src/buttons/styles/registry.d.ts +25 -25
- package/dist/_dts/theme-core/src/buttons/styles/selection.d.ts +7 -7
- package/dist/_dts/theme-core/src/buttons/types.d.ts +22 -22
- package/dist/_dts/theme-core/src/cards/types.d.ts +49 -49
- package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
- package/dist/_dts/theme-core/src/gradients/types.d.ts +5 -0
- package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +26 -3
- package/dist/_dts/theme-core/src/inputs/types.d.ts +2 -2
- package/dist/_dts/theme-core/src/interactive/baseSchema.d.ts +1 -1
- package/dist/_dts/theme-core/src/mock-themes/all.d.ts +195 -195
- package/dist/_dts/theme-core/src/navigation/types.d.ts +3 -3
- package/dist/_dts/theme-core/src/palette/colors.d.ts +1 -1
- package/dist/_dts/theme-core/src/palette/curated/types.d.ts +2 -2
- package/dist/_dts/theme-core/src/schema.d.ts +258 -257
- package/dist/_dts/theme-core/src/shared/componentStyles.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +2 -2
- package/dist/_dts/theme-core/src/site-styles/cardRoleVocabulary.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/compilationPlan.d.ts +43 -3
- package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +10 -0
- package/dist/_dts/theme-core/src/site-styles/designState.d.ts +4 -4
- package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +2 -2
- package/dist/_dts/theme-core/src/site-styles/headerBrandPresentation.d.ts +63 -0
- package/dist/_dts/theme-core/src/site-styles/headerBytesComparison.d.ts +30 -0
- package/dist/_dts/theme-core/src/site-styles/headerInteractionPalette.d.ts +50 -1
- package/dist/_dts/theme-core/src/site-styles/headerLayoutCatalog.d.ts +48 -9
- package/dist/_dts/theme-core/src/site-styles/headerPreferences.d.ts +162 -0
- package/dist/_dts/theme-core/src/site-styles/headerPreferencesPersistence.d.ts +73 -0
- package/dist/_dts/theme-core/src/site-styles/headerRecompile.d.ts +118 -0
- package/dist/_dts/theme-core/src/site-styles/headerStyleCompiler.d.ts +10 -1
- package/dist/_dts/theme-core/src/site-styles/headerStyleDefaults.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/headerStyleRecipe.d.ts +7 -0
- package/dist/_dts/theme-core/src/site-styles/index.d.ts +5 -0
- package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/siteChromeBackgrounds.d.ts +20 -1
- package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +43 -2
- package/dist/_dts/theme-core/src/site-styles/tokenRecipes.d.ts +1 -1
- package/dist/_dts/theme-core/src/tokens/themeColorTokens.d.ts +3 -3
- package/dist/_dts/ui/src/badge.d.ts +1 -1
- package/dist/_dts/ui/src/button.d.ts +2 -2
- package/dist/client/{BookingConsentAgreement-DCch21a6.mjs → BookingConsentAgreement-DQUik1Mx.mjs} +2 -2
- package/dist/client/{DiscountCodeDisclosure-DIj1T59K.mjs → DiscountCodeDisclosure-CU67Q4vH.mjs} +1 -1
- package/dist/client/{EventCombined.client-BWVNlXTx.mjs → EventCombined.client-a02TXUgg.mjs} +233 -348
- package/dist/client/{EventListing.client-DVFCDe3i.mjs → EventListing.client-99qx7jFl.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-BY5mIHw9.mjs → LeafletStaticMap-CWzcq73L.mjs} +1 -1
- package/dist/client/{accordion-CK29E8rG.mjs → accordion-D1nb3-Oj.mjs} +1 -1
- package/dist/client/{bookingForm-DFvnet-N.mjs → bookingForm-BGrmLhaO.mjs} +5 -5
- package/dist/client/bookings.mjs +10555 -10475
- package/dist/client/{carousel-BVU5NQlb.mjs → carousel-DSmOx3ad.mjs} +1 -1
- package/dist/client/{cart-BNItcZVa.mjs → cart-COWeOIUk.mjs} +3 -3
- package/dist/client/{checkout-Bu6iCdkP.mjs → checkout-CeysaIJK.mjs} +3 -3
- package/dist/client/client.mjs +58968 -57441
- package/dist/client/{context-BImarOAq.mjs → context-DBzX85Xc.mjs} +46 -18
- package/dist/client/dates-DCYhZBlW.mjs +264 -0
- package/dist/client/{eventCalendar-DS2h-UXD.mjs → eventCalendar-BgsN73Ul.mjs} +21 -44
- package/dist/client/{eventCombined-Drt4Oq9p.mjs → eventCombined-DcZQAMQP.mjs} +3 -3
- package/dist/client/{eventDetails-Bl2vWgTX.mjs → eventDetails-BWwGJ54l.mjs} +131 -51
- package/dist/client/{eventListing-CS7PHY7v.mjs → eventListing-DqYqV8vp.mjs} +3 -3
- package/dist/client/{eventRegistration-D-j8eNy2.mjs → eventRegistration-DQGDgu_e.mjs} +1122 -803
- package/dist/client/{form-RMpoLTyr.mjs → form-ClfpasVT.mjs} +2 -2
- package/dist/client/{headerSection-BYE3Lb3k.mjs → headerSection-BuOMe98N.mjs} +2 -2
- package/dist/client/hooks.mjs +9630 -9526
- package/dist/client/{locationMap-BxSr7Kkh.mjs → locationMap-CEqu_sfa.mjs} +2 -2
- package/dist/client/{newsletterForm-DerbXwFC.mjs → newsletterForm-IbrHjMxy.mjs} +2 -2
- package/dist/client/pricing-xj7MPZlK.mjs +314 -0
- package/dist/client/{productDetail-4SZCLhAf.mjs → productDetail-vxqTt5Xj.mjs} +3 -3
- package/dist/client/{productList-D7AP4GNq.mjs → productList-OTdZu8sb.mjs} +3 -3
- package/dist/client/{propsDecoder-pzBeCh14.mjs → propsDecoder-CY9gGEF7.mjs} +786 -1194
- package/dist/client/rendering/client.mjs +11481 -10469
- package/dist/client/rendering/islands.mjs +17 -17
- package/dist/client/rendering.mjs +26871 -25232
- package/dist/client/{scrollToBlock-CduAKf8T.mjs → scrollToBlock--BFV6kl-.mjs} +1 -1
- package/dist/client/{shop-Cp5p_kGe.mjs → shop-CP4YbDL9.mjs} +6 -6
- package/dist/client/{shop-commerce-DicXYaYX.mjs → shop-commerce-APs4XBXE.mjs} +5 -5
- package/dist/client/{shop-commerce-store-CGWnpY4K.mjs → shop-commerce-store-CAVLxLFr.mjs} +1 -1
- package/dist/client/{shopShared-BDf9ljkm.mjs → shopShared-BnSRrwXI.mjs} +3 -3
- package/dist/client/{useEventFilters-DeeyGYuk.mjs → useEventFilters-1a1by4c8.mjs} +33 -18
- package/dist/preview-next/before-render.mjs +186 -148
- package/dist/preview-next/client/runtime.mjs +4 -4
- package/dist/preview-next/keepAlive.mjs +186 -148
- package/dist/preview-next/middleware.mjs +186 -148
- package/dist/{previewAuthStore-DbqBol0V.mjs → previewAuthStore-BkEgnYPP.mjs} +186 -148
- package/dist/{sdk-runtime-19MO27F0.mjs → sdk-runtime-DwGfsT0S.mjs} +2 -2
- package/dist/{separator-DaPLtJ1f.mjs → separator-BeqDLneQ.mjs} +1 -1
- package/dist/server/components.mjs +53243 -51879
- package/dist/server/config-validation.mjs +1015 -906
- package/dist/server/config.mjs +1019 -910
- package/dist/server/data.mjs +10304 -10200
- package/dist/server/index.mjs +217 -198
- package/dist/server/next/tags.mjs +18 -4
- package/dist/server/next.mjs +62787 -61617
- package/dist/server/page-converter.mjs +797 -917
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +52557 -51365
- package/dist/server/rendering.mjs +54373 -53054
- package/dist/server/routing.mjs +13274 -13142
- package/dist/server/server.mjs +1076 -1154
- package/dist/server/theme-bridge.mjs +69 -9
- package/dist/server/theme.mjs +27 -8
- package/dist/styles/index.css +32 -1
- package/package.json +1 -1
- package/dist/_dts/api/src/publicExperience/wholeSeriesEndpoints.d.ts +0 -65
- package/dist/_dts/api/src/publicWholeSeriesEndpointDefinitions.d.ts +0 -20
- package/dist/_dts/api/src/sdk-event-pricing.d.ts +0 -61
- package/dist/_dts/blocks/src/system/blocks/events/whole-series/index.d.ts +0 -3
- package/dist/_dts/blocks/src/system/blocks/events/whole-series/pricing.d.ts +0 -50
- package/dist/_dts/blocks/src/system/blocks/events/whole-series/schemas.d.ts +0 -135
- package/dist/_dts/blocks/src/system/blocks/events/whole-series/types.d.ts +0 -87
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCapacity.d.ts +0 -48
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/pricing.d.ts +0 -17
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +0 -100
- package/dist/_dts/sdk/src/client/wholeSeriesReadOperations.d.ts +0 -11
- package/dist/_dts/sdk/src/public-api/wholeSeriesContracts.d.ts +0 -2
- /package/dist/_dts/blocks/src/system/runtime/nodes/events/{shared → domain}/destination.d.ts +0 -0
|
@@ -53,53 +53,80 @@ function formatCurrencyAmount(amountCents, currency, options) {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
//#endregion
|
|
56
|
+
//#region ../core/src/planner.ts
|
|
57
|
+
/** Default clock for production callers that do not inject time explicitly. */
|
|
58
|
+
const systemPlanningClock = { now: () => Date.now() };
|
|
59
|
+
/** Resolve current time as a Date from an explicit Date, injected clock, or system clock. */
|
|
60
|
+
function resolvePlanningNowDate(input = {}) {
|
|
61
|
+
if (input.now !== void 0) return input.now;
|
|
62
|
+
return new Date((input.clock ?? systemPlanningClock).now());
|
|
63
|
+
}
|
|
64
|
+
//#endregion
|
|
56
65
|
//#region ../core/src/event-pricing.ts
|
|
66
|
+
/** Capacity closes booking, but does not make an otherwise eligible price unknown. */
|
|
67
|
+
function isPublicEventPricingOptionDisplayable(option) {
|
|
68
|
+
if (!option.isActive) return false;
|
|
69
|
+
if (option.availability.kind === "available") return true;
|
|
70
|
+
const reason = option.availability.reason;
|
|
71
|
+
switch (reason) {
|
|
72
|
+
case "sold_out":
|
|
73
|
+
case "overallCapacityUnavailable": return true;
|
|
74
|
+
case "inactive":
|
|
75
|
+
case "not_on_sale_yet":
|
|
76
|
+
case "sale_ended":
|
|
77
|
+
case "attendance_mode_unavailable": return false;
|
|
78
|
+
default: return assertNever$2(reason);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
57
81
|
function publicEventPricingDisplay(pricing) {
|
|
58
|
-
|
|
82
|
+
switch (pricing.kind) {
|
|
83
|
+
case "free":
|
|
84
|
+
case "single":
|
|
85
|
+
case "sliding_scale": return canonicalEventPricingDisplay(pricing);
|
|
86
|
+
case "tiered": return resolvePricingOptionsPriceDisplay({
|
|
87
|
+
options: pricing.options.filter(isPublicEventPricingOptionDisplayable),
|
|
88
|
+
currency: pricing.currency,
|
|
89
|
+
purpose: "configured"
|
|
90
|
+
});
|
|
91
|
+
case "external": return {
|
|
92
|
+
kind: "external",
|
|
93
|
+
label: pricing.label
|
|
94
|
+
};
|
|
95
|
+
}
|
|
59
96
|
}
|
|
60
97
|
function publicEventPricingType(pricing) {
|
|
61
98
|
switch (pricing.kind) {
|
|
62
|
-
case "
|
|
63
|
-
case "
|
|
64
|
-
case "
|
|
65
|
-
case "
|
|
66
|
-
case "sliding_scale":
|
|
67
|
-
case "whole_series": return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
|
|
99
|
+
case "free": return "free";
|
|
100
|
+
case "single":
|
|
101
|
+
case "tiered":
|
|
102
|
+
case "sliding_scale": return isFreePublicEventPriceDisplay(publicEventPricingDisplay(pricing)) ? "free" : "paid";
|
|
68
103
|
case "external": return "external";
|
|
69
104
|
}
|
|
70
105
|
}
|
|
71
106
|
function publicEventPricingCurrency(pricing) {
|
|
72
107
|
switch (pricing.kind) {
|
|
73
|
-
case "
|
|
74
|
-
case "
|
|
75
|
-
case "
|
|
76
|
-
case "ticket_types":
|
|
108
|
+
case "free":
|
|
109
|
+
case "single":
|
|
110
|
+
case "tiered":
|
|
77
111
|
case "sliding_scale": return pricing.currency;
|
|
78
|
-
case "whole_series": return pricing.display.display.currency;
|
|
79
112
|
case "external": return null;
|
|
80
113
|
}
|
|
81
114
|
}
|
|
82
|
-
function
|
|
83
|
-
return pricing.kind === "single_paid" ? pricing.amount : null;
|
|
84
|
-
}
|
|
85
|
-
function publicEventPricingMode(pricing) {
|
|
115
|
+
function publicEventPricingStrategy(pricing) {
|
|
86
116
|
switch (pricing.kind) {
|
|
87
|
-
case "
|
|
88
|
-
case "
|
|
89
|
-
case "
|
|
117
|
+
case "single": return "single";
|
|
118
|
+
case "free": return "free";
|
|
119
|
+
case "tiered": return "tiered";
|
|
90
120
|
case "sliding_scale": return "sliding_scale";
|
|
91
|
-
case "drop_in":
|
|
92
|
-
case "whole_series":
|
|
93
121
|
case "external": return;
|
|
94
122
|
}
|
|
95
123
|
}
|
|
96
|
-
function
|
|
97
|
-
return pricing.kind === "
|
|
124
|
+
function publicEventPricingOptions(pricing) {
|
|
125
|
+
return pricing.kind === "tiered" ? pricing.options : [];
|
|
98
126
|
}
|
|
99
127
|
function isFreePublicEventPriceDisplay(display) {
|
|
100
128
|
switch (display.kind) {
|
|
101
129
|
case "free": return true;
|
|
102
|
-
case "whole_series": return display.display.kind === "free";
|
|
103
130
|
case "exact":
|
|
104
131
|
case "from":
|
|
105
132
|
case "range":
|
|
@@ -108,15 +135,77 @@ function isFreePublicEventPriceDisplay(display) {
|
|
|
108
135
|
case "external": return false;
|
|
109
136
|
}
|
|
110
137
|
}
|
|
111
|
-
function
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
138
|
+
function resolvePricingOptionSaleWindowState(option, now) {
|
|
139
|
+
if (option.saleStartsAt !== null && option.saleStartsAt !== void 0 && new Date(option.saleStartsAt) > now) return "not_started";
|
|
140
|
+
if (option.saleEndsAt !== null && option.saleEndsAt !== void 0 && new Date(option.saleEndsAt) < now) return "ended";
|
|
141
|
+
return "open";
|
|
142
|
+
}
|
|
143
|
+
function resolvePricingOptionsPriceDisplay(input) {
|
|
144
|
+
const now = input.purpose === "available_now" ? resolvePlanningNowDate({
|
|
145
|
+
now: input.now,
|
|
146
|
+
clock: input.clock
|
|
147
|
+
}) : null;
|
|
148
|
+
const amounts = input.options.filter((option) => option.isActive && (now === null || resolvePricingOptionSaleWindowState(option, now) === "open")).map((option) => option.priceAmount);
|
|
149
|
+
return amounts.length === 0 ? {
|
|
150
|
+
kind: "unavailable",
|
|
151
|
+
currency: input.currency
|
|
152
|
+
} : amountRangeDisplay(amounts, input.currency);
|
|
153
|
+
}
|
|
154
|
+
function amountRangeDisplay(amounts, currency) {
|
|
155
|
+
const minAmount = Math.min(...amounts);
|
|
156
|
+
const maxAmount = Math.max(...amounts);
|
|
157
|
+
if (minAmount === maxAmount) return minAmount === 0 ? {
|
|
158
|
+
kind: "free",
|
|
159
|
+
currency
|
|
160
|
+
} : {
|
|
161
|
+
kind: "exact",
|
|
162
|
+
amount: minAmount,
|
|
163
|
+
currency
|
|
164
|
+
};
|
|
165
|
+
if (minAmount === 0) {
|
|
166
|
+
const paidAmounts = amounts.filter((amount) => amount > 0);
|
|
167
|
+
return {
|
|
168
|
+
kind: "mixed",
|
|
169
|
+
paidFromAmount: Math.min(...paidAmounts),
|
|
170
|
+
paidToAmount: maxAmount,
|
|
171
|
+
currency
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
return {
|
|
175
|
+
kind: "range",
|
|
176
|
+
minAmount,
|
|
177
|
+
maxAmount,
|
|
178
|
+
currency
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/** Derives configured price presentation directly from canonical pricing. */
|
|
182
|
+
function canonicalEventPricingDisplay(pricing) {
|
|
183
|
+
switch (pricing.kind) {
|
|
184
|
+
case "free": return {
|
|
185
|
+
kind: "free",
|
|
186
|
+
currency: pricing.currency
|
|
187
|
+
};
|
|
188
|
+
case "single": return {
|
|
189
|
+
kind: "exact",
|
|
190
|
+
amount: pricing.amount,
|
|
191
|
+
currency: pricing.currency
|
|
192
|
+
};
|
|
193
|
+
case "sliding_scale": return pricing.minimum === pricing.maximum ? {
|
|
194
|
+
kind: "exact",
|
|
195
|
+
amount: pricing.maximum,
|
|
196
|
+
currency: pricing.currency
|
|
197
|
+
} : {
|
|
198
|
+
kind: "range",
|
|
199
|
+
minAmount: pricing.minimum,
|
|
200
|
+
maxAmount: pricing.maximum,
|
|
201
|
+
currency: pricing.currency
|
|
202
|
+
};
|
|
203
|
+
case "tiered": return resolvePricingOptionsPriceDisplay({
|
|
204
|
+
options: pricing.options,
|
|
205
|
+
currency: pricing.currency,
|
|
206
|
+
purpose: "configured"
|
|
207
|
+
});
|
|
208
|
+
default: return assertNever$2(pricing);
|
|
120
209
|
}
|
|
121
210
|
}
|
|
122
211
|
/**
|
|
@@ -135,7 +224,6 @@ function formatBookingPriceDisplay(display, options = {}) {
|
|
|
135
224
|
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)}`;
|
|
136
225
|
case "unavailable": return "Pricing unavailable";
|
|
137
226
|
case "external": return display.label;
|
|
138
|
-
case "whole_series": return formatCoursePriceDisplayLabel(display.display, options);
|
|
139
227
|
default: return assertNever$2(display);
|
|
140
228
|
}
|
|
141
229
|
}
|
|
@@ -145,20 +233,51 @@ function formatEventPricing(pricing, options = {}) {
|
|
|
145
233
|
}
|
|
146
234
|
//#endregion
|
|
147
235
|
//#region ../core/src/event-page-surface-subject.ts
|
|
148
|
-
function createEventSeriesPageSurfaceSubject(eventSeriesId, bookingScope) {
|
|
236
|
+
function createEventSeriesPageSurfaceSubject(eventSeriesId, bookingScope, eventDestinationMode) {
|
|
237
|
+
const mode = eventDestinationMode ? { eventDestinationMode } : {};
|
|
149
238
|
return bookingScope === "whole_series" ? {
|
|
150
239
|
kind: "eventSeries",
|
|
151
240
|
eventSeriesId,
|
|
152
241
|
bookingScope,
|
|
153
|
-
isWholeSeriesBooking: true
|
|
242
|
+
isWholeSeriesBooking: true,
|
|
243
|
+
...mode
|
|
154
244
|
} : {
|
|
155
245
|
kind: "eventSeries",
|
|
156
246
|
eventSeriesId,
|
|
157
|
-
bookingScope
|
|
247
|
+
bookingScope,
|
|
248
|
+
...mode
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
function createEventOfferingPageSurfaceSubject(eventOfferingId, input) {
|
|
252
|
+
const mode = input.eventDestinationMode ? { eventDestinationMode: input.eventDestinationMode } : {};
|
|
253
|
+
const identity = {
|
|
254
|
+
kind: "eventOffering",
|
|
255
|
+
eventOfferingId,
|
|
256
|
+
catalogueEventSeriesIds: input.catalogueEventSeriesIds
|
|
257
|
+
};
|
|
258
|
+
return input.bookingScope === "whole_series" ? {
|
|
259
|
+
...identity,
|
|
260
|
+
bookingScope: input.bookingScope,
|
|
261
|
+
isWholeSeriesBooking: true,
|
|
262
|
+
...mode
|
|
263
|
+
} : {
|
|
264
|
+
...identity,
|
|
265
|
+
bookingScope: input.bookingScope,
|
|
266
|
+
...mode
|
|
158
267
|
};
|
|
159
268
|
}
|
|
269
|
+
/**
|
|
270
|
+
* Read the destination mode off a wire value.
|
|
271
|
+
*
|
|
272
|
+
* Absent or unrecognised reads as absent, which leaves the routed Event record
|
|
273
|
+
* as the only authority — the behaviour every caller had before the field
|
|
274
|
+
* existed.
|
|
275
|
+
*/
|
|
276
|
+
function parseEventPageSurfaceDestinationMode(value) {
|
|
277
|
+
return value === "cms-managed" || value === "system-managed" ? value : void 0;
|
|
278
|
+
}
|
|
160
279
|
function parseEventPageSurfaceSubject(value) {
|
|
161
|
-
if (!isRecord$
|
|
280
|
+
if (!isRecord$5(value)) return err$1({ kind: "notObject" });
|
|
162
281
|
switch (value.kind) {
|
|
163
282
|
case "eventSeries": {
|
|
164
283
|
const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
|
|
@@ -170,7 +289,7 @@ function parseEventPageSurfaceSubject(value) {
|
|
|
170
289
|
kind: "invalidEventSeriesBookingScope",
|
|
171
290
|
bookingScope: value.bookingScope
|
|
172
291
|
});
|
|
173
|
-
return ok$1(createEventSeriesPageSurfaceSubject(eventSeriesId.value, value.bookingScope));
|
|
292
|
+
return ok$1(createEventSeriesPageSurfaceSubject(eventSeriesId.value, value.bookingScope, parseEventPageSurfaceDestinationMode(value.eventDestinationMode)));
|
|
174
293
|
}
|
|
175
294
|
case "eventOffering": {
|
|
176
295
|
const eventOfferingId = parseEventOfferingId(value.eventOfferingId);
|
|
@@ -178,24 +297,22 @@ function parseEventPageSurfaceSubject(value) {
|
|
|
178
297
|
kind: "invalidEventOfferingId",
|
|
179
298
|
error: eventOfferingId.error
|
|
180
299
|
});
|
|
181
|
-
if (!Array.isArray(value.
|
|
182
|
-
kind: "
|
|
183
|
-
|
|
300
|
+
if (!Array.isArray(value.catalogueEventSeriesIds)) return err$1({
|
|
301
|
+
kind: "invalidEventOfferingCatalogue",
|
|
302
|
+
catalogue: value.catalogueEventSeriesIds
|
|
184
303
|
});
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
if (!eventSeriesId.ok) return err$1({
|
|
189
|
-
kind: "invalidEventSeriesId",
|
|
190
|
-
error: eventSeriesId.error
|
|
191
|
-
});
|
|
192
|
-
parsedSeriesIds.push(eventSeriesId.value);
|
|
193
|
-
}
|
|
194
|
-
return ok$1({
|
|
195
|
-
kind: "eventOffering",
|
|
196
|
-
eventOfferingId: eventOfferingId.value,
|
|
197
|
-
availableEventSeriesIds: parsedSeriesIds
|
|
304
|
+
if (value.bookingScope !== "single_occurrence" && value.bookingScope !== "whole_series") return err$1({
|
|
305
|
+
kind: "invalidEventOfferingBookingScope",
|
|
306
|
+
bookingScope: value.bookingScope
|
|
198
307
|
});
|
|
308
|
+
const parsedCatalogueIds = parseEventSeriesIdList(value.catalogueEventSeriesIds);
|
|
309
|
+
if (!parsedCatalogueIds.ok) return parsedCatalogueIds;
|
|
310
|
+
const eventDestinationMode = parseEventPageSurfaceDestinationMode(value.eventDestinationMode);
|
|
311
|
+
return ok$1(createEventOfferingPageSurfaceSubject(eventOfferingId.value, {
|
|
312
|
+
catalogueEventSeriesIds: parsedCatalogueIds.value,
|
|
313
|
+
bookingScope: value.bookingScope,
|
|
314
|
+
...eventDestinationMode ? { eventDestinationMode } : {}
|
|
315
|
+
}));
|
|
199
316
|
}
|
|
200
317
|
default: return err$1({
|
|
201
318
|
kind: "unsupportedSubject",
|
|
@@ -203,7 +320,19 @@ function parseEventPageSurfaceSubject(value) {
|
|
|
203
320
|
});
|
|
204
321
|
}
|
|
205
322
|
}
|
|
206
|
-
function
|
|
323
|
+
function parseEventSeriesIdList(values) {
|
|
324
|
+
const parsed = [];
|
|
325
|
+
for (const value of values) {
|
|
326
|
+
const eventSeriesId = parseEventSeriesId(value);
|
|
327
|
+
if (!eventSeriesId.ok) return err$1({
|
|
328
|
+
kind: "invalidEventSeriesId",
|
|
329
|
+
error: eventSeriesId.error
|
|
330
|
+
});
|
|
331
|
+
parsed.push(eventSeriesId.value);
|
|
332
|
+
}
|
|
333
|
+
return ok$1(parsed);
|
|
334
|
+
}
|
|
335
|
+
function isRecord$5(value) {
|
|
207
336
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
208
337
|
}
|
|
209
338
|
//#endregion
|
|
@@ -302,7 +431,7 @@ function getZonedDateTimeParts(date, timeZone) {
|
|
|
302
431
|
second: read("second")
|
|
303
432
|
};
|
|
304
433
|
}
|
|
305
|
-
function formatDateKey(date) {
|
|
434
|
+
function formatDateKey$1(date) {
|
|
306
435
|
return `${String(date.year).padStart(4, "0")}-${String(date.month).padStart(2, "0")}-${String(date.day).padStart(2, "0")}`;
|
|
307
436
|
}
|
|
308
437
|
function toBookingTimeZone(timeZone) {
|
|
@@ -450,7 +579,7 @@ function formatBookingDateParts(input, options) {
|
|
|
450
579
|
};
|
|
451
580
|
}
|
|
452
581
|
function getBookingLocalDateKey(input) {
|
|
453
|
-
return formatDateKey(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
|
|
582
|
+
return formatDateKey$1(getLocalScheduleDate(new Date(input.startsAt), input.timeZone));
|
|
454
583
|
}
|
|
455
584
|
function compareLocalScheduleDates(left, right) {
|
|
456
585
|
return Date.UTC(left.year, left.month - 1, left.day) - Date.UTC(right.year, right.month - 1, right.day);
|
|
@@ -525,7 +654,7 @@ function getLocalScheduleDate(date, timeZone) {
|
|
|
525
654
|
};
|
|
526
655
|
}
|
|
527
656
|
function formatLocalScheduleDate(date) {
|
|
528
|
-
return formatDateKey(date);
|
|
657
|
+
return formatDateKey$1(date);
|
|
529
658
|
}
|
|
530
659
|
function addLocalScheduleDays(date, days) {
|
|
531
660
|
const utcDate = new Date(Date.UTC(date.year, date.month - 1, date.day + days, 12, 0, 0));
|
|
@@ -557,23 +686,78 @@ function parseNewsletterSignupDestinationProvider(value) {
|
|
|
557
686
|
return value === "riverbank" || value === "mailchimp" ? value : null;
|
|
558
687
|
}
|
|
559
688
|
//#endregion
|
|
560
|
-
//#region ../core/src/
|
|
561
|
-
/**
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
689
|
+
//#region ../core/src/whole-series-run-schedule.ts
|
|
690
|
+
/**
|
|
691
|
+
* A session that is not happening.
|
|
692
|
+
*
|
|
693
|
+
* Exported because every surface that renders a run's schedule has to mark the
|
|
694
|
+
* same weeks, and a second copy of the string is a second chance to disagree.
|
|
695
|
+
*/
|
|
696
|
+
const CANCELLED_SESSION_STATUS = "cancelled";
|
|
697
|
+
function sessionStartMs(session) {
|
|
698
|
+
return Date.parse(session.startsAt);
|
|
699
|
+
}
|
|
700
|
+
/**
|
|
701
|
+
* The run's sessions that still count, in schedule order.
|
|
702
|
+
*
|
|
703
|
+
* Sessions whose start cannot be read are dropped rather than sorted to an
|
|
704
|
+
* arbitrary end: an unparseable date is not a date a visitor can attend.
|
|
705
|
+
*/
|
|
706
|
+
function orderedLiveRunSessions(sessions) {
|
|
707
|
+
return sessions.filter((session) => session.status !== "cancelled" && Number.isFinite(sessionStartMs(session))).sort((left, right) => sessionStartMs(left) - sessionStartMs(right));
|
|
708
|
+
}
|
|
709
|
+
/** When the first session a visitor could attend begins. */
|
|
710
|
+
function firstLiveRunSessionStartMs(sessions) {
|
|
711
|
+
const first = orderedLiveRunSessions(sessions)[0];
|
|
712
|
+
return first === void 0 ? null : sessionStartMs(first);
|
|
713
|
+
}
|
|
714
|
+
/**
|
|
715
|
+
* Booking stays open until the run's first surviving session has started.
|
|
716
|
+
*
|
|
717
|
+
* There has to be something left to sell: a run with no schedule at all, or one
|
|
718
|
+
* whose every session has been cancelled, is closed rather than open. Adding a
|
|
719
|
+
* future session opens it again, subject to the usual status, visibility and
|
|
720
|
+
* admission rules.
|
|
721
|
+
*/
|
|
722
|
+
function isWholeSeriesRegistrationOpen(sessions, now) {
|
|
723
|
+
const firstStart = firstLiveRunSessionStartMs(sessions);
|
|
724
|
+
return firstStart !== null && firstStart > now.getTime();
|
|
567
725
|
}
|
|
568
726
|
/**
|
|
569
|
-
*
|
|
727
|
+
* Whether a prepared run is still inviting bookings at render time.
|
|
570
728
|
*
|
|
571
|
-
*
|
|
572
|
-
*
|
|
729
|
+
* `lifecycle` and `enrollmentOpen` come from the projection; the first session
|
|
730
|
+
* start is the one fact re-read against `now`, because that is the boundary a
|
|
731
|
+
* cached page can cross while it sits in front of a visitor.
|
|
573
732
|
*/
|
|
574
|
-
function
|
|
575
|
-
|
|
576
|
-
|
|
733
|
+
function resolveWholeSeriesBookingPhase(run, now) {
|
|
734
|
+
switch (run.lifecycle) {
|
|
735
|
+
case "cancelled": return {
|
|
736
|
+
kind: "closed",
|
|
737
|
+
reason: "cancelled"
|
|
738
|
+
};
|
|
739
|
+
case "in_progress": return {
|
|
740
|
+
kind: "closed",
|
|
741
|
+
reason: "in-progress"
|
|
742
|
+
};
|
|
743
|
+
case "completed": return {
|
|
744
|
+
kind: "closed",
|
|
745
|
+
reason: "completed"
|
|
746
|
+
};
|
|
747
|
+
case "upcoming":
|
|
748
|
+
if (firstLiveRunSessionStartMs(run.sessions) === null) return {
|
|
749
|
+
kind: "closed",
|
|
750
|
+
reason: "no-sessions"
|
|
751
|
+
};
|
|
752
|
+
if (!isWholeSeriesRegistrationOpen(run.sessions, now)) return {
|
|
753
|
+
kind: "closed",
|
|
754
|
+
reason: "in-progress"
|
|
755
|
+
};
|
|
756
|
+
return run.enrollmentOpen ? { kind: "open" } : {
|
|
757
|
+
kind: "closed",
|
|
758
|
+
reason: "enrolment-closed"
|
|
759
|
+
};
|
|
760
|
+
}
|
|
577
761
|
}
|
|
578
762
|
//#endregion
|
|
579
763
|
//#region ../core/src/event-series-behaviour.ts
|
|
@@ -760,7 +944,7 @@ function assertNever$1(value, message) {
|
|
|
760
944
|
/**
|
|
761
945
|
* Strict record guard: excludes null, primitives, and arrays.
|
|
762
946
|
*/
|
|
763
|
-
function isRecord$
|
|
947
|
+
function isRecord$4(value) {
|
|
764
948
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
765
949
|
}
|
|
766
950
|
//#endregion
|
|
@@ -1015,12 +1199,12 @@ function resolveBookingSiteId(siteId, form) {
|
|
|
1015
1199
|
return siteId || form?.siteId || "";
|
|
1016
1200
|
}
|
|
1017
1201
|
function normalizeBookingFormConfig(form) {
|
|
1018
|
-
if (!isRecord$
|
|
1202
|
+
if (!isRecord$3(form)) return null;
|
|
1019
1203
|
const id = readNonEmptyString(form.id);
|
|
1020
1204
|
const name = readNonEmptyString(form.name);
|
|
1021
1205
|
if (!id || !name) return null;
|
|
1022
|
-
const schemaSource = isRecord$
|
|
1023
|
-
const settingsSource = isRecord$
|
|
1206
|
+
const schemaSource = isRecord$3(form.schema) ? form.schema : isRecord$3(form.schemaJson) ? form.schemaJson : null;
|
|
1207
|
+
const settingsSource = isRecord$3(form.settings) ? form.settings : isRecord$3(form.settingsJson) ? form.settingsJson : null;
|
|
1024
1208
|
return {
|
|
1025
1209
|
id,
|
|
1026
1210
|
name,
|
|
@@ -1040,8 +1224,8 @@ function normalizeBookingServices(services) {
|
|
|
1040
1224
|
};
|
|
1041
1225
|
if (!services) return [];
|
|
1042
1226
|
if (Array.isArray(services)) return services.filter(isBookingFormService).map(normalizeService);
|
|
1043
|
-
if (isRecord$
|
|
1044
|
-
return isRecord$
|
|
1227
|
+
if (isRecord$3(services) && "services" in services) return Array.isArray(services.services) ? services.services.filter(isBookingFormService).map(normalizeService) : [];
|
|
1228
|
+
return isRecord$3(services) ? Object.values(services).filter(isBookingFormService).map(normalizeService) : [];
|
|
1045
1229
|
}
|
|
1046
1230
|
function normalizeBookingSchema(value) {
|
|
1047
1231
|
if (!value) return void 0;
|
|
@@ -1052,7 +1236,7 @@ function normalizeBookingSchema(value) {
|
|
|
1052
1236
|
};
|
|
1053
1237
|
}
|
|
1054
1238
|
function readBookingFormField(value) {
|
|
1055
|
-
if (!isRecord$
|
|
1239
|
+
if (!isRecord$3(value)) return null;
|
|
1056
1240
|
const id = readNonEmptyString(value.id);
|
|
1057
1241
|
const label = readNonEmptyString(value.label);
|
|
1058
1242
|
const type = readBookingFieldType(value.type);
|
|
@@ -1095,7 +1279,7 @@ function readBookingFieldOptions(value) {
|
|
|
1095
1279
|
return options.length > 0 ? options : void 0;
|
|
1096
1280
|
}
|
|
1097
1281
|
function readBookingFieldOption(value) {
|
|
1098
|
-
if (!isRecord$
|
|
1282
|
+
if (!isRecord$3(value)) return null;
|
|
1099
1283
|
const optionValue = readNonEmptyString(value.value);
|
|
1100
1284
|
const label = readNonEmptyString(value.label);
|
|
1101
1285
|
return optionValue && label ? {
|
|
@@ -1115,7 +1299,7 @@ function normalizeBookingSettings(value) {
|
|
|
1115
1299
|
};
|
|
1116
1300
|
}
|
|
1117
1301
|
function isBookingFormService(value) {
|
|
1118
|
-
return isRecord$
|
|
1302
|
+
return isRecord$3(value) && typeof value.id === "string" && typeof value.siteId === "string" && typeof value.title === "string" && (value.consent === void 0 || blockBookingConsentSchema.safeParse(value.consent).success);
|
|
1119
1303
|
}
|
|
1120
1304
|
function collectBookingCustomFields(data) {
|
|
1121
1305
|
const customFields = {};
|
|
@@ -1165,7 +1349,7 @@ function readStringArray(value) {
|
|
|
1165
1349
|
const strings = value.filter((item) => typeof item === "string");
|
|
1166
1350
|
return strings.length > 0 ? strings : void 0;
|
|
1167
1351
|
}
|
|
1168
|
-
function isRecord$
|
|
1352
|
+
function isRecord$3(value) {
|
|
1169
1353
|
return typeof value === "object" && value !== null;
|
|
1170
1354
|
}
|
|
1171
1355
|
function getBookingServicePaymentSelectionMode(service) {
|
|
@@ -4551,6 +4735,11 @@ const gradientConfigSchema = z.object({
|
|
|
4551
4735
|
position: z.string().optional(),
|
|
4552
4736
|
stops: z.array(gradientStopSchema).min(2)
|
|
4553
4737
|
});
|
|
4738
|
+
const gradientsSchema = z.object({
|
|
4739
|
+
button: z.string().min(1).nullable().optional(),
|
|
4740
|
+
hero: z.string().min(1).nullable().optional(),
|
|
4741
|
+
background: z.string().min(1).nullable().optional()
|
|
4742
|
+
});
|
|
4554
4743
|
//#endregion
|
|
4555
4744
|
//#region ../theme-core/src/interactive/baseSchema.ts
|
|
4556
4745
|
/**
|
|
@@ -5208,11 +5397,30 @@ const headerContainerSchema = z.object({
|
|
|
5208
5397
|
tint: z.string().nullable().optional(),
|
|
5209
5398
|
opacity: z.number().min(0).max(1).default(.12)
|
|
5210
5399
|
}).optional();
|
|
5211
|
-
|
|
5400
|
+
//#endregion
|
|
5401
|
+
//#region ../theme-core/src/header/interactionPalette.ts
|
|
5402
|
+
/**
|
|
5403
|
+
* The palettes that fill the nav link with a colour on hover and focus. Each
|
|
5404
|
+
* one names a background/foreground token pair.
|
|
5405
|
+
*/
|
|
5406
|
+
const headerInteractionPillPaletteValues = [
|
|
5212
5407
|
"primary",
|
|
5213
5408
|
"secondary",
|
|
5214
5409
|
"accent"
|
|
5215
|
-
]
|
|
5410
|
+
];
|
|
5411
|
+
/**
|
|
5412
|
+
* "No pill": the nav link keeps whatever hover treatment its recipe compiled,
|
|
5413
|
+
* and the palette step writes nothing at all (#1318 Phase 4c decision 2).
|
|
5414
|
+
*
|
|
5415
|
+
* It exists because "a colour change on hover, no filled background" was not
|
|
5416
|
+
* expressible in the vocabulary, and it is what
|
|
5417
|
+
* `anna-raven-therapy-and-yoga` and `kirtan-lucy` have rendered since before
|
|
5418
|
+
* the palette existed. Without it those two rows can only be classified as a
|
|
5419
|
+
* conscious visual change.
|
|
5420
|
+
*/
|
|
5421
|
+
const headerInteractionQuietPalette = "quiet";
|
|
5422
|
+
const headerInteractionPaletteValues = [...headerInteractionPillPaletteValues, headerInteractionQuietPalette];
|
|
5423
|
+
const headerInteractionPaletteSchema = z.enum(headerInteractionPaletteValues);
|
|
5216
5424
|
//#endregion
|
|
5217
5425
|
//#region ../theme-core/src/boxBackgroundSchema.ts
|
|
5218
5426
|
const boxBackgroundOverlaySchema = z.preprocess(normalizeAuthoringOpacity, z.discriminatedUnion("type", [
|
|
@@ -5270,7 +5478,7 @@ const boxBackgroundSchema = z.discriminatedUnion("type", [
|
|
|
5270
5478
|
})
|
|
5271
5479
|
]);
|
|
5272
5480
|
function normalizeAuthoringOpacity(value) {
|
|
5273
|
-
if (!isRecord$
|
|
5481
|
+
if (!isRecord$2(value)) return value;
|
|
5274
5482
|
return {
|
|
5275
5483
|
...value,
|
|
5276
5484
|
opacity: normalizeOpacity(value.opacity)
|
|
@@ -5279,7 +5487,7 @@ function normalizeAuthoringOpacity(value) {
|
|
|
5279
5487
|
function normalizeOpacity(value) {
|
|
5280
5488
|
return typeof value === "number" && value > 1 && value <= 100 ? value / 100 : value;
|
|
5281
5489
|
}
|
|
5282
|
-
function isRecord$
|
|
5490
|
+
function isRecord$2(value) {
|
|
5283
5491
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5284
5492
|
}
|
|
5285
5493
|
//#endregion
|
|
@@ -5733,7 +5941,7 @@ const headerSchema = z.object({
|
|
|
5733
5941
|
variant: headerVariantWithLegacyAliasSchema,
|
|
5734
5942
|
positioning: headerPositioning,
|
|
5735
5943
|
shrinkOnScroll: z.boolean(),
|
|
5736
|
-
maxWidth: headerMaxWidth,
|
|
5944
|
+
maxWidth: headerMaxWidth.default("container"),
|
|
5737
5945
|
scrollTreatment: headerScrollTreatmentSchema,
|
|
5738
5946
|
background: headerBackgroundSchema.default({
|
|
5739
5947
|
type: "color",
|
|
@@ -5932,11 +6140,6 @@ const bodyTextSchema = z.object({ intro: z.object({
|
|
|
5932
6140
|
paragraphSize: bodyTextIntroTypographySizeSchema.optional(),
|
|
5933
6141
|
headingSize: bodyTextIntroTypographySizeSchema.optional()
|
|
5934
6142
|
}).optional() }).optional();
|
|
5935
|
-
const gradientsSchema = z.object({
|
|
5936
|
-
button: z.string().min(1).nullable().optional(),
|
|
5937
|
-
hero: z.string().min(1).nullable().optional(),
|
|
5938
|
-
background: z.string().min(1).nullable().optional()
|
|
5939
|
-
});
|
|
5940
6143
|
/**
|
|
5941
6144
|
* Testimonial quote-mark treatment, owned by the site style (analogous to the
|
|
5942
6145
|
* accordion icon). `style` is the coarse selector; the optional fields fine-tune
|
|
@@ -6022,267 +6225,6 @@ z.object({
|
|
|
6022
6225
|
themes: z.array(themeSchema).length(3)
|
|
6023
6226
|
});
|
|
6024
6227
|
//#endregion
|
|
6025
|
-
//#region ../blocks/src/system/blocks/events/whole-series/pricing.ts
|
|
6026
|
-
function isSaleWindowOpen(option, now) {
|
|
6027
|
-
if (!option.isActive) return false;
|
|
6028
|
-
if (option.saleStartsAt && new Date(option.saleStartsAt) > now) return false;
|
|
6029
|
-
if (option.saleEndsAt && new Date(option.saleEndsAt) < now) return false;
|
|
6030
|
-
return true;
|
|
6031
|
-
}
|
|
6032
|
-
function toExactOrFreeDisplay(amount, currency) {
|
|
6033
|
-
if (amount <= 0) return {
|
|
6034
|
-
kind: "free",
|
|
6035
|
-
currency
|
|
6036
|
-
};
|
|
6037
|
-
return {
|
|
6038
|
-
kind: "exact",
|
|
6039
|
-
amount,
|
|
6040
|
-
currency
|
|
6041
|
-
};
|
|
6042
|
-
}
|
|
6043
|
-
function getSelectableWholeSeriesPricingOptionsForNow(offering, now) {
|
|
6044
|
-
if (offering.pricing.pricingStrategy !== "tiered") return [];
|
|
6045
|
-
return [...offering.pricing.options].filter((option) => isSaleWindowOpen(option, now)).sort((left, right) => {
|
|
6046
|
-
if (left.sortOrder !== right.sortOrder) return left.sortOrder - right.sortOrder;
|
|
6047
|
-
if (left.priceAmount !== right.priceAmount) return left.priceAmount - right.priceAmount;
|
|
6048
|
-
return left.name.localeCompare(right.name);
|
|
6049
|
-
});
|
|
6050
|
-
}
|
|
6051
|
-
function resolveWholeSeriesPricingState(offering, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
|
|
6052
|
-
const selection = normalizePricingSelectionInput(selectedSlidingAmountOrNowInput, nowInput);
|
|
6053
|
-
const currency = offering.pricing.currency;
|
|
6054
|
-
switch (offering.pricing.pricingStrategy) {
|
|
6055
|
-
case "free": return resolveFreePricing(currency);
|
|
6056
|
-
case "single": return resolveSinglePricing(offering.pricing.singlePriceAmount ?? 0, currency);
|
|
6057
|
-
case "tiered": return resolveTieredPricing(offering, selectedPricingOptionId, selection.nowInput);
|
|
6058
|
-
case "sliding_scale": return resolveSlidingScalePricing(offering, selection.selectedSlidingAmount);
|
|
6059
|
-
}
|
|
6060
|
-
}
|
|
6061
|
-
function normalizePricingSelectionInput(selectedSlidingAmountOrNowInput, nowInput) {
|
|
6062
|
-
return typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? {
|
|
6063
|
-
selectedSlidingAmount: null,
|
|
6064
|
-
nowInput: selectedSlidingAmountOrNowInput
|
|
6065
|
-
} : {
|
|
6066
|
-
selectedSlidingAmount: typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null,
|
|
6067
|
-
nowInput
|
|
6068
|
-
};
|
|
6069
|
-
}
|
|
6070
|
-
function resolveFreePricing(currency) {
|
|
6071
|
-
return {
|
|
6072
|
-
currency,
|
|
6073
|
-
display: {
|
|
6074
|
-
kind: "free",
|
|
6075
|
-
currency
|
|
6076
|
-
},
|
|
6077
|
-
selectableOptions: [],
|
|
6078
|
-
requiresSelection: false,
|
|
6079
|
-
selectedOption: null,
|
|
6080
|
-
slidingScale: null,
|
|
6081
|
-
selectedSlidingAmount: null,
|
|
6082
|
-
selectedPriceAmount: 0,
|
|
6083
|
-
selectedRequiresPayment: false,
|
|
6084
|
-
hasPaidSelection: false,
|
|
6085
|
-
hasFreeSelection: true
|
|
6086
|
-
};
|
|
6087
|
-
}
|
|
6088
|
-
function resolveSinglePricing(amount, currency) {
|
|
6089
|
-
return {
|
|
6090
|
-
currency,
|
|
6091
|
-
display: toExactOrFreeDisplay(amount, currency),
|
|
6092
|
-
selectableOptions: [],
|
|
6093
|
-
requiresSelection: false,
|
|
6094
|
-
selectedOption: null,
|
|
6095
|
-
slidingScale: null,
|
|
6096
|
-
selectedSlidingAmount: null,
|
|
6097
|
-
selectedPriceAmount: amount,
|
|
6098
|
-
selectedRequiresPayment: amount > 0,
|
|
6099
|
-
hasPaidSelection: amount > 0,
|
|
6100
|
-
hasFreeSelection: amount <= 0
|
|
6101
|
-
};
|
|
6102
|
-
}
|
|
6103
|
-
function resolveTieredPricing(offering, selectedPricingOptionId, nowInput) {
|
|
6104
|
-
const currency = offering.pricing.currency;
|
|
6105
|
-
const selectableOptions = getSelectableWholeSeriesPricingOptionsForNow(offering, resolvePlanningDateInput(nowInput));
|
|
6106
|
-
const selectedOption = resolveSelectedTier(selectableOptions, selectedPricingOptionId);
|
|
6107
|
-
return {
|
|
6108
|
-
currency,
|
|
6109
|
-
display: resolveTieredDisplay(selectableOptions.reduce((lowest, option) => lowest === null || option.priceAmount < lowest ? option.priceAmount : lowest, null), selectableOptions.length, currency),
|
|
6110
|
-
selectableOptions,
|
|
6111
|
-
requiresSelection: selectableOptions.length > 1,
|
|
6112
|
-
selectedOption,
|
|
6113
|
-
slidingScale: null,
|
|
6114
|
-
selectedSlidingAmount: null,
|
|
6115
|
-
selectedPriceAmount: selectedOption?.priceAmount ?? null,
|
|
6116
|
-
selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
|
|
6117
|
-
hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
|
|
6118
|
-
hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
|
|
6119
|
-
};
|
|
6120
|
-
}
|
|
6121
|
-
function resolveSelectedTier(options, selectedId) {
|
|
6122
|
-
return (selectedId ? options.find((option) => option.id === selectedId) : null) ?? (options.length === 1 ? options[0] ?? null : null);
|
|
6123
|
-
}
|
|
6124
|
-
function resolveTieredDisplay(lowestAmount, optionCount, currency) {
|
|
6125
|
-
if (lowestAmount === null) return {
|
|
6126
|
-
kind: "unavailable",
|
|
6127
|
-
currency
|
|
6128
|
-
};
|
|
6129
|
-
return optionCount > 1 && lowestAmount > 0 ? {
|
|
6130
|
-
kind: "from",
|
|
6131
|
-
amount: lowestAmount,
|
|
6132
|
-
currency
|
|
6133
|
-
} : toExactOrFreeDisplay(lowestAmount, currency);
|
|
6134
|
-
}
|
|
6135
|
-
function resolveSlidingScalePricing(offering, selectedSlidingAmount) {
|
|
6136
|
-
const currency = offering.pricing.currency;
|
|
6137
|
-
const minAmount = offering.pricing.slidingMinAmount ?? null;
|
|
6138
|
-
const maxAmount = offering.pricing.slidingMaxAmount ?? null;
|
|
6139
|
-
if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) return unavailableSlidingScale(currency);
|
|
6140
|
-
const selectedAmount = Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
|
|
6141
|
-
return {
|
|
6142
|
-
currency,
|
|
6143
|
-
display: {
|
|
6144
|
-
kind: "range",
|
|
6145
|
-
minAmount,
|
|
6146
|
-
maxAmount,
|
|
6147
|
-
currency
|
|
6148
|
-
},
|
|
6149
|
-
selectableOptions: [],
|
|
6150
|
-
requiresSelection: selectedAmount === null,
|
|
6151
|
-
selectedOption: null,
|
|
6152
|
-
slidingScale: {
|
|
6153
|
-
minAmount,
|
|
6154
|
-
maxAmount,
|
|
6155
|
-
suggestedAmount: offering.pricing.slidingSuggestedAmount ?? null
|
|
6156
|
-
},
|
|
6157
|
-
selectedSlidingAmount: selectedAmount,
|
|
6158
|
-
selectedPriceAmount: selectedAmount,
|
|
6159
|
-
selectedRequiresPayment: (selectedAmount ?? 0) > 0,
|
|
6160
|
-
hasPaidSelection: maxAmount > 0,
|
|
6161
|
-
hasFreeSelection: minAmount === 0
|
|
6162
|
-
};
|
|
6163
|
-
}
|
|
6164
|
-
function unavailableSlidingScale(currency) {
|
|
6165
|
-
return {
|
|
6166
|
-
currency,
|
|
6167
|
-
display: {
|
|
6168
|
-
kind: "unavailable",
|
|
6169
|
-
currency
|
|
6170
|
-
},
|
|
6171
|
-
selectableOptions: [],
|
|
6172
|
-
requiresSelection: true,
|
|
6173
|
-
selectedOption: null,
|
|
6174
|
-
slidingScale: null,
|
|
6175
|
-
selectedSlidingAmount: null,
|
|
6176
|
-
selectedPriceAmount: null,
|
|
6177
|
-
selectedRequiresPayment: false,
|
|
6178
|
-
hasPaidSelection: false,
|
|
6179
|
-
hasFreeSelection: false
|
|
6180
|
-
};
|
|
6181
|
-
}
|
|
6182
|
-
function formatWholeSeriesPriceDisplay(display, locale) {
|
|
6183
|
-
return formatBookingPriceDisplay(display, {
|
|
6184
|
-
decimals: "exact",
|
|
6185
|
-
locale
|
|
6186
|
-
});
|
|
6187
|
-
}
|
|
6188
|
-
function formatWholeSeriesPriceAmount(amount, currency, locale) {
|
|
6189
|
-
return formatWholeSeriesPriceDisplay(amount > 0 ? {
|
|
6190
|
-
kind: "exact",
|
|
6191
|
-
amount,
|
|
6192
|
-
currency
|
|
6193
|
-
} : {
|
|
6194
|
-
kind: "free",
|
|
6195
|
-
currency
|
|
6196
|
-
}, locale);
|
|
6197
|
-
}
|
|
6198
|
-
//#endregion
|
|
6199
|
-
//#region ../blocks/src/system/blocks/events/whole-series/schemas.ts
|
|
6200
|
-
const wholeSeriesVenueSchema = z.object({
|
|
6201
|
-
id: z.string(),
|
|
6202
|
-
name: z.string(),
|
|
6203
|
-
address: z.string().nullable()
|
|
6204
|
-
});
|
|
6205
|
-
const wholeSeriesSessionSchema = z.object({
|
|
6206
|
-
id: z.string(),
|
|
6207
|
-
startsAt: z.string(),
|
|
6208
|
-
endsAt: z.string(),
|
|
6209
|
-
timeZone: z.string(),
|
|
6210
|
-
capacityOverride: z.number().nullable().optional(),
|
|
6211
|
-
overrides: z.record(z.string(), z.unknown()).nullable().optional()
|
|
6212
|
-
});
|
|
6213
|
-
const wholeSeriesTeamMemberSummarySchema = z.object({
|
|
6214
|
-
id: z.string(),
|
|
6215
|
-
name: z.string(),
|
|
6216
|
-
roleLabel: z.string().nullable(),
|
|
6217
|
-
summary: z.string().nullable(),
|
|
6218
|
-
profilePath: z.string().nullable()
|
|
6219
|
-
});
|
|
6220
|
-
const wholeSeriesPricingOptionSchema = z.object({
|
|
6221
|
-
id: z.string(),
|
|
6222
|
-
name: z.string(),
|
|
6223
|
-
description: z.string().nullable(),
|
|
6224
|
-
priceAmount: z.number(),
|
|
6225
|
-
isActive: z.boolean(),
|
|
6226
|
-
sortOrder: z.number(),
|
|
6227
|
-
capacityLimit: z.number().nullable(),
|
|
6228
|
-
saleStartsAt: z.string().nullable(),
|
|
6229
|
-
saleEndsAt: z.string().nullable(),
|
|
6230
|
-
attendanceScope: z.enum([
|
|
6231
|
-
"in_person",
|
|
6232
|
-
"online",
|
|
6233
|
-
"both"
|
|
6234
|
-
]).nullable().optional()
|
|
6235
|
-
});
|
|
6236
|
-
const wholeSeriesPricingSchema = z.object({
|
|
6237
|
-
bookingRequirement: z.enum(["none", "required"]),
|
|
6238
|
-
pricingStrategy: z.enum([
|
|
6239
|
-
"free",
|
|
6240
|
-
"single",
|
|
6241
|
-
"tiered",
|
|
6242
|
-
"sliding_scale"
|
|
6243
|
-
]),
|
|
6244
|
-
currency: z.string(),
|
|
6245
|
-
singlePriceAmount: z.number().nullable(),
|
|
6246
|
-
slidingMinAmount: z.number().nullable().optional(),
|
|
6247
|
-
slidingMaxAmount: z.number().nullable().optional(),
|
|
6248
|
-
slidingSuggestedAmount: z.number().nullable().optional(),
|
|
6249
|
-
paymentTerms: blockBookingPaymentTermsSchema,
|
|
6250
|
-
options: z.array(wholeSeriesPricingOptionSchema)
|
|
6251
|
-
});
|
|
6252
|
-
const publicWholeSeriesOfferingSchema = z.object({
|
|
6253
|
-
eventSeriesId: z.string(),
|
|
6254
|
-
eventOfferingId: z.string(),
|
|
6255
|
-
title: z.string(),
|
|
6256
|
-
slug: z.string(),
|
|
6257
|
-
description: z.unknown().nullable(),
|
|
6258
|
-
deliveryMode: z.enum([
|
|
6259
|
-
"in_person",
|
|
6260
|
-
"online",
|
|
6261
|
-
"hybrid"
|
|
6262
|
-
]),
|
|
6263
|
-
waitlistEnabled: z.boolean(),
|
|
6264
|
-
requireGuestDetails: z.boolean(),
|
|
6265
|
-
teamMembers: z.array(wholeSeriesTeamMemberSummarySchema).optional(),
|
|
6266
|
-
enrollmentOpen: z.boolean(),
|
|
6267
|
-
pricing: wholeSeriesPricingSchema,
|
|
6268
|
-
currency: z.string(),
|
|
6269
|
-
paymentTerms: blockBookingPaymentTermsSchema,
|
|
6270
|
-
consent: blockBookingConsentSchema.nullable(),
|
|
6271
|
-
enrollmentCapacity: z.number().nullable(),
|
|
6272
|
-
acceptsMemberships: z.boolean(),
|
|
6273
|
-
status: z.enum([
|
|
6274
|
-
"active",
|
|
6275
|
-
"draft",
|
|
6276
|
-
"cancelled"
|
|
6277
|
-
]),
|
|
6278
|
-
sessionsCount: z.number(),
|
|
6279
|
-
enrolledCount: z.number(),
|
|
6280
|
-
availableSpots: z.number().nullable(),
|
|
6281
|
-
sessions: z.array(wholeSeriesSessionSchema),
|
|
6282
|
-
venue: wholeSeriesVenueSchema.nullable()
|
|
6283
|
-
});
|
|
6284
|
-
const publicWholeSeriesOfferingsArraySchema = z.array(publicWholeSeriesOfferingSchema);
|
|
6285
|
-
//#endregion
|
|
6286
6228
|
//#region ../blocks/src/system/blocks/events/shared/schemas.ts
|
|
6287
6229
|
const eventPresetSchema = z.enum([
|
|
6288
6230
|
"event",
|
|
@@ -6337,77 +6279,14 @@ const eventCategorySchema = z.object({
|
|
|
6337
6279
|
name: z.string(),
|
|
6338
6280
|
color: z.string().nullable()
|
|
6339
6281
|
});
|
|
6340
|
-
z.enum([
|
|
6341
|
-
"free",
|
|
6342
|
-
"paid",
|
|
6343
|
-
"external"
|
|
6344
|
-
]);
|
|
6345
6282
|
/**
|
|
6346
6283
|
* Access restriction type for public events
|
|
6347
6284
|
*/
|
|
6348
6285
|
const accessRestrictionSchema = z.enum(["none", "category"]);
|
|
6349
|
-
z.
|
|
6350
|
-
const
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
});
|
|
6354
|
-
const exactPriceDisplaySchema = z.object({
|
|
6355
|
-
kind: z.literal("exact"),
|
|
6356
|
-
amount: z.number(),
|
|
6357
|
-
currency: z.string()
|
|
6358
|
-
});
|
|
6359
|
-
const fromPriceDisplaySchema = z.object({
|
|
6360
|
-
kind: z.literal("from"),
|
|
6361
|
-
amount: z.number(),
|
|
6362
|
-
currency: z.string()
|
|
6363
|
-
});
|
|
6364
|
-
const unavailablePriceDisplaySchema = z.object({
|
|
6365
|
-
kind: z.literal("unavailable"),
|
|
6366
|
-
currency: z.string()
|
|
6367
|
-
});
|
|
6368
|
-
const rangePriceDisplaySchema = z.object({
|
|
6369
|
-
kind: z.literal("range"),
|
|
6370
|
-
minAmount: z.number(),
|
|
6371
|
-
maxAmount: z.number(),
|
|
6372
|
-
currency: z.string()
|
|
6373
|
-
});
|
|
6374
|
-
const mixedPriceDisplaySchema = z.object({
|
|
6375
|
-
kind: z.literal("mixed"),
|
|
6376
|
-
paidFromAmount: z.number(),
|
|
6377
|
-
paidToAmount: z.number(),
|
|
6378
|
-
currency: z.string()
|
|
6379
|
-
});
|
|
6380
|
-
const publicWholeSeriesPriceDisplaySchema = z.discriminatedUnion("kind", [
|
|
6381
|
-
freePriceDisplaySchema,
|
|
6382
|
-
exactPriceDisplaySchema,
|
|
6383
|
-
fromPriceDisplaySchema,
|
|
6384
|
-
rangePriceDisplaySchema,
|
|
6385
|
-
unavailablePriceDisplaySchema
|
|
6386
|
-
]);
|
|
6387
|
-
z.discriminatedUnion("kind", [
|
|
6388
|
-
freePriceDisplaySchema,
|
|
6389
|
-
exactPriceDisplaySchema,
|
|
6390
|
-
fromPriceDisplaySchema,
|
|
6391
|
-
rangePriceDisplaySchema,
|
|
6392
|
-
mixedPriceDisplaySchema,
|
|
6393
|
-
unavailablePriceDisplaySchema,
|
|
6394
|
-
z.object({
|
|
6395
|
-
kind: z.literal("external"),
|
|
6396
|
-
label: z.string()
|
|
6397
|
-
}),
|
|
6398
|
-
z.object({
|
|
6399
|
-
kind: z.literal("whole_series"),
|
|
6400
|
-
display: publicWholeSeriesPriceDisplaySchema
|
|
6401
|
-
})
|
|
6402
|
-
]);
|
|
6403
|
-
const publicEventTicketTypePriceDisplaySchema = z.union([
|
|
6404
|
-
freePriceDisplaySchema,
|
|
6405
|
-
exactPriceDisplaySchema,
|
|
6406
|
-
fromPriceDisplaySchema,
|
|
6407
|
-
rangePriceDisplaySchema,
|
|
6408
|
-
mixedPriceDisplaySchema,
|
|
6409
|
-
unavailablePriceDisplaySchema
|
|
6410
|
-
]);
|
|
6286
|
+
const publicCurrencySchema = z.string().regex(/^[A-Z]{3}$/u);
|
|
6287
|
+
const publicCentsSchema = z.number().int().nonnegative();
|
|
6288
|
+
const publicPositiveCentsSchema = z.number().int().positive();
|
|
6289
|
+
const publicIsoDateTimeSchema = z.string().datetime({ offset: true });
|
|
6411
6290
|
const publicEventAttendanceModeSchema = z.enum(["in_person", "online"]);
|
|
6412
6291
|
const publicEventAttendanceModeAvailabilitySchema = z.object({
|
|
6413
6292
|
mode: publicEventAttendanceModeSchema,
|
|
@@ -6416,9 +6295,9 @@ const publicEventAttendanceModeAvailabilitySchema = z.object({
|
|
|
6416
6295
|
availableSpots: z.number().nullable(),
|
|
6417
6296
|
waitlistEnabled: z.boolean()
|
|
6418
6297
|
});
|
|
6419
|
-
const
|
|
6298
|
+
const publicEventPricingOptionAvailabilitySchema = z.union([z.object({
|
|
6420
6299
|
kind: z.literal("available"),
|
|
6421
|
-
|
|
6300
|
+
remainingPlaces: z.number().int().nonnegative().nullable()
|
|
6422
6301
|
}), z.object({
|
|
6423
6302
|
kind: z.literal("unavailable"),
|
|
6424
6303
|
reason: z.enum([
|
|
@@ -6426,91 +6305,69 @@ const publicEventTicketTypeAvailabilitySchema = z.union([z.object({
|
|
|
6426
6305
|
"not_on_sale_yet",
|
|
6427
6306
|
"sale_ended",
|
|
6428
6307
|
"sold_out",
|
|
6429
|
-
"
|
|
6308
|
+
"attendance_mode_unavailable",
|
|
6309
|
+
"overallCapacityUnavailable"
|
|
6430
6310
|
]),
|
|
6431
|
-
|
|
6311
|
+
remainingPlaces: z.number().int().nonnegative().nullable()
|
|
6432
6312
|
})]);
|
|
6433
|
-
const
|
|
6434
|
-
id: z.string(),
|
|
6435
|
-
|
|
6436
|
-
eventSeriesId: z.string(),
|
|
6437
|
-
name: z.string(),
|
|
6313
|
+
const publicEventPricingOptionSchema = z.object({
|
|
6314
|
+
id: z.string().min(1),
|
|
6315
|
+
name: z.string().min(1),
|
|
6438
6316
|
description: z.string().nullable(),
|
|
6439
|
-
priceAmount:
|
|
6317
|
+
priceAmount: publicCentsSchema,
|
|
6440
6318
|
isActive: z.boolean(),
|
|
6441
|
-
sortOrder: z.number(),
|
|
6442
|
-
capacityMode: z.enum(["limited", "unlimited"]),
|
|
6443
|
-
capacityLimit: z.number().nullable(),
|
|
6319
|
+
sortOrder: z.number().int().nonnegative(),
|
|
6444
6320
|
attendanceScope: z.enum([
|
|
6445
6321
|
"in_person",
|
|
6446
6322
|
"online",
|
|
6447
6323
|
"both"
|
|
6448
|
-
])
|
|
6449
|
-
saleStartsAt:
|
|
6450
|
-
saleEndsAt:
|
|
6451
|
-
availability:
|
|
6452
|
-
|
|
6453
|
-
|
|
6324
|
+
]),
|
|
6325
|
+
saleStartsAt: publicIsoDateTimeSchema.nullable(),
|
|
6326
|
+
saleEndsAt: publicIsoDateTimeSchema.nullable(),
|
|
6327
|
+
availability: publicEventPricingOptionAvailabilitySchema
|
|
6328
|
+
}).superRefine((option, context) => {
|
|
6329
|
+
if (option.saleStartsAt && option.saleEndsAt && Date.parse(option.saleEndsAt) <= Date.parse(option.saleStartsAt)) context.addIssue({
|
|
6330
|
+
code: "custom",
|
|
6331
|
+
path: ["saleEndsAt"],
|
|
6332
|
+
message: "Sale end must be after sale start"
|
|
6333
|
+
});
|
|
6454
6334
|
});
|
|
6455
6335
|
const publicEventPricingSchema = z.discriminatedUnion("kind", [
|
|
6456
6336
|
z.object({
|
|
6457
|
-
kind: z.literal("
|
|
6458
|
-
currency:
|
|
6459
|
-
display: z.object({
|
|
6460
|
-
kind: z.literal("free"),
|
|
6461
|
-
currency: z.string()
|
|
6462
|
-
})
|
|
6463
|
-
}),
|
|
6464
|
-
z.object({
|
|
6465
|
-
kind: z.literal("free_registration"),
|
|
6466
|
-
currency: z.string(),
|
|
6467
|
-
display: z.object({
|
|
6468
|
-
kind: z.literal("free"),
|
|
6469
|
-
currency: z.string()
|
|
6470
|
-
})
|
|
6337
|
+
kind: z.literal("free"),
|
|
6338
|
+
currency: publicCurrencySchema
|
|
6471
6339
|
}),
|
|
6472
6340
|
z.object({
|
|
6473
|
-
kind: z.literal("
|
|
6474
|
-
amount:
|
|
6475
|
-
currency:
|
|
6476
|
-
display: z.object({
|
|
6477
|
-
kind: z.literal("exact"),
|
|
6478
|
-
amount: z.number(),
|
|
6479
|
-
currency: z.string()
|
|
6480
|
-
})
|
|
6341
|
+
kind: z.literal("single"),
|
|
6342
|
+
amount: publicPositiveCentsSchema,
|
|
6343
|
+
currency: publicCurrencySchema
|
|
6481
6344
|
}),
|
|
6482
6345
|
z.object({
|
|
6483
|
-
kind: z.literal("
|
|
6484
|
-
currency:
|
|
6485
|
-
|
|
6486
|
-
display: publicEventTicketTypePriceDisplaySchema
|
|
6346
|
+
kind: z.literal("tiered"),
|
|
6347
|
+
currency: publicCurrencySchema,
|
|
6348
|
+
options: z.tuple([publicEventPricingOptionSchema], publicEventPricingOptionSchema)
|
|
6487
6349
|
}),
|
|
6488
6350
|
z.object({
|
|
6489
6351
|
kind: z.literal("sliding_scale"),
|
|
6490
|
-
|
|
6491
|
-
|
|
6492
|
-
|
|
6493
|
-
currency:
|
|
6494
|
-
|
|
6495
|
-
|
|
6496
|
-
|
|
6497
|
-
|
|
6498
|
-
|
|
6499
|
-
})
|
|
6500
|
-
|
|
6501
|
-
|
|
6502
|
-
|
|
6503
|
-
|
|
6504
|
-
|
|
6505
|
-
display: publicWholeSeriesPriceDisplaySchema
|
|
6506
|
-
})
|
|
6352
|
+
minimum: publicCentsSchema,
|
|
6353
|
+
maximum: publicPositiveCentsSchema,
|
|
6354
|
+
suggested: publicCentsSchema.nullable(),
|
|
6355
|
+
currency: publicCurrencySchema
|
|
6356
|
+
}).superRefine((pricing, context) => {
|
|
6357
|
+
if (pricing.minimum > pricing.maximum) context.addIssue({
|
|
6358
|
+
code: "custom",
|
|
6359
|
+
path: ["minimum"],
|
|
6360
|
+
message: "Minimum must not exceed maximum"
|
|
6361
|
+
});
|
|
6362
|
+
if (pricing.suggested !== null && (pricing.suggested < pricing.minimum || pricing.suggested > pricing.maximum)) context.addIssue({
|
|
6363
|
+
code: "custom",
|
|
6364
|
+
path: ["suggested"],
|
|
6365
|
+
message: "Suggested amount must be within the sliding-scale range"
|
|
6366
|
+
});
|
|
6507
6367
|
}),
|
|
6508
6368
|
z.object({
|
|
6509
6369
|
kind: z.literal("external"),
|
|
6510
|
-
|
|
6511
|
-
kind: z.literal("external"),
|
|
6512
|
-
label: z.string()
|
|
6513
|
-
})
|
|
6370
|
+
label: z.string().min(1)
|
|
6514
6371
|
})
|
|
6515
6372
|
]);
|
|
6516
6373
|
const publicTeamMemberSummarySchema = z.object({
|
|
@@ -6536,11 +6393,30 @@ const publicEventBookingAvailabilitySchema = z.discriminatedUnion("kind", [z.obj
|
|
|
6536
6393
|
"enrollment_closed"
|
|
6537
6394
|
])
|
|
6538
6395
|
})]);
|
|
6396
|
+
const publicRunSessionSchema = z.object({
|
|
6397
|
+
occurrenceId: z.string(),
|
|
6398
|
+
startsAt: z.string(),
|
|
6399
|
+
endsAt: z.string(),
|
|
6400
|
+
timeZone: z.string(),
|
|
6401
|
+
status: z.string()
|
|
6402
|
+
});
|
|
6403
|
+
const publicWholeSeriesRunSchema = z.object({
|
|
6404
|
+
eventSeriesId: z.string(),
|
|
6405
|
+
eventOfferingId: z.string(),
|
|
6406
|
+
enrollmentOpen: z.boolean(),
|
|
6407
|
+
visibility: z.enum(["public", "unlisted"]),
|
|
6408
|
+
lifecycle: z.enum([
|
|
6409
|
+
"upcoming",
|
|
6410
|
+
"in_progress",
|
|
6411
|
+
"completed",
|
|
6412
|
+
"cancelled"
|
|
6413
|
+
]),
|
|
6414
|
+
sessions: z.array(publicRunSessionSchema)
|
|
6415
|
+
});
|
|
6539
6416
|
/**
|
|
6540
|
-
* Zod schema for
|
|
6417
|
+
* Zod schema for the fields shared by both booking scopes.
|
|
6541
6418
|
*/
|
|
6542
|
-
const
|
|
6543
|
-
bookingScope: z.enum(["single_occurrence", "whole_series"]),
|
|
6419
|
+
const publicEventBaseSchema = z.object({
|
|
6544
6420
|
eventPreset: eventPresetSchema.optional(),
|
|
6545
6421
|
eventDestinationMode: eventDestinationModeSchema.optional(),
|
|
6546
6422
|
scheduleScope: eventScheduleScopeSchema$2.optional(),
|
|
@@ -6590,20 +6466,68 @@ const publicEventSchema = z.object({
|
|
|
6590
6466
|
accessRestriction: accessRestrictionSchema,
|
|
6591
6467
|
allowedCategoryIds: z.array(z.string()),
|
|
6592
6468
|
requireGuestDetails: z.boolean().optional(),
|
|
6593
|
-
acceptsPasses: z.boolean()
|
|
6594
|
-
acceptsMemberships: z.boolean()
|
|
6595
|
-
wholeSeries: z.object({
|
|
6596
|
-
eventSeriesId: z.string(),
|
|
6597
|
-
pricing: wholeSeriesPricingSchema,
|
|
6598
|
-
currency: z.string(),
|
|
6599
|
-
enrollmentOpen: z.boolean()
|
|
6600
|
-
}).nullable().optional()
|
|
6469
|
+
acceptsPasses: z.boolean(),
|
|
6470
|
+
acceptsMemberships: z.boolean()
|
|
6601
6471
|
});
|
|
6602
6472
|
/**
|
|
6473
|
+
* Zod schema for public event data.
|
|
6474
|
+
*
|
|
6475
|
+
* The booking scope discriminates: a `whole_series` record without complete
|
|
6476
|
+
* `run` facts is rejected, and a `single_occurrence` record never carries them.
|
|
6477
|
+
*/
|
|
6478
|
+
const publicEventSchema = z.union([publicEventBaseSchema.extend({
|
|
6479
|
+
bookingScope: z.literal("single_occurrence"),
|
|
6480
|
+
run: z.undefined().optional()
|
|
6481
|
+
}), publicEventBaseSchema.extend({
|
|
6482
|
+
bookingScope: z.literal("whole_series"),
|
|
6483
|
+
run: publicWholeSeriesRunSchema
|
|
6484
|
+
})]);
|
|
6485
|
+
/**
|
|
6603
6486
|
* Schema for an array of public events
|
|
6604
6487
|
*/
|
|
6605
6488
|
const publicEventsArraySchema = z.array(publicEventSchema);
|
|
6606
6489
|
//#endregion
|
|
6490
|
+
//#region ../blocks/src/system/blocks/events/shared/runGrouping.ts
|
|
6491
|
+
function isWholeSeriesPublicEvent(event) {
|
|
6492
|
+
return event.bookingScope === "whole_series";
|
|
6493
|
+
}
|
|
6494
|
+
/**
|
|
6495
|
+
* Group events into one entry per whole-series run.
|
|
6496
|
+
*
|
|
6497
|
+
* Single-occurrence events are ignored. Run order follows first appearance, so
|
|
6498
|
+
* a caller's sort survives the grouping, and an occurrence that arrives twice
|
|
6499
|
+
* is kept once.
|
|
6500
|
+
*/
|
|
6501
|
+
function groupPublicEventsByRun(events) {
|
|
6502
|
+
const occurrencesBySeriesId = /* @__PURE__ */ new Map();
|
|
6503
|
+
const order = [];
|
|
6504
|
+
const seenOccurrenceIds = /* @__PURE__ */ new Set();
|
|
6505
|
+
for (const event of events) {
|
|
6506
|
+
if (!isWholeSeriesPublicEvent(event)) continue;
|
|
6507
|
+
if (seenOccurrenceIds.has(event.occurrenceId)) continue;
|
|
6508
|
+
seenOccurrenceIds.add(event.occurrenceId);
|
|
6509
|
+
const seriesId = event.run.eventSeriesId;
|
|
6510
|
+
const existing = occurrencesBySeriesId.get(seriesId);
|
|
6511
|
+
if (existing) {
|
|
6512
|
+
existing.push(event);
|
|
6513
|
+
continue;
|
|
6514
|
+
}
|
|
6515
|
+
occurrencesBySeriesId.set(seriesId, [event]);
|
|
6516
|
+
order.push(seriesId);
|
|
6517
|
+
}
|
|
6518
|
+
return order.map((eventSeriesId) => {
|
|
6519
|
+
const occurrences = occurrencesBySeriesId.get(eventSeriesId) ?? [];
|
|
6520
|
+
const representative = occurrences[0];
|
|
6521
|
+
if (!representative) throw new Error(`Run ${eventSeriesId} grouped without any occurrence`);
|
|
6522
|
+
return {
|
|
6523
|
+
eventSeriesId,
|
|
6524
|
+
run: representative.run,
|
|
6525
|
+
occurrences,
|
|
6526
|
+
representative
|
|
6527
|
+
};
|
|
6528
|
+
});
|
|
6529
|
+
}
|
|
6530
|
+
//#endregion
|
|
6607
6531
|
//#region ../blocks/src/system/helpers/normalizeIds.ts
|
|
6608
6532
|
function normalizeIdList(parts) {
|
|
6609
6533
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -6669,94 +6593,142 @@ function normalizeEventStaffMemberId(value) {
|
|
|
6669
6593
|
return trimmed ? trimmed : null;
|
|
6670
6594
|
}
|
|
6671
6595
|
//#endregion
|
|
6672
|
-
//#region ../
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
|
|
6677
|
-
|
|
6678
|
-
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
const date = new Date(isoTimestamp);
|
|
6689
|
-
if (Number.isNaN(date.getTime())) return NaN;
|
|
6690
|
-
if (!isValidTimeZone(timeZone)) return NaN;
|
|
6691
|
-
const parts = new Intl.DateTimeFormat("en-GB", {
|
|
6692
|
-
timeZone,
|
|
6693
|
-
hour: "2-digit",
|
|
6694
|
-
minute: "2-digit",
|
|
6695
|
-
hourCycle: "h23"
|
|
6696
|
-
}).formatToParts(date);
|
|
6697
|
-
const hourPart = Number(parts.find((part) => part.type === "hour")?.value);
|
|
6698
|
-
const minute = Number(parts.find((part) => part.type === "minute")?.value);
|
|
6699
|
-
const hour = hourPart === 24 ? 0 : hourPart;
|
|
6700
|
-
if (Number.isNaN(hour) || Number.isNaN(minute)) return NaN;
|
|
6701
|
-
return hour * MINUTES_PER_HOUR + minute;
|
|
6702
|
-
}
|
|
6703
|
-
/**
|
|
6704
|
-
* Local YYYY-MM-DD for an ISO instant in the given zone.
|
|
6705
|
-
* Returns null if the inputs cannot be parsed.
|
|
6706
|
-
*/
|
|
6707
|
-
function getLocalDateKey(isoTimestamp, timeZone) {
|
|
6708
|
-
const date = new Date(isoTimestamp);
|
|
6709
|
-
if (Number.isNaN(date.getTime())) return null;
|
|
6710
|
-
if (!isValidTimeZone(timeZone)) return null;
|
|
6711
|
-
const parts = new Intl.DateTimeFormat("en-CA", {
|
|
6712
|
-
timeZone,
|
|
6713
|
-
year: "numeric",
|
|
6714
|
-
month: "2-digit",
|
|
6715
|
-
day: "2-digit"
|
|
6716
|
-
}).formatToParts(date);
|
|
6717
|
-
const year = parts.find((part) => part.type === "year")?.value;
|
|
6718
|
-
const month = parts.find((part) => part.type === "month")?.value;
|
|
6719
|
-
const day = parts.find((part) => part.type === "day")?.value;
|
|
6720
|
-
if (year === void 0 || year.length === 0) return null;
|
|
6721
|
-
if (month === void 0 || month.length === 0) return null;
|
|
6722
|
-
if (day === void 0 || day.length === 0) return null;
|
|
6723
|
-
return `${year}-${month}-${day}`;
|
|
6724
|
-
}
|
|
6725
|
-
const validTimeZoneCache = /* @__PURE__ */ new Map();
|
|
6726
|
-
function isValidTimeZone(timeZone) {
|
|
6727
|
-
if (typeof timeZone !== "string" || timeZone.length === 0) return false;
|
|
6728
|
-
const cached = validTimeZoneCache.get(timeZone);
|
|
6729
|
-
if (cached !== void 0) return cached;
|
|
6730
|
-
try {
|
|
6731
|
-
new Intl.DateTimeFormat("en-US", { timeZone });
|
|
6732
|
-
validTimeZoneCache.set(timeZone, true);
|
|
6733
|
-
return true;
|
|
6734
|
-
} catch {
|
|
6735
|
-
validTimeZoneCache.set(timeZone, false);
|
|
6736
|
-
return false;
|
|
6737
|
-
}
|
|
6596
|
+
//#region ../blocks/src/system/runtime/nodes/events/domain/destination.ts
|
|
6597
|
+
function isRecord$1(value) {
|
|
6598
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6599
|
+
}
|
|
6600
|
+
function isRuntimeEventDestination(value) {
|
|
6601
|
+
if (!isRecord$1(value) || typeof value.kind !== "string") return false;
|
|
6602
|
+
if (value.kind === "native") return (value.mode === "cms-managed" || value.mode === "system-managed") && typeof value.path === "string";
|
|
6603
|
+
return value.kind === "external" && typeof value.url === "string" && typeof value.label === "string";
|
|
6604
|
+
}
|
|
6605
|
+
function resolveRuntimeEventDestination(event) {
|
|
6606
|
+
if (isRuntimeEventDestination(event.destination)) return event.destination;
|
|
6607
|
+
return {
|
|
6608
|
+
kind: "native",
|
|
6609
|
+
mode: event.eventDestinationMode === "system-managed" ? "system-managed" : "cms-managed",
|
|
6610
|
+
path: typeof event.path === "string" ? event.path : ""
|
|
6611
|
+
};
|
|
6738
6612
|
}
|
|
6739
6613
|
//#endregion
|
|
6740
|
-
//#region ../calendar/src/
|
|
6741
|
-
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6745
|
-
|
|
6746
|
-
|
|
6747
|
-
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
|
|
6753
|
-
|
|
6754
|
-
|
|
6755
|
-
|
|
6756
|
-
|
|
6757
|
-
|
|
6614
|
+
//#region ../calendar/src/grid.ts
|
|
6615
|
+
const DAY_NAMES = [
|
|
6616
|
+
"Sun",
|
|
6617
|
+
"Mon",
|
|
6618
|
+
"Tue",
|
|
6619
|
+
"Wed",
|
|
6620
|
+
"Thu",
|
|
6621
|
+
"Fri",
|
|
6622
|
+
"Sat"
|
|
6623
|
+
];
|
|
6624
|
+
const MONTH_NAMES = [
|
|
6625
|
+
"January",
|
|
6626
|
+
"February",
|
|
6627
|
+
"March",
|
|
6628
|
+
"April",
|
|
6629
|
+
"May",
|
|
6630
|
+
"June",
|
|
6631
|
+
"July",
|
|
6632
|
+
"August",
|
|
6633
|
+
"September",
|
|
6634
|
+
"October",
|
|
6635
|
+
"November",
|
|
6636
|
+
"December"
|
|
6637
|
+
];
|
|
6638
|
+
function formatDateKey(date) {
|
|
6639
|
+
return `${String(date.year).padStart(4, "0")}-${String(date.month).padStart(2, "0")}-${String(date.day).padStart(2, "0")}`;
|
|
6640
|
+
}
|
|
6641
|
+
function isToday(date, today) {
|
|
6642
|
+
return isSameCalendarDay(date, today);
|
|
6643
|
+
}
|
|
6644
|
+
function isSameCalendarDay(left, right) {
|
|
6645
|
+
return left.year === right.year && left.month === right.month && left.day === right.day;
|
|
6646
|
+
}
|
|
6647
|
+
function addMonths(date, months) {
|
|
6648
|
+
const target = new Date(Date.UTC(date.year, date.month - 1 + months, 1, 12));
|
|
6649
|
+
const year = target.getUTCFullYear();
|
|
6650
|
+
const month = target.getUTCMonth() + 1;
|
|
6651
|
+
const lastDay = new Date(Date.UTC(year, month, 0, 12)).getUTCDate();
|
|
6652
|
+
return {
|
|
6653
|
+
year,
|
|
6654
|
+
month,
|
|
6655
|
+
day: Math.min(date.day, lastDay)
|
|
6656
|
+
};
|
|
6657
|
+
}
|
|
6658
|
+
function addDays(date, days) {
|
|
6659
|
+
const result = new Date(Date.UTC(date.year, date.month - 1, date.day + days, 12));
|
|
6660
|
+
return {
|
|
6661
|
+
year: result.getUTCFullYear(),
|
|
6662
|
+
month: result.getUTCMonth() + 1,
|
|
6663
|
+
day: result.getUTCDate()
|
|
6664
|
+
};
|
|
6665
|
+
}
|
|
6666
|
+
function shiftCalendarAnchorDate(date, view, steps) {
|
|
6667
|
+
return view === "week" ? addDays(date, steps * 7) : addMonths(date, steps);
|
|
6668
|
+
}
|
|
6669
|
+
function getMonthCalendarDays(year, month, startOfWeek) {
|
|
6670
|
+
const firstDay = {
|
|
6671
|
+
year,
|
|
6672
|
+
month,
|
|
6673
|
+
day: 1
|
|
6674
|
+
};
|
|
6675
|
+
const dayOfWeek = getDayOfWeek(firstDay);
|
|
6676
|
+
const gridStart = addDays(firstDay, -(startOfWeek === "monday" ? dayOfWeek === 0 ? 6 : dayOfWeek - 1 : dayOfWeek));
|
|
6677
|
+
return Array.from({ length: 42 }, (_, index) => addDays(gridStart, index));
|
|
6678
|
+
}
|
|
6679
|
+
function getWeekCalendarDays(baseDate, startOfWeek) {
|
|
6680
|
+
const dayOfWeek = getDayOfWeek(baseDate);
|
|
6681
|
+
const weekStart = addDays(baseDate, -(startOfWeek === "monday" ? dayOfWeek === 0 ? 6 : dayOfWeek - 1 : dayOfWeek));
|
|
6682
|
+
return Array.from({ length: 7 }, (_, index) => addDays(weekStart, index));
|
|
6683
|
+
}
|
|
6684
|
+
function getDayOfWeek(date) {
|
|
6685
|
+
return new Date(Date.UTC(date.year, date.month - 1, date.day, 12)).getUTCDay();
|
|
6686
|
+
}
|
|
6687
|
+
function getWeekCalendarDayTuple(baseDate, startOfWeek) {
|
|
6688
|
+
const days = getWeekCalendarDays(baseDate, startOfWeek);
|
|
6689
|
+
assertWeekCalendarDays(days);
|
|
6690
|
+
return days;
|
|
6691
|
+
}
|
|
6692
|
+
function assertWeekCalendarDays(days) {
|
|
6693
|
+
if (days.length !== 7) throw new Error("Expected exactly 7 calendar days");
|
|
6694
|
+
}
|
|
6695
|
+
function getOrderedDayNames(startOfWeek, dayNames = DAY_NAMES) {
|
|
6696
|
+
if (startOfWeek === "monday") {
|
|
6697
|
+
const sunday = dayNames[0] ?? "Sun";
|
|
6698
|
+
return [...dayNames.slice(1), sunday];
|
|
6699
|
+
}
|
|
6700
|
+
return [...dayNames];
|
|
6701
|
+
}
|
|
6702
|
+
function formatCalendarTitle(viewDate, view, days, monthNames = MONTH_NAMES) {
|
|
6703
|
+
if (view === "week") {
|
|
6704
|
+
const weekStart = days[0];
|
|
6705
|
+
const weekEnd = days[6];
|
|
6706
|
+
if (weekStart === void 0 || weekEnd === void 0) return `${monthNames[viewDate.month - 1] ?? ""} ${viewDate.year}`;
|
|
6707
|
+
const startMonth = monthNames[weekStart.month - 1] ?? "";
|
|
6708
|
+
const endMonth = monthNames[weekEnd.month - 1] ?? "";
|
|
6709
|
+
if (weekStart.month === weekEnd.month) return `${startMonth} ${weekStart.day} - ${weekEnd.day}, ${weekEnd.year}`;
|
|
6710
|
+
return `${startMonth} ${weekStart.day} - ${endMonth} ${weekEnd.day}, ${weekEnd.year}`;
|
|
6758
6711
|
}
|
|
6759
|
-
return
|
|
6712
|
+
return `${monthNames[viewDate.month - 1] ?? ""} ${viewDate.year}`;
|
|
6713
|
+
}
|
|
6714
|
+
function buildCalendarViewport(input) {
|
|
6715
|
+
const monthNames = input.monthNames ?? MONTH_NAMES;
|
|
6716
|
+
if (input.view === "week") {
|
|
6717
|
+
const days = getWeekCalendarDayTuple(input.anchorDate, input.startOfWeek);
|
|
6718
|
+
return {
|
|
6719
|
+
kind: "week",
|
|
6720
|
+
anchorDate: input.anchorDate,
|
|
6721
|
+
days,
|
|
6722
|
+
title: formatCalendarTitle(input.anchorDate, "week", days, monthNames)
|
|
6723
|
+
};
|
|
6724
|
+
}
|
|
6725
|
+
const days = getMonthCalendarDays(input.anchorDate.year, input.anchorDate.month, input.startOfWeek);
|
|
6726
|
+
return {
|
|
6727
|
+
kind: "month",
|
|
6728
|
+
anchorDate: input.anchorDate,
|
|
6729
|
+
days,
|
|
6730
|
+
title: formatCalendarTitle(input.anchorDate, "month", days, monthNames)
|
|
6731
|
+
};
|
|
6760
6732
|
}
|
|
6761
6733
|
/**
|
|
6762
6734
|
* Canonical responsive ladder for a user-configured column count: 1 column at
|
|
@@ -6796,254 +6768,10 @@ const GRID_BREAKPOINTS = [
|
|
|
6796
6768
|
"xl"
|
|
6797
6769
|
];
|
|
6798
6770
|
//#endregion
|
|
6799
|
-
//#region ../blocks/src/system/runtime/nodes/events/shared/
|
|
6771
|
+
//#region ../blocks/src/system/runtime/nodes/events/shared/listingLayout.ts
|
|
6800
6772
|
/**
|
|
6801
|
-
*
|
|
6802
|
-
*
|
|
6803
|
-
* for uncapped events so call sites can render no capacity indicator at all.
|
|
6804
|
-
*
|
|
6805
|
-
* The single source of truth for capacity math across event cards, agenda
|
|
6806
|
-
* rows, and timetable cells — keep wording variations in the call sites.
|
|
6807
|
-
*/
|
|
6808
|
-
function getEventAvailability(event) {
|
|
6809
|
-
if (event.capacity == null) return {
|
|
6810
|
-
available: null,
|
|
6811
|
-
isFull: false
|
|
6812
|
-
};
|
|
6813
|
-
const available = event.availableSpots ?? event.capacity - event.registeredCount;
|
|
6814
|
-
if (available <= 0) return {
|
|
6815
|
-
available: 0,
|
|
6816
|
-
isFull: true
|
|
6817
|
-
};
|
|
6818
|
-
return {
|
|
6819
|
-
available,
|
|
6820
|
-
isFull: false
|
|
6821
|
-
};
|
|
6822
|
-
}
|
|
6823
|
-
/**
|
|
6824
|
-
* Derive the three-state availability status (available / filling / waitlist)
|
|
6825
|
-
* plus a short pill label. Builds on {@link getEventAvailability} so the
|
|
6826
|
-
* capacity math (availableSpots with a `capacity - registeredCount` fallback)
|
|
6827
|
-
* stays consistent with the binary helper used elsewhere.
|
|
6828
|
-
*/
|
|
6829
|
-
function getEventAvailabilityStatus(event, options) {
|
|
6830
|
-
const threshold = options?.fillingThreshold ?? 2;
|
|
6831
|
-
const { available, isFull } = getEventAvailability(event);
|
|
6832
|
-
if (available == null) return {
|
|
6833
|
-
status: "available",
|
|
6834
|
-
available: null,
|
|
6835
|
-
isFull: false,
|
|
6836
|
-
label: null
|
|
6837
|
-
};
|
|
6838
|
-
if (isFull) return {
|
|
6839
|
-
status: "waitlist",
|
|
6840
|
-
available: 0,
|
|
6841
|
-
isFull: true,
|
|
6842
|
-
label: event.waitlistEnabled ? "Waitlist" : "Full"
|
|
6843
|
-
};
|
|
6844
|
-
if (available <= threshold) return {
|
|
6845
|
-
status: "filling",
|
|
6846
|
-
available,
|
|
6847
|
-
isFull: false,
|
|
6848
|
-
label: `${available} left`
|
|
6849
|
-
};
|
|
6850
|
-
return {
|
|
6851
|
-
status: "available",
|
|
6852
|
-
available,
|
|
6853
|
-
isFull: false,
|
|
6854
|
-
label: `${available} places`
|
|
6855
|
-
};
|
|
6856
|
-
}
|
|
6857
|
-
//#endregion
|
|
6858
|
-
//#region ../blocks/src/system/runtime/nodes/events/shared/destination.ts
|
|
6859
|
-
function isRecord$2(value) {
|
|
6860
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6861
|
-
}
|
|
6862
|
-
function isRuntimeEventDestination(value) {
|
|
6863
|
-
if (!isRecord$2(value) || typeof value.kind !== "string") return false;
|
|
6864
|
-
if (value.kind === "native") return (value.mode === "cms-managed" || value.mode === "system-managed") && typeof value.path === "string";
|
|
6865
|
-
return value.kind === "external" && typeof value.url === "string" && typeof value.label === "string";
|
|
6866
|
-
}
|
|
6867
|
-
function resolveRuntimeEventDestination(event) {
|
|
6868
|
-
if (isRuntimeEventDestination(event.destination)) return event.destination;
|
|
6869
|
-
return {
|
|
6870
|
-
kind: "native",
|
|
6871
|
-
mode: event.eventDestinationMode === "system-managed" ? "system-managed" : "cms-managed",
|
|
6872
|
-
path: typeof event.path === "string" ? event.path : ""
|
|
6873
|
-
};
|
|
6874
|
-
}
|
|
6875
|
-
//#endregion
|
|
6876
|
-
//#region ../blocks/src/system/runtime/nodes/events/shared/pricing.ts
|
|
6877
|
-
const DEFAULT_EVENT_CURRENCY = "USD";
|
|
6878
|
-
function resolveRuntimeEventPricing(event) {
|
|
6879
|
-
if (isPublicEventPricing(event.pricing)) return event.pricing;
|
|
6880
|
-
if (resolveRuntimeEventDestination(event).kind === "external") return {
|
|
6881
|
-
kind: "external",
|
|
6882
|
-
display: {
|
|
6883
|
-
kind: "external",
|
|
6884
|
-
label: "External registration"
|
|
6885
|
-
}
|
|
6886
|
-
};
|
|
6887
|
-
const legacy = event;
|
|
6888
|
-
const currency = readCurrency(legacy.currency);
|
|
6889
|
-
if (event.requiresRegistration === false) return {
|
|
6890
|
-
kind: "drop_in",
|
|
6891
|
-
currency,
|
|
6892
|
-
display: {
|
|
6893
|
-
kind: "free",
|
|
6894
|
-
currency
|
|
6895
|
-
}
|
|
6896
|
-
};
|
|
6897
|
-
if (legacy.pricingMode === "ticket_types") return {
|
|
6898
|
-
kind: "ticket_types",
|
|
6899
|
-
currency,
|
|
6900
|
-
ticketTypes: Array.isArray(legacy.ticketTypes) ? legacy.ticketTypes.filter(isPublicEventTicketType) : [],
|
|
6901
|
-
display: readTicketTypePriceDisplay(legacy.priceDisplay, currency)
|
|
6902
|
-
};
|
|
6903
|
-
const amount = typeof legacy.price === "number" ? legacy.price : 0;
|
|
6904
|
-
if (legacy.pricingType === "paid" && amount > 0) return {
|
|
6905
|
-
kind: "single_paid",
|
|
6906
|
-
amount,
|
|
6907
|
-
currency,
|
|
6908
|
-
display: {
|
|
6909
|
-
kind: "exact",
|
|
6910
|
-
amount,
|
|
6911
|
-
currency
|
|
6912
|
-
}
|
|
6913
|
-
};
|
|
6914
|
-
return {
|
|
6915
|
-
kind: "free_registration",
|
|
6916
|
-
currency,
|
|
6917
|
-
display: {
|
|
6918
|
-
kind: "free",
|
|
6919
|
-
currency
|
|
6920
|
-
}
|
|
6921
|
-
};
|
|
6922
|
-
}
|
|
6923
|
-
function readCurrency(value) {
|
|
6924
|
-
return typeof value === "string" && value.trim().length > 0 ? value : DEFAULT_EVENT_CURRENCY;
|
|
6925
|
-
}
|
|
6926
|
-
function isRecord$1(value) {
|
|
6927
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
6928
|
-
}
|
|
6929
|
-
function isPublicEventPricing(value) {
|
|
6930
|
-
if (!isRecord$1(value) || typeof value.kind !== "string") return false;
|
|
6931
|
-
return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "sliding_scale" || value.kind === "ticket_types" || value.kind === "whole_series" || value.kind === "external";
|
|
6932
|
-
}
|
|
6933
|
-
function isPublicEventTicketType(value) {
|
|
6934
|
-
return isRecord$1(value) && typeof value.id === "string";
|
|
6935
|
-
}
|
|
6936
|
-
function readTicketTypePriceDisplay(value, currency) {
|
|
6937
|
-
const display = readLegacyPriceDisplay(value, currency);
|
|
6938
|
-
return display.kind === "whole_series" || display.kind === "external" ? {
|
|
6939
|
-
kind: "unavailable",
|
|
6940
|
-
currency
|
|
6941
|
-
} : display;
|
|
6942
|
-
}
|
|
6943
|
-
function readLegacyPriceDisplay(value, currency) {
|
|
6944
|
-
if (!isRecord$1(value) || typeof value.kind !== "string") return {
|
|
6945
|
-
kind: "unavailable",
|
|
6946
|
-
currency
|
|
6947
|
-
};
|
|
6948
|
-
const displayCurrency = readCurrency(value.currency);
|
|
6949
|
-
switch (value.kind) {
|
|
6950
|
-
case "free": return {
|
|
6951
|
-
kind: "free",
|
|
6952
|
-
currency: displayCurrency
|
|
6953
|
-
};
|
|
6954
|
-
case "exact": return readAmount(value.amount) !== null ? {
|
|
6955
|
-
kind: "exact",
|
|
6956
|
-
amount: readAmount(value.amount) ?? 0,
|
|
6957
|
-
currency: displayCurrency
|
|
6958
|
-
} : {
|
|
6959
|
-
kind: "unavailable",
|
|
6960
|
-
currency
|
|
6961
|
-
};
|
|
6962
|
-
case "from": return readAmount(value.amount) !== null ? {
|
|
6963
|
-
kind: "from",
|
|
6964
|
-
amount: readAmount(value.amount) ?? 0,
|
|
6965
|
-
currency: displayCurrency
|
|
6966
|
-
} : {
|
|
6967
|
-
kind: "unavailable",
|
|
6968
|
-
currency
|
|
6969
|
-
};
|
|
6970
|
-
case "range": {
|
|
6971
|
-
const minAmount = readAmount(value.minAmount);
|
|
6972
|
-
const maxAmount = readAmount(value.maxAmount);
|
|
6973
|
-
return minAmount !== null && maxAmount !== null ? {
|
|
6974
|
-
kind: "range",
|
|
6975
|
-
minAmount,
|
|
6976
|
-
maxAmount,
|
|
6977
|
-
currency: displayCurrency
|
|
6978
|
-
} : {
|
|
6979
|
-
kind: "unavailable",
|
|
6980
|
-
currency
|
|
6981
|
-
};
|
|
6982
|
-
}
|
|
6983
|
-
case "mixed": return readAmount(value.paidFromAmount) !== null ? {
|
|
6984
|
-
kind: "mixed",
|
|
6985
|
-
paidFromAmount: readAmount(value.paidFromAmount) ?? 0,
|
|
6986
|
-
paidToAmount: readAmount(value.paidToAmount) ?? readAmount(value.paidFromAmount) ?? 0,
|
|
6987
|
-
currency: displayCurrency
|
|
6988
|
-
} : {
|
|
6989
|
-
kind: "unavailable",
|
|
6990
|
-
currency
|
|
6991
|
-
};
|
|
6992
|
-
case "unavailable": return {
|
|
6993
|
-
kind: "unavailable",
|
|
6994
|
-
currency: displayCurrency
|
|
6995
|
-
};
|
|
6996
|
-
case "whole_series": return isRecord$1(value.display) ? {
|
|
6997
|
-
kind: "whole_series",
|
|
6998
|
-
display: readCoursePriceDisplay(value.display, displayCurrency)
|
|
6999
|
-
} : {
|
|
7000
|
-
kind: "whole_series",
|
|
7001
|
-
display: {
|
|
7002
|
-
kind: "unavailable",
|
|
7003
|
-
currency: displayCurrency
|
|
7004
|
-
}
|
|
7005
|
-
};
|
|
7006
|
-
default: return {
|
|
7007
|
-
kind: "unavailable",
|
|
7008
|
-
currency
|
|
7009
|
-
};
|
|
7010
|
-
}
|
|
7011
|
-
}
|
|
7012
|
-
function readCoursePriceDisplay(value, currency) {
|
|
7013
|
-
switch (value.kind) {
|
|
7014
|
-
case "free": return {
|
|
7015
|
-
kind: "free",
|
|
7016
|
-
currency: readCurrency(value.currency)
|
|
7017
|
-
};
|
|
7018
|
-
case "exact": return readAmount(value.amount) !== null ? {
|
|
7019
|
-
kind: "exact",
|
|
7020
|
-
amount: readAmount(value.amount) ?? 0,
|
|
7021
|
-
currency: readCurrency(value.currency)
|
|
7022
|
-
} : {
|
|
7023
|
-
kind: "unavailable",
|
|
7024
|
-
currency
|
|
7025
|
-
};
|
|
7026
|
-
case "from": return readAmount(value.amount) !== null ? {
|
|
7027
|
-
kind: "from",
|
|
7028
|
-
amount: readAmount(value.amount) ?? 0,
|
|
7029
|
-
currency: readCurrency(value.currency)
|
|
7030
|
-
} : {
|
|
7031
|
-
kind: "unavailable",
|
|
7032
|
-
currency
|
|
7033
|
-
};
|
|
7034
|
-
default: return {
|
|
7035
|
-
kind: "unavailable",
|
|
7036
|
-
currency
|
|
7037
|
-
};
|
|
7038
|
-
}
|
|
7039
|
-
}
|
|
7040
|
-
function readAmount(value) {
|
|
7041
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
7042
|
-
}
|
|
7043
|
-
//#endregion
|
|
7044
|
-
//#region ../blocks/src/system/runtime/nodes/events/shared/utils.ts
|
|
7045
|
-
/**
|
|
7046
|
-
* Shared utility functions for event blocks
|
|
6773
|
+
* Layout classes for event listing containers and cards. Presentation
|
|
6774
|
+
* plumbing rather than event domain logic, so it lives beside the components.
|
|
7047
6775
|
*/
|
|
7048
6776
|
/**
|
|
7049
6777
|
* Column class mappings for grid layouts, derived from the canonical
|
|
@@ -7078,187 +6806,6 @@ function getCardOrientation(layout) {
|
|
|
7078
6806
|
case "compact": return "vertical";
|
|
7079
6807
|
}
|
|
7080
6808
|
}
|
|
7081
|
-
/**
|
|
7082
|
-
* Format date for display.
|
|
7083
|
-
* Returns: "Monday, January 15, 2025"
|
|
7084
|
-
*/
|
|
7085
|
-
function formatDate(isoTimestamp, options) {
|
|
7086
|
-
return formatBookingDate(toScheduledBookingDateTime({
|
|
7087
|
-
startsAt: isoTimestamp,
|
|
7088
|
-
timeZone: toBookingTimeZone(options?.timeZone ?? "UTC"),
|
|
7089
|
-
locale: options?.locale ?? "en-US"
|
|
7090
|
-
}), {
|
|
7091
|
-
weekday: "long",
|
|
7092
|
-
year: "numeric",
|
|
7093
|
-
month: "long",
|
|
7094
|
-
day: "numeric"
|
|
7095
|
-
});
|
|
7096
|
-
}
|
|
7097
|
-
/**
|
|
7098
|
-
* Format time for display.
|
|
7099
|
-
* Returns: "10:00 AM"
|
|
7100
|
-
*/
|
|
7101
|
-
function formatTime(isoTimestamp, options) {
|
|
7102
|
-
return formatBookingTime(toScheduledBookingDateTime({
|
|
7103
|
-
startsAt: isoTimestamp,
|
|
7104
|
-
timeZone: toBookingTimeZone(options?.timeZone ?? "UTC"),
|
|
7105
|
-
locale: options?.locale ?? "en-US"
|
|
7106
|
-
}), {
|
|
7107
|
-
hour: "numeric",
|
|
7108
|
-
minute: "2-digit",
|
|
7109
|
-
hour12: true
|
|
7110
|
-
});
|
|
7111
|
-
}
|
|
7112
|
-
function formatEventDateParts(args) {
|
|
7113
|
-
const scheduledRange = toScheduledBookingDateRange({
|
|
7114
|
-
startsAt: args.startsAt,
|
|
7115
|
-
endsAt: args.endsAt,
|
|
7116
|
-
timeZone: toBookingTimeZone(args.timeZone ?? "UTC"),
|
|
7117
|
-
locale: args.locale ?? "en-US"
|
|
7118
|
-
});
|
|
7119
|
-
const { date, time: start } = formatBookingDateParts(scheduledRange, { dateFormat: {
|
|
7120
|
-
weekday: "long",
|
|
7121
|
-
year: "numeric",
|
|
7122
|
-
month: "long",
|
|
7123
|
-
day: "numeric"
|
|
7124
|
-
} });
|
|
7125
|
-
return {
|
|
7126
|
-
date,
|
|
7127
|
-
timeRange: `${start} – ${formatBookingTime(toScheduledBookingDateTime({
|
|
7128
|
-
startsAt: args.endsAt,
|
|
7129
|
-
timeZone: scheduledRange.timeZone,
|
|
7130
|
-
locale: args.locale ?? "en-US"
|
|
7131
|
-
}))}`
|
|
7132
|
-
};
|
|
7133
|
-
}
|
|
7134
|
-
function formatEventCompactDateRail(isoTimestamp, options) {
|
|
7135
|
-
const dateTime = toScheduledBookingDateTime({
|
|
7136
|
-
startsAt: isoTimestamp,
|
|
7137
|
-
timeZone: toBookingTimeZone(options?.timeZone ?? "UTC"),
|
|
7138
|
-
locale: options?.locale ?? "en-US"
|
|
7139
|
-
});
|
|
7140
|
-
const weekday = formatBookingDate(dateTime, { weekday: "short" }).toLocaleUpperCase(options?.locale ?? "en-US");
|
|
7141
|
-
const month = formatBookingDate(dateTime, { month: "short" }).toLocaleUpperCase(options?.locale ?? "en-US");
|
|
7142
|
-
return {
|
|
7143
|
-
weekday,
|
|
7144
|
-
day: formatBookingDate(dateTime, { day: "numeric" }),
|
|
7145
|
-
month,
|
|
7146
|
-
label: formatBookingDate(dateTime, {
|
|
7147
|
-
weekday: "long",
|
|
7148
|
-
year: "numeric",
|
|
7149
|
-
month: "long",
|
|
7150
|
-
day: "numeric"
|
|
7151
|
-
})
|
|
7152
|
-
};
|
|
7153
|
-
}
|
|
7154
|
-
function formatTeamMemberNames(names) {
|
|
7155
|
-
const normalized = names.map((name) => name.trim()).filter(Boolean);
|
|
7156
|
-
if (normalized.length === 0) return null;
|
|
7157
|
-
const [firstName, secondName] = normalized;
|
|
7158
|
-
if (!firstName) return null;
|
|
7159
|
-
if (normalized.length === 1) return firstName;
|
|
7160
|
-
if (normalized.length === 2 && secondName) return `${firstName} and ${secondName}`;
|
|
7161
|
-
const finalName = normalized[normalized.length - 1] ?? "";
|
|
7162
|
-
return `${normalized.slice(0, -1).join(", ")}, and ${finalName}`;
|
|
7163
|
-
}
|
|
7164
|
-
function formatEventTeacherLine(event) {
|
|
7165
|
-
const names = formatTeamMemberNames((event.teamMembers ?? []).map((teamMember) => teamMember.name));
|
|
7166
|
-
return names ? `with ${names}` : null;
|
|
7167
|
-
}
|
|
7168
|
-
/**
|
|
7169
|
-
* Group events by their local date (YYYY-MM-DD key in each event's own
|
|
7170
|
-
* timezone). Thin domain wrapper over `groupItemsByDate` from the calendar
|
|
7171
|
-
* package; preserves the historical `Map<string, PublicEvent[]>` shape.
|
|
7172
|
-
*/
|
|
7173
|
-
function groupEventsByDate(events, calendarTimeZone) {
|
|
7174
|
-
const grouped = groupItemsByDate(events, {
|
|
7175
|
-
getStartsAt: (event) => event.startsAt,
|
|
7176
|
-
getTimeZone: () => calendarTimeZone
|
|
7177
|
-
});
|
|
7178
|
-
const map = /* @__PURE__ */ new Map();
|
|
7179
|
-
for (const [dateKey, bucket] of grouped) map.set(dateKey, [...bucket]);
|
|
7180
|
-
return map;
|
|
7181
|
-
}
|
|
7182
|
-
/**
|
|
7183
|
-
* Format event price for display.
|
|
7184
|
-
* @returns "Free", "£25", "£12 - £25", "Free / £12 - £25", "Course (From £40)", etc.
|
|
7185
|
-
*
|
|
7186
|
-
* Events render compact amounts (no trailing ".00"); the actual ADT→string
|
|
7187
|
-
* mapping lives in `formatBookingPriceDisplay` in @riverbankcms/core so all
|
|
7188
|
-
* surfaces stay consistent.
|
|
7189
|
-
*/
|
|
7190
|
-
function formatEventPrice(event) {
|
|
7191
|
-
return formatEventPricing(resolveRuntimeEventPricing(event), { decimals: "auto" });
|
|
7192
|
-
}
|
|
7193
|
-
/**
|
|
7194
|
-
* Format an event's price directly from its pricing value (without the full
|
|
7195
|
-
* event). Same output as {@link formatEventPrice}.
|
|
7196
|
-
*/
|
|
7197
|
-
function formatEventPriceDisplay(pricing) {
|
|
7198
|
-
return formatEventPricing(pricing, { decimals: "auto" });
|
|
7199
|
-
}
|
|
7200
|
-
function closedEventBookingLabel(reason) {
|
|
7201
|
-
switch (reason) {
|
|
7202
|
-
case "occurrence_cancelled":
|
|
7203
|
-
case "series_cancelled": return "Cancelled";
|
|
7204
|
-
case "occurrence_completed":
|
|
7205
|
-
case "series_completed": return "Completed";
|
|
7206
|
-
case "series_draft":
|
|
7207
|
-
case "series_archived":
|
|
7208
|
-
case "parent_archived":
|
|
7209
|
-
case "parent_inconsistent":
|
|
7210
|
-
case "not_public":
|
|
7211
|
-
case "already_started":
|
|
7212
|
-
case "enrollment_closed": return "Registration closed";
|
|
7213
|
-
default: return assertNever$2(reason);
|
|
7214
|
-
}
|
|
7215
|
-
}
|
|
7216
|
-
function resolveEventHref(event) {
|
|
7217
|
-
const destination = resolveRuntimeEventDestination(event);
|
|
7218
|
-
return destination.kind === "external" ? destination.url : destination.path;
|
|
7219
|
-
}
|
|
7220
|
-
function resolveEventLinkProps(event) {
|
|
7221
|
-
const href = resolveEventHref(event);
|
|
7222
|
-
return resolveRuntimeEventDestination(event).kind === "external" ? {
|
|
7223
|
-
href,
|
|
7224
|
-
target: "_blank",
|
|
7225
|
-
rel: "noopener noreferrer"
|
|
7226
|
-
} : { href };
|
|
7227
|
-
}
|
|
7228
|
-
/**
|
|
7229
|
-
* Resolve the CTA state for an event.
|
|
7230
|
-
* Shared by EventCard and EventCompactRow to keep sold-out, registration-closed,
|
|
7231
|
-
* and course-specific defaults consistent.
|
|
7232
|
-
*/
|
|
7233
|
-
function resolveEventCta(event, buttonText) {
|
|
7234
|
-
const { isFull: isSoldOut } = getEventAvailability(event);
|
|
7235
|
-
const destination = resolveRuntimeEventDestination(event);
|
|
7236
|
-
const isExternal = destination.kind === "external";
|
|
7237
|
-
const defaultButtonText = isExternal ? destination.label : event.bookingScope === "whole_series" ? "Book course" : "Book";
|
|
7238
|
-
const effectiveButtonText = buttonText ?? defaultButtonText;
|
|
7239
|
-
const href = resolveEventHref(event);
|
|
7240
|
-
if (event.bookingAvailability.kind === "closed") {
|
|
7241
|
-
const linksToClosedWholeSeriesDetails = event.bookingAvailability.reason === "enrollment_closed" && !isExternal;
|
|
7242
|
-
return {
|
|
7243
|
-
label: closedEventBookingLabel(event.bookingAvailability.reason),
|
|
7244
|
-
href,
|
|
7245
|
-
external: isExternal,
|
|
7246
|
-
hidden: !linksToClosedWholeSeriesDetails
|
|
7247
|
-
};
|
|
7248
|
-
}
|
|
7249
|
-
if (!isExternal && isSoldOut) return {
|
|
7250
|
-
label: "Sold out",
|
|
7251
|
-
href,
|
|
7252
|
-
external: false,
|
|
7253
|
-
hidden: true
|
|
7254
|
-
};
|
|
7255
|
-
return {
|
|
7256
|
-
label: effectiveButtonText,
|
|
7257
|
-
href,
|
|
7258
|
-
external: isExternal,
|
|
7259
|
-
hidden: false
|
|
7260
|
-
};
|
|
7261
|
-
}
|
|
7262
6809
|
//#endregion
|
|
7263
6810
|
//#region ../blocks/src/system/constants/events.ts
|
|
7264
6811
|
const eventCalendarDisplayModeValues = [
|
|
@@ -7274,6 +6821,13 @@ const eventCalendarListLayoutValues = [
|
|
|
7274
6821
|
"grid",
|
|
7275
6822
|
"compact"
|
|
7276
6823
|
];
|
|
6824
|
+
function isEventCalendarDisplayMode(value) {
|
|
6825
|
+
return typeof value === "string" && eventCalendarDisplayModeValues.includes(value);
|
|
6826
|
+
}
|
|
6827
|
+
function normalizeEventCalendarDisplayMode(input) {
|
|
6828
|
+
if (isEventCalendarDisplayMode(input.variant)) return input.variant;
|
|
6829
|
+
return isEventCalendarDisplayMode(input.displayMode) ? input.displayMode : void 0;
|
|
6830
|
+
}
|
|
7277
6831
|
//#endregion
|
|
7278
6832
|
//#region ../blocks/src/system/constants/buttonRoles.ts
|
|
7279
6833
|
/**
|
|
@@ -7411,6 +6965,158 @@ function getEventRuntimeFiltersKey(filters) {
|
|
|
7411
6965
|
});
|
|
7412
6966
|
}
|
|
7413
6967
|
//#endregion
|
|
6968
|
+
//#region ../blocks/src/system/blocks/events/shared/calendarWindow.ts
|
|
6969
|
+
function resolveCalendarReadProfile(content) {
|
|
6970
|
+
const mode = normalizeEventCalendarDisplayMode(content);
|
|
6971
|
+
return mode === "timetable" || mode === "week-board" ? "timetable" : "listing-card";
|
|
6972
|
+
}
|
|
6973
|
+
/** Runtime picker sentinels and bound loader IDs must describe the same query. */
|
|
6974
|
+
function normalizeCalendarFilterId(value) {
|
|
6975
|
+
const id = value?.trim();
|
|
6976
|
+
return !id || id === "all" ? void 0 : id;
|
|
6977
|
+
}
|
|
6978
|
+
const calendarMonthSchema = z.string().regex(/^\d{4}-(0[1-9]|1[0-2])$/).refine((month) => Number(month.slice(0, 4)) > 0, "Invalid calendar year");
|
|
6979
|
+
function calendarMonthDate(month) {
|
|
6980
|
+
return {
|
|
6981
|
+
year: Number(month.slice(0, 4)),
|
|
6982
|
+
month: Number(month.slice(5, 7)),
|
|
6983
|
+
day: 1
|
|
6984
|
+
};
|
|
6985
|
+
}
|
|
6986
|
+
function calendarMonthKey(date) {
|
|
6987
|
+
return `${String(date.year).padStart(4, "0")}-${String(date.month).padStart(2, "0")}`;
|
|
6988
|
+
}
|
|
6989
|
+
const monthNumber = (month) => {
|
|
6990
|
+
const date = calendarMonthDate(month);
|
|
6991
|
+
return date.year * 12 + date.month - 1;
|
|
6992
|
+
};
|
|
6993
|
+
const calendarMonthWindowSchema = z.object({
|
|
6994
|
+
startMonth: calendarMonthSchema,
|
|
6995
|
+
endMonthExclusive: calendarMonthSchema
|
|
6996
|
+
}).refine((window) => {
|
|
6997
|
+
const width = monthNumber(window.endMonthExclusive) - monthNumber(window.startMonth);
|
|
6998
|
+
return width > 0 && width <= 3;
|
|
6999
|
+
}, "Calendar windows must cover one to three months");
|
|
7000
|
+
z.object({
|
|
7001
|
+
startMonth: calendarMonthSchema.optional(),
|
|
7002
|
+
endMonthExclusive: calendarMonthSchema.optional(),
|
|
7003
|
+
afterStartsAt: z.string().datetime({ offset: true }).optional(),
|
|
7004
|
+
afterId: z.string().uuid().optional(),
|
|
7005
|
+
limit: z.coerce.number().int().min(1).max(200).default(100),
|
|
7006
|
+
stage: z.enum(["published", "preview"]).default("published"),
|
|
7007
|
+
readProfile: z.enum(["listing-card", "timetable"]).optional(),
|
|
7008
|
+
eventSurface: z.enum(eventSurfaceScopeValues).optional(),
|
|
7009
|
+
eventPresets: z.string().optional(),
|
|
7010
|
+
scheduleScope: z.enum(eventScheduleScopeValues).optional(),
|
|
7011
|
+
categoryIds: z.string().optional(),
|
|
7012
|
+
venueId: z.string().transform(normalizeCalendarFilterId).optional(),
|
|
7013
|
+
staffMemberId: z.string().transform(normalizeCalendarFilterId).optional()
|
|
7014
|
+
}).superRefine((query, ctx) => {
|
|
7015
|
+
if (Boolean(query.startMonth) !== Boolean(query.endMonthExclusive)) ctx.addIssue({
|
|
7016
|
+
code: "custom",
|
|
7017
|
+
message: "Both month bounds are required"
|
|
7018
|
+
});
|
|
7019
|
+
if (query.startMonth && query.endMonthExclusive && !calendarMonthWindowSchema.safeParse(query).success) ctx.addIssue({
|
|
7020
|
+
code: "custom",
|
|
7021
|
+
message: "Invalid calendar window"
|
|
7022
|
+
});
|
|
7023
|
+
if (Boolean(query.afterStartsAt) !== Boolean(query.afterId)) ctx.addIssue({
|
|
7024
|
+
code: "custom",
|
|
7025
|
+
message: "Both cursor fields are required"
|
|
7026
|
+
});
|
|
7027
|
+
if (query.afterStartsAt && !query.startMonth) ctx.addIssue({
|
|
7028
|
+
code: "custom",
|
|
7029
|
+
message: "A continuation requires explicit month bounds"
|
|
7030
|
+
});
|
|
7031
|
+
});
|
|
7032
|
+
function normalizedCsv(value) {
|
|
7033
|
+
return [...new Set((value ?? "").split(",").map((part) => part.trim()).filter(Boolean))].sort().join(",");
|
|
7034
|
+
}
|
|
7035
|
+
/** Pagination and window bounds deliberately do not change the query's identity. */
|
|
7036
|
+
function calendarQueryKey(siteId, stage, filters) {
|
|
7037
|
+
return JSON.stringify([
|
|
7038
|
+
siteId,
|
|
7039
|
+
stage ?? "published",
|
|
7040
|
+
filters.eventSurface ?? "all",
|
|
7041
|
+
normalizedCsv(filters.eventPresets),
|
|
7042
|
+
filters.scheduleScope ?? "any",
|
|
7043
|
+
normalizedCsv(filters.categoryIds),
|
|
7044
|
+
normalizeCalendarFilterId(filters.venueId) ?? "",
|
|
7045
|
+
normalizeCalendarFilterId(filters.staffMemberId) ?? "",
|
|
7046
|
+
filters.readProfile ?? "listing-card"
|
|
7047
|
+
]);
|
|
7048
|
+
}
|
|
7049
|
+
function calendarWindowMonths(window) {
|
|
7050
|
+
const first = calendarMonthDate(window.startMonth);
|
|
7051
|
+
return Array.from({ length: monthNumber(window.endMonthExclusive) - monthNumber(window.startMonth) }, (_, index) => calendarMonthKey(addMonths(first, index)));
|
|
7052
|
+
}
|
|
7053
|
+
function calendarWindowBounds(window, timeZone) {
|
|
7054
|
+
const start = buildBookingUtcDateWindow({
|
|
7055
|
+
startDate: formatLocalScheduleDate(calendarMonthDate(window.startMonth)),
|
|
7056
|
+
endDate: formatLocalScheduleDate(calendarMonthDate(window.startMonth)),
|
|
7057
|
+
timeZone
|
|
7058
|
+
});
|
|
7059
|
+
const end = buildBookingUtcDateWindow({
|
|
7060
|
+
startDate: formatLocalScheduleDate(calendarMonthDate(window.endMonthExclusive)),
|
|
7061
|
+
endDate: formatLocalScheduleDate(calendarMonthDate(window.endMonthExclusive)),
|
|
7062
|
+
timeZone
|
|
7063
|
+
});
|
|
7064
|
+
return {
|
|
7065
|
+
startInclusive: start.startAt.toISOString(),
|
|
7066
|
+
endExclusive: end.startAt.toISOString()
|
|
7067
|
+
};
|
|
7068
|
+
}
|
|
7069
|
+
const calendarSourceCursorSchema = z.object({
|
|
7070
|
+
startsAt: z.string().datetime({ offset: true }),
|
|
7071
|
+
occurrenceId: z.string().uuid()
|
|
7072
|
+
});
|
|
7073
|
+
z.discriminatedUnion("kind", [z.object({ kind: z.literal("complete") }), z.object({
|
|
7074
|
+
kind: z.literal("partial"),
|
|
7075
|
+
nextCursor: calendarSourceCursorSchema
|
|
7076
|
+
})]);
|
|
7077
|
+
const pageFields = {
|
|
7078
|
+
scope: z.object({
|
|
7079
|
+
key: z.string(),
|
|
7080
|
+
timeZone: z.string().transform(toBookingTimeZone)
|
|
7081
|
+
}),
|
|
7082
|
+
window: calendarMonthWindowSchema,
|
|
7083
|
+
initialToday: z.object({
|
|
7084
|
+
year: z.number().int(),
|
|
7085
|
+
month: z.number().int().min(1).max(12),
|
|
7086
|
+
day: z.number().int().min(1).max(31)
|
|
7087
|
+
}),
|
|
7088
|
+
events: z.array(publicEventSchema)
|
|
7089
|
+
};
|
|
7090
|
+
function calendarPageResponseError(page, expected) {
|
|
7091
|
+
if (page.scope.key !== expected.key || page.scope.timeZone !== expected.timeZone || page.window.startMonth !== expected.window.startMonth || page.window.endMonthExclusive !== expected.window.endMonthExclusive) return "scopeMismatch";
|
|
7092
|
+
if (page.kind === "complete" || !expected.cursor) return null;
|
|
7093
|
+
const difference = Date.parse(page.nextCursor.startsAt) - Date.parse(expected.cursor.startsAt);
|
|
7094
|
+
return difference < 0 || difference === 0 && page.nextCursor.occurrenceId <= expected.cursor.occurrenceId ? "nonAdvancingCursor" : null;
|
|
7095
|
+
}
|
|
7096
|
+
const calendarWindowPageSchema = z.discriminatedUnion("kind", [z.object({
|
|
7097
|
+
...pageFields,
|
|
7098
|
+
kind: z.literal("complete")
|
|
7099
|
+
}), z.object({
|
|
7100
|
+
...pageFields,
|
|
7101
|
+
kind: z.literal("partial"),
|
|
7102
|
+
nextCursor: calendarSourceCursorSchema
|
|
7103
|
+
})]);
|
|
7104
|
+
/** Split missing months without bridging covered months or exceeding the wire cap. */
|
|
7105
|
+
function planCalendarMonthRanges(months) {
|
|
7106
|
+
const sorted = [...new Set(months)].sort();
|
|
7107
|
+
const ranges = [];
|
|
7108
|
+
for (const month of sorted) {
|
|
7109
|
+
const previous = ranges.at(-1);
|
|
7110
|
+
const end = calendarMonthKey(addMonths(calendarMonthDate(month), 1));
|
|
7111
|
+
if (previous?.endMonthExclusive === month && monthNumber(end) - monthNumber(previous.startMonth) <= 3) previous.endMonthExclusive = end;
|
|
7112
|
+
else ranges.push({
|
|
7113
|
+
startMonth: month,
|
|
7114
|
+
endMonthExclusive: end
|
|
7115
|
+
});
|
|
7116
|
+
}
|
|
7117
|
+
return ranges;
|
|
7118
|
+
}
|
|
7119
|
+
//#endregion
|
|
7414
7120
|
//#region ../blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.ts
|
|
7415
7121
|
const eventSurfaceScopeSchema$1 = z.enum(eventSurfaceScopeValues);
|
|
7416
7122
|
const eventScheduleScopeSchema$1 = z.enum(eventScheduleScopeValues);
|
|
@@ -7427,6 +7133,7 @@ const eventCollectionFilterSourceSchemaShape = {
|
|
|
7427
7133
|
filterVenueId: z.string().nullable().optional()
|
|
7428
7134
|
};
|
|
7429
7135
|
const eventCollectionSourceSchemaShape = {
|
|
7136
|
+
calendarWindow: calendarWindowPageSchema.nullable().optional(),
|
|
7430
7137
|
events: z.array(publicEventSchema).nullable().optional(),
|
|
7431
7138
|
siteId: z.string(),
|
|
7432
7139
|
apiBaseUrl: z.string().optional(),
|
|
@@ -7480,6 +7187,7 @@ const eventCollectionDisplaySchemaShape = {
|
|
|
7480
7187
|
};
|
|
7481
7188
|
const eventCollectionHydrationSchema = z.object({
|
|
7482
7189
|
siteId: z.string(),
|
|
7190
|
+
calendarWindow: calendarWindowPageSchema.optional(),
|
|
7483
7191
|
stage: previewStageSchema.optional(),
|
|
7484
7192
|
prefetchedEvents: z.boolean(),
|
|
7485
7193
|
eventSurface: eventSurfaceScopeSchema$1,
|
|
@@ -7538,8 +7246,9 @@ function buildEventCollectionPresentationDisplay(source) {
|
|
|
7538
7246
|
};
|
|
7539
7247
|
}
|
|
7540
7248
|
function buildEventCollectionHydration(source, now = /* @__PURE__ */ new Date()) {
|
|
7541
|
-
const timeZone = toBookingTimeZone(source.bookingTimeZone);
|
|
7249
|
+
const timeZone = source.calendarWindow?.scope.timeZone ?? toBookingTimeZone(source.bookingTimeZone);
|
|
7542
7250
|
return {
|
|
7251
|
+
calendarWindow: source.calendarWindow ?? void 0,
|
|
7543
7252
|
siteId: source.siteId,
|
|
7544
7253
|
stage: source.stage,
|
|
7545
7254
|
prefetchedEvents: source.events != null,
|
|
@@ -7548,7 +7257,7 @@ function buildEventCollectionHydration(source, now = /* @__PURE__ */ new Date())
|
|
|
7548
7257
|
scheduleScope: normalizeEventScheduleScope(source.scheduleScope),
|
|
7549
7258
|
calendarContext: {
|
|
7550
7259
|
timeZone,
|
|
7551
|
-
initialToday: getLocalScheduleDate(now, timeZone)
|
|
7260
|
+
initialToday: source.calendarWindow?.initialToday ?? getLocalScheduleDate(now, timeZone)
|
|
7552
7261
|
}
|
|
7553
7262
|
};
|
|
7554
7263
|
}
|
|
@@ -10264,7 +9973,9 @@ const unsupportedEventRegistrationPageSurfaceSubjectSchema = z.object({
|
|
|
10264
9973
|
"unsupportedSubject",
|
|
10265
9974
|
"invalidEventSeriesId",
|
|
10266
9975
|
"invalidEventSeriesBookingScope",
|
|
10267
|
-
"invalidEventOfferingId"
|
|
9976
|
+
"invalidEventOfferingId",
|
|
9977
|
+
"invalidEventOfferingBookingScope",
|
|
9978
|
+
"invalidEventOfferingCatalogue"
|
|
10268
9979
|
])
|
|
10269
9980
|
});
|
|
10270
9981
|
const eventRegistrationPageSurfaceSubjectSchema = z.unknown().transform((value, ctx) => {
|
|
@@ -10291,7 +10002,7 @@ function resolveEventRegistrationScope(context) {
|
|
|
10291
10002
|
if (context.subject?.kind === "eventOffering") return {
|
|
10292
10003
|
kind: "pageSurfaceOffering",
|
|
10293
10004
|
offeringId: context.subject.eventOfferingId,
|
|
10294
|
-
seriesIds: context.subject.
|
|
10005
|
+
seriesIds: context.subject.catalogueEventSeriesIds
|
|
10295
10006
|
};
|
|
10296
10007
|
if (context.subject?.kind === "unsupported") return {
|
|
10297
10008
|
kind: "unsupportedPageSurfaceSubject",
|
|
@@ -10452,7 +10163,7 @@ function buildEventCalendarDisplay(source) {
|
|
|
10452
10163
|
listColumns: source.listColumns ?? source.columns
|
|
10453
10164
|
}),
|
|
10454
10165
|
kind: "event-calendar",
|
|
10455
|
-
displayMode: source
|
|
10166
|
+
displayMode: normalizeEventCalendarDisplayMode(source) ?? "combined",
|
|
10456
10167
|
className: source.className ?? null,
|
|
10457
10168
|
events: (source.events ?? []).slice().sort((left, right) => new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime()),
|
|
10458
10169
|
boardTitle: normalizeOptionalText(source.boardTitle),
|
|
@@ -10498,7 +10209,10 @@ const eventCalendarInteractiveIslandPropsCodec = createInteractiveIslandCodec({
|
|
|
10498
10209
|
render: createZodCodec(eventCalendarRenderSchema)
|
|
10499
10210
|
},
|
|
10500
10211
|
buildRender: (source) => ({
|
|
10501
|
-
display: buildEventCalendarDisplay(source)
|
|
10212
|
+
display: buildEventCalendarDisplay(source.calendarWindow && (source.variant ?? source.displayMode ?? "combined") !== "combined" && (source.variant ?? source.displayMode) !== "list" ? {
|
|
10213
|
+
...source,
|
|
10214
|
+
events: source.calendarWindow.events
|
|
10215
|
+
} : source),
|
|
10502
10216
|
hydration: buildEventCollectionHydration(source)
|
|
10503
10217
|
})
|
|
10504
10218
|
}),
|
|
@@ -10559,54 +10273,6 @@ const eventCombinedInteractiveIslandPropsCodec = createInteractiveIslandCodec({
|
|
|
10559
10273
|
})
|
|
10560
10274
|
});
|
|
10561
10275
|
//#endregion
|
|
10562
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationSurface.ts
|
|
10563
|
-
function planEventRegistrationScope(input) {
|
|
10564
|
-
const subject = input.subject;
|
|
10565
|
-
const selectedRunOffering = input.wholeSeriesOffering;
|
|
10566
|
-
if (subject?.kind !== "eventOffering" || !selectedRunOffering) return {
|
|
10567
|
-
kind: "context",
|
|
10568
|
-
events: resolveEventRegistrationScopedEvents(input.events, {
|
|
10569
|
-
occurrenceContext: input.occurrenceContext,
|
|
10570
|
-
subject
|
|
10571
|
-
})
|
|
10572
|
-
};
|
|
10573
|
-
if (!(selectedRunOffering.eventOfferingId === subject.eventOfferingId && subject.availableEventSeriesIds.some((seriesId) => seriesId === selectedRunOffering.eventSeriesId))) return { kind: "invalidSelectedRun" };
|
|
10574
|
-
return {
|
|
10575
|
-
kind: "selectedRun",
|
|
10576
|
-
events: input.events.filter((event) => event.seriesId === selectedRunOffering.eventSeriesId),
|
|
10577
|
-
offering: selectedRunOffering
|
|
10578
|
-
};
|
|
10579
|
-
}
|
|
10580
|
-
function planEventRegistrationSurface(input) {
|
|
10581
|
-
const scope = planEventRegistrationScope(input);
|
|
10582
|
-
if (scope.kind === "invalidSelectedRun") return { kind: "unavailableWholeSeries" };
|
|
10583
|
-
const scopedEvents = scope.events;
|
|
10584
|
-
const bookingScopes = new Set(scopedEvents.map((event) => event.bookingScope));
|
|
10585
|
-
if (scope.kind === "selectedRun") {
|
|
10586
|
-
if (bookingScopes.size !== 1 || !bookingScopes.has("whole_series")) return { kind: "unavailableWholeSeries" };
|
|
10587
|
-
return {
|
|
10588
|
-
kind: "wholeSeries",
|
|
10589
|
-
offerings: [scope.offering]
|
|
10590
|
-
};
|
|
10591
|
-
}
|
|
10592
|
-
if (!input.occurrenceContext && !input.subject && bookingScopes.has("single_occurrence")) return {
|
|
10593
|
-
kind: "occurrence",
|
|
10594
|
-
events: scopedEvents.filter((event) => event.bookingScope === "single_occurrence")
|
|
10595
|
-
};
|
|
10596
|
-
if (bookingScopes.size === 0 || bookingScopes.has("single_occurrence")) return bookingScopes.has("whole_series") ? { kind: "mixedBookingScopes" } : {
|
|
10597
|
-
kind: "occurrence",
|
|
10598
|
-
events: scopedEvents
|
|
10599
|
-
};
|
|
10600
|
-
const requiredSeriesIds = new Set(scopedEvents.map((event) => event.seriesId));
|
|
10601
|
-
const wholeSeriesOffering = input.wholeSeriesOffering;
|
|
10602
|
-
const offerings = (wholeSeriesOffering ? [wholeSeriesOffering, ...input.wholeSeriesOfferings.filter((offering) => offering.eventSeriesId !== wholeSeriesOffering.eventSeriesId)] : input.wholeSeriesOfferings).filter((offering) => requiredSeriesIds.has(offering.eventSeriesId));
|
|
10603
|
-
const loadedSeriesIds = new Set(offerings.map((offering) => offering.eventSeriesId));
|
|
10604
|
-
return [...requiredSeriesIds].every((seriesId) => loadedSeriesIds.has(seriesId)) && offerings.length > 0 ? {
|
|
10605
|
-
kind: "wholeSeries",
|
|
10606
|
-
offerings
|
|
10607
|
-
} : { kind: "unavailableWholeSeries" };
|
|
10608
|
-
}
|
|
10609
|
-
//#endregion
|
|
10610
10276
|
//#region ../blocks/src/system/runtime/nodes/event-registration/wizardSteps.ts
|
|
10611
10277
|
/**
|
|
10612
10278
|
* Steps that are part of the main wizard and should show the step indicator
|
|
@@ -10675,7 +10341,7 @@ function resolveEventRequiresPayment(input) {
|
|
|
10675
10341
|
if (input.eligibility) return input.eligibility.requiresPayment;
|
|
10676
10342
|
if (input.selectedTicketType) return input.selectedTicketType.priceAmount > 0;
|
|
10677
10343
|
if (!input.event) return false;
|
|
10678
|
-
return publicEventPricingType(
|
|
10344
|
+
return publicEventPricingType(input.event.pricing) === "paid";
|
|
10679
10345
|
}
|
|
10680
10346
|
function resolveDiscountContext(input) {
|
|
10681
10347
|
const selection = input.paymentSelection.method ? input.paymentSelection : null;
|
|
@@ -10703,7 +10369,6 @@ function resolveDiscountContext(input) {
|
|
|
10703
10369
|
function toRegistrationEvent(event) {
|
|
10704
10370
|
return {
|
|
10705
10371
|
...event,
|
|
10706
|
-
pricing: resolveRuntimeEventPricing(event),
|
|
10707
10372
|
selectionId: event.id,
|
|
10708
10373
|
registrationSubject: {
|
|
10709
10374
|
kind: "occurrence",
|
|
@@ -10714,120 +10379,38 @@ function toRegistrationEvent(event) {
|
|
|
10714
10379
|
function toRegistrationEvents(events) {
|
|
10715
10380
|
return events.filter((event) => event.bookingScope === "single_occurrence").map(toRegistrationEvent);
|
|
10716
10381
|
}
|
|
10717
|
-
|
|
10718
|
-
|
|
10719
|
-
|
|
10720
|
-
|
|
10721
|
-
|
|
10722
|
-
|
|
10723
|
-
|
|
10724
|
-
|
|
10725
|
-
|
|
10726
|
-
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
const
|
|
10730
|
-
switch (offering.pricing.pricingStrategy) {
|
|
10731
|
-
case "free": return {
|
|
10732
|
-
kind: "free_registration",
|
|
10733
|
-
currency: offering.currency,
|
|
10734
|
-
display: {
|
|
10735
|
-
kind: "free",
|
|
10736
|
-
currency: offering.currency
|
|
10737
|
-
}
|
|
10738
|
-
};
|
|
10739
|
-
case "single": {
|
|
10740
|
-
const amount = offering.pricing.singlePriceAmount ?? 0;
|
|
10741
|
-
return amount === 0 ? {
|
|
10742
|
-
kind: "free_registration",
|
|
10743
|
-
currency: offering.currency,
|
|
10744
|
-
display: {
|
|
10745
|
-
kind: "free",
|
|
10746
|
-
currency: offering.currency
|
|
10747
|
-
}
|
|
10748
|
-
} : {
|
|
10749
|
-
kind: "single_paid",
|
|
10750
|
-
amount,
|
|
10751
|
-
currency: offering.currency,
|
|
10752
|
-
display: {
|
|
10753
|
-
kind: "exact",
|
|
10754
|
-
amount,
|
|
10755
|
-
currency: offering.currency
|
|
10756
|
-
}
|
|
10757
|
-
};
|
|
10758
|
-
}
|
|
10759
|
-
case "tiered": return {
|
|
10760
|
-
kind: "ticket_types",
|
|
10761
|
-
currency: offering.currency,
|
|
10762
|
-
ticketTypes: resolved.selectableOptions.map((option) => toWholeSeriesTicketType(option)),
|
|
10763
|
-
display: resolved.display
|
|
10764
|
-
};
|
|
10765
|
-
case "sliding_scale": return {
|
|
10766
|
-
kind: "sliding_scale",
|
|
10767
|
-
minAmount: offering.pricing.slidingMinAmount ?? 0,
|
|
10768
|
-
maxAmount: offering.pricing.slidingMaxAmount ?? 0,
|
|
10769
|
-
suggestedAmount: offering.pricing.slidingSuggestedAmount ?? null,
|
|
10770
|
-
currency: offering.currency,
|
|
10771
|
-
display: {
|
|
10772
|
-
kind: "range",
|
|
10773
|
-
minAmount: offering.pricing.slidingMinAmount ?? 0,
|
|
10774
|
-
maxAmount: offering.pricing.slidingMaxAmount ?? 0,
|
|
10775
|
-
currency: offering.currency
|
|
10776
|
-
}
|
|
10777
|
-
};
|
|
10778
|
-
}
|
|
10779
|
-
}
|
|
10780
|
-
function toAttendanceModes(offering) {
|
|
10781
|
-
return (offering.deliveryMode === "hybrid" ? ["in_person", "online"] : [offering.deliveryMode]).map((mode) => ({
|
|
10782
|
-
mode,
|
|
10783
|
-
capacity: offering.enrollmentCapacity,
|
|
10784
|
-
registeredCount: offering.enrolledCount,
|
|
10785
|
-
availableSpots: offering.availableSpots,
|
|
10786
|
-
waitlistEnabled: offering.waitlistEnabled
|
|
10787
|
-
}));
|
|
10788
|
-
}
|
|
10789
|
-
function toWholeSeriesRegistrationEvent(offering) {
|
|
10790
|
-
const firstSession = offering.sessions[0];
|
|
10791
|
-
const lastSession = offering.sessions[offering.sessions.length - 1];
|
|
10382
|
+
/**
|
|
10383
|
+
* Project one whole-series run onto the registration surface.
|
|
10384
|
+
*
|
|
10385
|
+
* Capacity, pricing, payment terms and consent come straight off the canonical
|
|
10386
|
+
* Event record; only the schedule is widened from the single occurrence to the
|
|
10387
|
+
* live run. A run without live sessions has no registration event.
|
|
10388
|
+
*/
|
|
10389
|
+
function toWholeSeriesRegistrationEvent(group) {
|
|
10390
|
+
const { representative, run } = group;
|
|
10391
|
+
const sessions = orderedLiveRunSessions(run.sessions);
|
|
10392
|
+
const firstSession = sessions[0];
|
|
10393
|
+
if (!firstSession) return null;
|
|
10394
|
+
const lastSession = sessions[sessions.length - 1] ?? firstSession;
|
|
10792
10395
|
return {
|
|
10793
|
-
|
|
10396
|
+
...representative,
|
|
10397
|
+
selectionId: run.eventSeriesId,
|
|
10794
10398
|
registrationSubject: {
|
|
10795
10399
|
kind: "wholeSeries",
|
|
10796
|
-
eventSeriesId:
|
|
10797
|
-
sessions
|
|
10798
|
-
},
|
|
10799
|
-
seriesId: offering.eventSeriesId,
|
|
10800
|
-
title: offering.title,
|
|
10801
|
-
startsAt: firstSession?.startsAt ?? "",
|
|
10802
|
-
endsAt: lastSession?.endsAt ?? firstSession?.endsAt ?? "",
|
|
10803
|
-
bookingAvailability: offering.enrollmentOpen ? { kind: "open" } : {
|
|
10804
|
-
kind: "closed",
|
|
10805
|
-
reason: "enrollment_closed"
|
|
10400
|
+
eventSeriesId: run.eventSeriesId,
|
|
10401
|
+
sessions
|
|
10806
10402
|
},
|
|
10807
|
-
|
|
10808
|
-
|
|
10809
|
-
|
|
10810
|
-
registeredCount: offering.enrolledCount,
|
|
10811
|
-
availableSpots: offering.availableSpots,
|
|
10812
|
-
waitlistEnabled: offering.waitlistEnabled,
|
|
10813
|
-
venue: offering.venue ? {
|
|
10814
|
-
...offering.venue,
|
|
10815
|
-
location: null
|
|
10816
|
-
} : null,
|
|
10817
|
-
eventCategory: null,
|
|
10818
|
-
teamMembers: offering.teamMembers,
|
|
10819
|
-
status: offering.status,
|
|
10820
|
-
timeZone: firstSession?.timeZone ?? "UTC",
|
|
10821
|
-
pricing: toWholeSeriesPricing(offering),
|
|
10822
|
-
paymentTerms: offering.paymentTerms,
|
|
10823
|
-
consent: offering.consent,
|
|
10824
|
-
requireGuestDetails: offering.requireGuestDetails,
|
|
10825
|
-
acceptsPasses: false,
|
|
10826
|
-
acceptsMemberships: offering.acceptsMemberships
|
|
10403
|
+
startsAt: firstSession.startsAt,
|
|
10404
|
+
endsAt: lastSession.endsAt,
|
|
10405
|
+
timeZone: firstSession.timeZone
|
|
10827
10406
|
};
|
|
10828
10407
|
}
|
|
10829
|
-
function toWholeSeriesRegistrationEvents(
|
|
10830
|
-
return
|
|
10408
|
+
function toWholeSeriesRegistrationEvents(events) {
|
|
10409
|
+
return groupPublicEventsByRun(events).map(toWholeSeriesRegistrationEvent).filter((event) => event !== null);
|
|
10410
|
+
}
|
|
10411
|
+
/** An occurrence-page context must not replace a whole run's booking start. */
|
|
10412
|
+
function getRegistrationStartAt(event, occurrenceContext) {
|
|
10413
|
+
return event?.registrationSubject.kind === "wholeSeries" ? event.startsAt : occurrenceContext?.startsAt ?? event?.startsAt;
|
|
10831
10414
|
}
|
|
10832
10415
|
//#endregion
|
|
10833
10416
|
//#region ../blocks/src/system/runtime/nodes/event-registration.interactive.ts
|
|
@@ -10848,8 +10431,7 @@ const eventRegistrationHydrationSchemaShape = {
|
|
|
10848
10431
|
occurrenceContext: occurrenceContextSchema.optional(),
|
|
10849
10432
|
subject: eventRegistrationPageSurfaceSubjectSchema.nullable().optional(),
|
|
10850
10433
|
events: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
10851
|
-
|
|
10852
|
-
wholeSeriesOffering: publicWholeSeriesOfferingSchema.nullable().optional(),
|
|
10434
|
+
wholeSeriesRunEvents: z.array(eventRegistrationPublicEventSchema).nullable().optional(),
|
|
10853
10435
|
maxTickets: z.string().optional(),
|
|
10854
10436
|
showVenue: z.boolean().optional(),
|
|
10855
10437
|
showCapacity: z.boolean().optional(),
|
|
@@ -10867,7 +10449,6 @@ const eventRegistrationSourceSchema = z.object({
|
|
|
10867
10449
|
portalToken: z.string().nullable().optional(),
|
|
10868
10450
|
previewToken: z.string().nullable().optional(),
|
|
10869
10451
|
...eventRegistrationHydrationSchemaShape,
|
|
10870
|
-
subjectWholeSeriesOffering: publicWholeSeriesOfferingSchema.nullable().optional(),
|
|
10871
10452
|
className: z.string().nullable().optional(),
|
|
10872
10453
|
buttonText: z.string().nullable().optional(),
|
|
10873
10454
|
maxTickets: z.string().nullable().optional(),
|
|
@@ -10902,7 +10483,8 @@ const eventRegistrationIslandMetaCodec = createZodCodec(z.object({
|
|
|
10902
10483
|
}));
|
|
10903
10484
|
const eventRegistrationIslandMetaKeys = defineInteractiveIslandMetaKeys("siteId", "apiBaseUrl", "portalToken", "previewToken", "stage");
|
|
10904
10485
|
function buildEventRegistrationDisplay(source) {
|
|
10905
|
-
|
|
10486
|
+
const selectedRun = resolveSelectedWholeSeriesRun(source);
|
|
10487
|
+
if (selectedRun && (!selectedRun.run.enrollmentOpen || toWholeSeriesRegistrationEvent(selectedRun) === null)) return {
|
|
10906
10488
|
kind: "event-registration",
|
|
10907
10489
|
state: "registration-closed",
|
|
10908
10490
|
className: source.className ?? null,
|
|
@@ -10920,13 +10502,11 @@ function buildEventRegistrationDisplay(source) {
|
|
|
10920
10502
|
summaryButtonText: source.buttonText?.trim() || "Register"
|
|
10921
10503
|
};
|
|
10922
10504
|
}
|
|
10923
|
-
function resolveWholeSeriesOffering(source) {
|
|
10924
|
-
return source.wholeSeriesOffering ?? source.subjectWholeSeriesOffering ?? null;
|
|
10925
|
-
}
|
|
10926
10505
|
function buildEventRegistrationShellStepLabels(source) {
|
|
10927
|
-
const
|
|
10928
|
-
if (
|
|
10929
|
-
const selectedEvent = toWholeSeriesRegistrationEvent(
|
|
10506
|
+
const selectedRun = resolveSelectedWholeSeriesRun(source);
|
|
10507
|
+
if (selectedRun) {
|
|
10508
|
+
const selectedEvent = toWholeSeriesRegistrationEvent(selectedRun);
|
|
10509
|
+
if (!selectedEvent) return EVENT_REGISTRATION_GENERIC_SHELL_STEP_LABELS;
|
|
10930
10510
|
return getWizardStepsForContext(true, resolveEventRequiresPayment({
|
|
10931
10511
|
eligibility: null,
|
|
10932
10512
|
selectedTicketType: null,
|
|
@@ -10947,16 +10527,31 @@ function buildEventRegistrationShellStepLabels(source) {
|
|
|
10947
10527
|
}) : false).map((step) => shellLabelForRegistrationStep(step, scopedEvents));
|
|
10948
10528
|
}
|
|
10949
10529
|
function scopeEventRegistrationEvents(source) {
|
|
10950
|
-
|
|
10530
|
+
const scoped = scopeEventRegistrationSourceEvents(source);
|
|
10531
|
+
return [...toRegistrationEvents(scoped), ...toWholeSeriesRegistrationEvents(scoped)];
|
|
10951
10532
|
}
|
|
10533
|
+
/**
|
|
10534
|
+
* Every event this surface may register for, from both of its loads.
|
|
10535
|
+
*
|
|
10536
|
+
* The date page and the run read answer different questions and can name the
|
|
10537
|
+
* same occurrence, so the two lists are joined and any occurrence that arrives
|
|
10538
|
+
* twice is kept once, in the order the date page gave it.
|
|
10539
|
+
*/
|
|
10952
10540
|
function scopeEventRegistrationSourceEvents(source) {
|
|
10953
|
-
const
|
|
10954
|
-
|
|
10955
|
-
|
|
10541
|
+
const byOccurrenceId = /* @__PURE__ */ new Map();
|
|
10542
|
+
for (const event of [...source.events ?? [], ...source.wholeSeriesRunEvents ?? []]) if (!byOccurrenceId.has(event.occurrenceId)) byOccurrenceId.set(event.occurrenceId, event);
|
|
10543
|
+
return resolveEventRegistrationScopedEvents([...byOccurrenceId.values()], {
|
|
10956
10544
|
occurrenceContext: source.occurrenceContext,
|
|
10957
10545
|
subject: source.subject
|
|
10958
10546
|
});
|
|
10959
|
-
|
|
10547
|
+
}
|
|
10548
|
+
/**
|
|
10549
|
+
* The one run this surface is registering for, when the scoped events describe
|
|
10550
|
+
* exactly one. More than one run means the visitor still has to choose.
|
|
10551
|
+
*/
|
|
10552
|
+
function resolveSelectedWholeSeriesRun(source) {
|
|
10553
|
+
const runs = groupPublicEventsByRun(scopeEventRegistrationSourceEvents(source));
|
|
10554
|
+
return runs.length === 1 ? runs[0] : null;
|
|
10960
10555
|
}
|
|
10961
10556
|
function shellLabelForRegistrationStep(step, events) {
|
|
10962
10557
|
switch (step) {
|
|
@@ -10996,8 +10591,6 @@ const eventRegistrationBlockRuntime = defineClientOwnedBlockRuntime({
|
|
|
10996
10591
|
occurrenceContext: source.occurrenceContext ?? null,
|
|
10997
10592
|
subject: source.subject ?? null,
|
|
10998
10593
|
events,
|
|
10999
|
-
wholeSeriesOfferings: source.wholeSeriesOfferings ?? null,
|
|
11000
|
-
wholeSeriesOffering: resolveWholeSeriesOffering(source),
|
|
11001
10594
|
maxTickets: source.maxTickets ?? void 0,
|
|
11002
10595
|
showVenue: source.showVenue,
|
|
11003
10596
|
showCapacity: source.showCapacity,
|
|
@@ -11016,8 +10609,7 @@ function normalizeEventRegistrationEventInput(value) {
|
|
|
11016
10609
|
if (!isRecord(value)) return value;
|
|
11017
10610
|
return {
|
|
11018
10611
|
...value,
|
|
11019
|
-
destination: resolveRuntimeEventDestination(value)
|
|
11020
|
-
pricing: resolveRuntimeEventPricing(value)
|
|
10612
|
+
destination: resolveRuntimeEventDestination(value)
|
|
11021
10613
|
};
|
|
11022
10614
|
}
|
|
11023
10615
|
function isRecord(value) {
|
|
@@ -12483,4 +12075,4 @@ function defineIslandPropsDecoder(kind) {
|
|
|
12483
12075
|
};
|
|
12484
12076
|
}
|
|
12485
12077
|
//#endregion
|
|
12486
|
-
export {
|
|
12078
|
+
export { getOrderedDayNames as $, toBookingTimeZone as $t, isSemanticSpacing as A, isBookingRequirementConsentFieldId as At, buildEventRuntimeFilters as B, CANCELLED_SESSION_STATUS as Bt, WIZARD_STEPS as C, resolveBookingPaymentStep as Ct, staticHeaderChromeRuntime as D, projectSelectedAppointmentConsentIntoForm as Dt, buildEventCalendarListingRender as E, toSelectedCollectionOptionKind as Et, calendarWindowBounds as F, err as Ft, getCardOrientation as G, formatBookingDateTime as Gt, normalizeCsvIds as H, addLocalScheduleDays as Ht, calendarWindowMonths as I, ok as It, addDays as J, formatLocalScheduleDate as Jt, getContainerClass as K, formatBookingInstant as Kt, calendarWindowPageSchema as L, okWith as Lt, calendarMonthDate as M, isRecord$4 as Mt, calendarPageResponseError as N, assertNever$1 as Nt, resolveEventRegistrationScopedEvents as O, resolveSelectedAppointmentConsent as Ot, calendarQueryKey as P, clearWorkflowFeedback as Pt, getDayOfWeek as Q, resolveBookingTimeZoneId as Qt, planCalendarMonthRanges as R, reportWorkflowError as Rt, resolveRegistrationTarget as S, resolveAppointmentCheckoutVerificationState as St, getWizardStepsForContext as T, resolveDefaultBookingServiceId as Tt, normalizeCsvString as U, formatBookingDate as Ut, getEventRuntimeFiltersKey as V, resolveWholeSeriesBookingPhase as Vt, normalizeOptionalId as W, formatBookingDateParts as Wt, buildCalendarViewport as X, getLocalScheduleDate as Xt, addMonths as Y, getBookingLocalDateKey as Yt, formatDateKey as Z, parseBookingLocalDate as Zt, toWholeSeriesRegistrationEvents as _, getBookingServiceSlidingScale as _t, buildProductDetailDisplay as a, publicEventPricingCurrency as an, groupPublicEventsByRun as at, resolveDiscountContext as b, parseBookingCurrencyInputToCents as bt, EMPTY_COMMERCE_CART_STATE as c, publicEventPricingStrategy as cn, resolveOnColorForThemeToken as ct, deriveCommerceCheckoutState as d, assertNever$2 as dn, normalizeCardRole as dt, toScheduledBookingDateRange as en, getWeekCalendarDays as et, parseStoredCommerceCartState as f, logger as ft, toRegistrationEvents as g, getBookingRedirectStateFromLocation as gt, getRegistrationStartAt as h, formatBookingSubmissionPreparationError as ht, buildProductCardDisplay as i, isPublicEventPricingOptionDisplayable as in, resolveRuntimeEventDestination as it, resolveSpacing as j, RichTextDocSchema as jt, SEMANTIC_SPACING_VALUES as k, BOOKING_FORM_DATA_RESERVED_KEYS as kt, buildPassCartItem as l, publicEventPricingType as ln, resolveTokenOrCssColorValue as lt, reduceCommerceCart as m, formatBookingCentsAsCurrencyInput as mt, getShopDisplayForItems as n, formatBookingPriceDisplay as nn, isToday as nt, formatCommercePrice as o, publicEventPricingDisplay as on, boxBackgroundSchema as ot, productItemKey as p, deriveBookingFormViewState as pt, MONTH_NAMES as q, formatBookingTime as qt, buildCartDisplay as r, formatEventPricing as rn, shiftCalendarAnchorDate as rt, formatInterval as s, publicEventPricingOptions as sn, isCssColorLiteral as st, defineIslandPropsDecoder as t, toScheduledBookingDateTime as tn, isSameCalendarDay as tt, buildProductCartItem as u, formatCurrencyAmount as un, themeButtonClassName as ut, findEventByOccurrenceId as v, getBookingSuccessMessage as vt, getStepNumber as w, resolveBookingSiteId as wt, resolveEventRequiresPayment as x, prepareBookingSubmission as xt, findPreSelectedEvent as y, isBookingServiceSlidingAmountInRange as yt, resolveCalendarReadProfile as z, reportWorkflowSuccess as zt };
|