@riverbankcms/sdk 0.134.0 → 0.135.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 +4 -3
- package/README.md +1 -1
- package/dist/{PreviewEditorSidebar-DfRhJPFQ.mjs → PreviewEditorSidebar-roNY0GVy.mjs} +4 -4
- package/dist/{PreviewEditorUI-Dppxcr_g.mjs → PreviewEditorUI-KboDbEh_.mjs} +3 -3
- package/dist/{PreviewQueryProvider-D51gQaG3.mjs → PreviewQueryProvider-DcgaESkm.mjs} +1 -1
- package/dist/{SdkPreviewModeRuntime-8CyGCXir.mjs → SdkPreviewModeRuntime-DBrF7Caa.mjs} +5 -5
- package/dist/{SiteChromeCustomizeContext-DVMTMvqA.mjs → SiteChromeCustomizeContext-DrIEpJKn.mjs} +4070 -8011
- package/dist/_dts/ai/src/contracts/proposals.d.ts +165 -165
- package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +15 -15
- package/dist/_dts/api/src/bookingConfig.d.ts +1 -1
- package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +25 -60
- package/dist/_dts/api/src/bookingOperations.d.ts +111 -161
- package/dist/_dts/api/src/bookingPaymentTermSchemas.d.ts +123 -0
- package/dist/_dts/api/src/bookingRecords.d.ts +13 -13
- package/dist/_dts/api/src/bookingRefundOutcomes.d.ts +4 -4
- package/dist/_dts/api/src/bookingSessionSummaryTypes.d.ts +34 -0
- package/dist/_dts/api/src/bookings.d.ts +5 -9
- package/dist/_dts/api/src/commercePortalEndpoints.d.ts +7 -7
- package/dist/_dts/api/src/communications.d.ts +1 -1
- package/dist/_dts/api/src/endpoints.d.ts +29 -109
- package/dist/_dts/api/src/eventManagementContracts.d.ts +1 -1
- package/dist/_dts/api/src/eventSeriesRegistrationEndpointDefinitions.d.ts +43 -0
- package/dist/_dts/api/src/index.d.ts +3 -4
- package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
- package/dist/_dts/api/src/participantMessaging.d.ts +2 -2
- package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +8 -0
- package/dist/_dts/api/src/publicExperience/commerceEndpoints.d.ts +32 -28
- package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +85 -5
- package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +1 -1
- package/dist/_dts/api/src/publicExperience/wholeSeriesEndpoints.d.ts +9 -100
- package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +7 -6
- package/dist/_dts/api/src/publicWholeSeriesEndpointDefinitions.d.ts +0 -32
- package/dist/_dts/api/src/sdk-event-payment-terms.d.ts +1 -1
- package/dist/_dts/api/src/sdk-event-upsert.d.ts +1 -1
- package/dist/_dts/api/src/siteOperations.d.ts +2 -2
- package/dist/_dts/api/src/types.d.ts +1 -1
- package/dist/_dts/api/src/{courses.d.ts → wholeSeriesOfferings.d.ts} +43 -95
- package/dist/_dts/blocks/src/client.d.ts +0 -5
- package/dist/_dts/blocks/src/contracts/index.d.ts +1 -1
- package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +5 -94
- package/dist/_dts/blocks/src/portal/dateFormatting.d.ts +3 -0
- package/dist/_dts/blocks/src/portal/types.d.ts +17 -20
- package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +147 -42
- package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +10 -10
- package/dist/_dts/blocks/src/system/blocks/events/whole-series/types.d.ts +3 -0
- package/dist/_dts/blocks/src/system/blocks/index.d.ts +0 -2
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +3 -3
- package/dist/_dts/blocks/src/system/blocks/offerings-preview/scheduleSummary.d.ts +3 -3
- package/dist/_dts/blocks/src/system/constants/blockKinds.d.ts +1 -1
- package/dist/_dts/blocks/src/system/node/builder.d.ts +0 -1
- package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +9 -12
- package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +2 -44
- 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 +1 -1
- package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +99 -59
- package/dist/_dts/blocks/src/system/runtime/api/types/portal.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/api/types/shop.d.ts +19 -16
- package/dist/_dts/blocks/src/system/runtime/api/types/waitlist-claims.d.ts +7 -0
- package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +24 -247
- package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +13 -126
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessEventRegistrationFlow.d.ts +0 -1
- package/dist/_dts/blocks/src/system/runtime/hooks/usePaymentVerification.d.ts +2 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-details/WholeSeriesPricingDisplay.d.ts +8 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationBookingLayer.d.ts +17 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.d.ts +24 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentBlockingPanel.d.ts +18 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +5 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/constants.d.ts +1 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +1 -3
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.d.ts +7 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventScope.d.ts +0 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +7 -8
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDerivations.d.ts +4 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationEventAdapter.d.ts +3 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationStateMachine.d.ts +5 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.d.ts +28 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/sessionStorage.d.ts +12 -11
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +53 -45
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +10 -6
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +9 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +20 -5
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.d.ts +20 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +5 -56
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/waitlistClaimRestoration.d.ts +20 -0
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +6 -22
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/DateTimeTile.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +6 -6
- package/dist/_dts/blocks/src/system/runtime/nodes/offerings-preview.d.ts +2 -2
- package/dist/_dts/blocks/src/system/runtime/shared/bookingPaymentOptions.d.ts +6 -1
- package/dist/_dts/blocks/src/system/runtime/shared/components/DiscountCodeDisclosure.d.ts +1 -13
- package/dist/_dts/blocks/src/system/runtime/shared/components/LoggedInAsUser.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/shared/components/MembershipHero.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/shared/components/StateIcon.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/shared/index.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/shared/types.d.ts +1 -1
- package/dist/_dts/blocks/src/system/runtime/shared/utils/checkoutUrls.d.ts +2 -2
- package/dist/_dts/commerce/src/index.d.ts +16 -0
- package/dist/_dts/commerce/src/money.d.ts +122 -0
- package/dist/_dts/commerce/src/moneyContracts.d.ts +178 -0
- package/dist/_dts/commerce/src/moneyDateUtils.d.ts +22 -0
- package/dist/_dts/commerce/src/moneyPayments.d.ts +59 -0
- package/dist/_dts/commerce/src/moneyPlanningTime.d.ts +4 -0
- package/dist/_dts/commerce/src/moneyReceiptReadModel.d.ts +68 -0
- package/dist/_dts/commerce/src/moneyReport.d.ts +105 -0
- package/dist/_dts/commerce/src/moneyReportBreakdowns.d.ts +3 -0
- package/dist/_dts/commerce/src/moneyReportKindFilter.d.ts +4 -0
- package/dist/_dts/commerce/src/moneyReportPage.d.ts +132 -0
- package/dist/_dts/commerce/src/purchase/checkoutCollectionPlan.d.ts +1 -1
- package/dist/_dts/commerce/src/purchase/confirmationEmailPayment.d.ts +1 -1
- package/dist/_dts/commerce/src/purchase/orderCompletionEmailPlan.d.ts +3 -3
- package/dist/_dts/commerce/src/purchase/orderFulfillmentPlan.d.ts +6 -25
- package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +4 -4
- package/dist/_dts/commerce/src/purchase/orderPlanningTypes.d.ts +11 -11
- package/dist/_dts/commerce/src/purchase/orderTypes.d.ts +1 -1
- package/dist/_dts/commerce/src/purchase/persistedCheckoutLines.d.ts +1 -1
- package/dist/_dts/commerce/src/purchase/types.d.ts +12 -8
- package/dist/_dts/commerce/src/shop/digitalFulfillment.d.ts +111 -0
- package/dist/_dts/commerce/src/shop/fulfillmentStatus.d.ts +10 -0
- package/dist/_dts/commerce/src/shop/inventoryRestore.d.ts +13 -0
- package/dist/_dts/commerce/src/shop/shippingAddress.d.ts +18 -0
- package/dist/_dts/commerce/src/types/json.d.ts +3 -0
- package/dist/_dts/commerce/src/utils/isPlainRecord.d.ts +1 -0
- package/dist/_dts/commerce/src/waitlists.d.ts +172 -0
- package/dist/_dts/content-model/src/content-types/builtin-schemas.d.ts +0 -30
- package/dist/_dts/content-model/src/content-types/builtins.d.ts +2 -39
- package/dist/_dts/content-model/src/metadataConfig.d.ts +0 -1
- package/dist/_dts/content-model/src/templates/defaults.d.ts +0 -68
- package/dist/_dts/core/src/branded.d.ts +3 -3
- package/dist/_dts/core/src/event-pricing.d.ts +6 -6
- package/dist/_dts/core/src/participants.d.ts +17 -17
- package/dist/_dts/core/src/rectification.d.ts +1 -1
- package/dist/_dts/db/src/generated/supabase/database.types.d.ts +890 -2154
- package/dist/_dts/sdk/src/bookings/index.d.ts +4 -5
- package/dist/_dts/sdk/src/bookings/types.d.ts +34 -4
- package/dist/_dts/sdk/src/rendering/islands/types.d.ts +4 -6
- package/dist/_dts/sdk/src/version.d.ts +1 -1
- package/dist/_dts/theme-core/src/blocks/vars/index.d.ts +0 -2
- package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +1 -1
- package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +1 -1
- package/dist/client/{usePolling-UN4WKnaM.mjs → BookingConsentAgreement-BQqwi8Oa.mjs} +180 -4
- package/dist/client/{DiscountCodeDisclosure-CfuPOHD0.mjs → DiscountCodeDisclosure-B97aMo0V.mjs} +13 -27
- package/dist/client/{EventCombined.client-DB8Qfzi-.mjs → EventCombined.client-Bs2Iw9Q6.mjs} +3 -3
- package/dist/client/{EventListing.client-DD4X8hp4.mjs → EventListing.client-C4QUQdmg.mjs} +2 -2
- package/dist/client/{LeafletStaticMap-QhgIBQbv.mjs → LeafletStaticMap-CwWRk69M.mjs} +1 -1
- package/dist/client/{accordion-DFXpLvwg.mjs → accordion-BA0j8Mpw.mjs} +1 -1
- package/dist/client/{bookingForm-sI05d3lk.mjs → bookingForm-Br2e41H0.mjs} +6 -7
- package/dist/client/bookings.mjs +912 -1906
- package/dist/client/{carousel-wjyWTZCh.mjs → carousel-B4dmwnpD.mjs} +1 -1
- package/dist/client/{cart-DCwdpA4i.mjs → cart-B_ckGW4b.mjs} +3 -3
- package/dist/client/{checkout-DTDW3l0R.mjs → checkout-DAyspHdf.mjs} +3 -3
- package/dist/client/{checkoutUrls-DQYC_Br-.mjs → checkoutUrls-BuseL0dw.mjs} +4 -2
- package/dist/client/client.mjs +5074 -9309
- package/dist/client/{context-TSK1CGx8.mjs → context-DljQn8L5.mjs} +15 -69
- package/dist/client/{eventCalendar-B0Zg-i_w.mjs → eventCalendar-pJu3FUod.mjs} +5 -5
- package/dist/client/{eventCombined-B8Y2wizd.mjs → eventCombined-B6Kacm9F.mjs} +3 -3
- package/dist/client/{eventDetails-DPDOwURJ.mjs → eventDetails-CaX9z1pv.mjs} +8 -8
- package/dist/client/{eventListing-CjBcmSLn.mjs → eventListing-B9aXPO-I.mjs} +3 -3
- package/dist/client/{eventRegistration-CK30HsAq.mjs → eventRegistration-CBSovBkg.mjs} +4522 -3690
- package/dist/client/{form-CUXfsABE.mjs → form-Cm0tu_7o.mjs} +2 -2
- package/dist/client/{headerSection-N-mN3rjr.mjs → headerSection-OgRtHeKS.mjs} +2 -2
- package/dist/client/hooks.mjs +430 -692
- package/dist/client/{locationMap-oiIDQMBt.mjs → locationMap-DmjcYqNM.mjs} +2 -2
- package/dist/client/{newsletterForm-CkQ2tTrM.mjs → newsletterForm-D08OZQAC.mjs} +2 -2
- package/dist/client/{productDetail-CnidyrsN.mjs → productDetail-BqZeu2P4.mjs} +3 -3
- package/dist/client/{productList-CttYcS_S.mjs → productList-mNyIF9FG.mjs} +3 -3
- package/dist/client/{propsDecoder-CeUMxI9a.mjs → propsDecoder-DwHXRm9X.mjs} +4656 -4419
- package/dist/client/rendering/client.mjs +59504 -62158
- package/dist/client/rendering/islands.mjs +17 -19
- package/dist/client/rendering.mjs +5354 -9683
- package/dist/client/{scrollToBlock-lPr1oqxB.mjs → scrollToBlock-DtmdM3v-.mjs} +2 -2
- package/dist/client/{shop-DXQtMo2O.mjs → shop-CNjZK16F.mjs} +6 -6
- package/dist/client/{shop-commerce-quDL411J.mjs → shop-commerce-DkNNao1J.mjs} +6 -6
- package/dist/client/{shop-commerce-store-Dnu-8Iub.mjs → shop-commerce-store-9WA--zuW.mjs} +1 -1
- package/dist/client/{shopShared-BWPUURvG.mjs → shopShared-CHCVfccY.mjs} +3 -3
- package/dist/client/{useEventFilters-DRhWp2_5.mjs → useEventFilters-DvuaB4ZN.mjs} +3 -3
- package/dist/preview-next/before-render.mjs +40 -161
- package/dist/preview-next/client/runtime.mjs +4 -4
- package/dist/preview-next/keepAlive.mjs +40 -161
- package/dist/preview-next/middleware.mjs +40 -161
- package/dist/{previewAuthStore-BFKd4LrN.mjs → previewAuthStore-C7ksxt5b.mjs} +40 -161
- package/dist/{sdk-runtime-Ca5RD78X.mjs → sdk-runtime-3GhW4knb.mjs} +2 -2
- package/dist/{separator-CMhj6BTi.mjs → separator-D3bCWYYb.mjs} +1 -1
- package/dist/server/components.mjs +535 -2950
- package/dist/server/config-validation.mjs +430 -692
- package/dist/server/config.mjs +430 -692
- package/dist/server/data.mjs +430 -692
- package/dist/server/index.mjs +41 -162
- package/dist/server/next.mjs +549 -2964
- package/dist/server/page-converter.mjs +331 -560
- package/dist/server/prebuild.mjs +1 -1
- package/dist/server/rendering/server.mjs +534 -2855
- package/dist/server/rendering.mjs +535 -2950
- package/dist/server/routing.mjs +574 -1065
- package/dist/server/server.mjs +444 -706
- package/dist/server/theme-bridge.mjs +41 -1524
- package/dist/styles/index.css +41 -1348
- package/package.json +1 -1
- package/dist/_dts/api/src/courseEndpointDefinitions.d.ts +0 -99
- package/dist/_dts/blocks/src/client/course-registration.d.ts +0 -5
- package/dist/_dts/blocks/src/system/blocks/course-details.d.ts +0 -134
- package/dist/_dts/blocks/src/system/blocks/course-registration.d.ts +0 -130
- package/dist/_dts/blocks/src/system/blocks/courses/shared/index.d.ts +0 -3
- package/dist/_dts/blocks/src/system/blocks/courses/shared/pricing.d.ts +0 -2
- package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +0 -1
- package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +0 -1
- package/dist/_dts/blocks/src/system/runtime/api/types/courses.d.ts +0 -135
- package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessWholeSeriesRegistrationFlow.d.ts +0 -28
- package/dist/_dts/blocks/src/system/runtime/nodes/course-details/logic.d.ts +0 -11
- package/dist/_dts/blocks/src/system/runtime/nodes/course-details/runs.d.ts +0 -10
- package/dist/_dts/blocks/src/system/runtime/nodes/course-details/view.d.ts +0 -15
- package/dist/_dts/blocks/src/system/runtime/nodes/course-details.server.d.ts +0 -20
- package/dist/_dts/blocks/src/system/runtime/nodes/course-page-surface-scope.d.ts +0 -14
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.client.d.ts +0 -10
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.interactive.d.ts +0 -181
- package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.server.d.ts +0 -12
- package/dist/_dts/blocks/src/system/runtime/nodes/event-details/CoursePricingDisplay.d.ts +0 -8
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/BookingModeStep.d.ts +0 -32
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/CheckIcon.d.ts +0 -4
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/ErrorStep.d.ts +0 -17
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/MembershipHero.d.ts +0 -12
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/PaymentFailedStep.d.ts +0 -17
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/PortalAuthSidebar.d.ts +0 -9
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/StepIndicator.d.ts +0 -6
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/SuccessStep.d.ts +0 -14
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/VerifyingTimeoutStep.d.ts +0 -17
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WaitlistStep.d.ts +0 -12
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WholeSeriesRegistrationActiveSteps.d.ts +0 -9
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WholeSeriesRegistrationErrorBoundary.d.ts +0 -25
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WholeSeriesRegistrationTerminalContent.d.ts +0 -8
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WholeSeriesRegistrationWizard.d.ts +0 -8
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/components.d.ts +0 -46
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/index.d.ts +0 -18
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/presentation.d.ts +0 -7
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/pricing.d.ts +0 -14
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/types.d.ts +0 -105
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesEligibility.d.ts +0 -24
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesPaymentVerification.d.ts +0 -10
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationActions.d.ts +0 -35
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationPortal.d.ts +0 -7
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationSelection.d.ts +0 -35
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationWizard.d.ts +0 -185
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesWaitlistSelection.d.ts +0 -14
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/utils.d.ts +0 -43
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/whole-series-registration.headless.contract.d.ts +0 -325
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/whole-series-registration.headless.planning.d.ts +0 -27
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/wholeSeriesPageSurfaceScope.d.ts +0 -17
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/wholeSeriesRegistrationViewState.d.ts +0 -21
- package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/wizardSteps.d.ts +0 -30
- package/dist/_dts/sdk/src/rendering/islands/enhancers/courseRegistration.d.ts +0 -3
- package/dist/_dts/theme-core/src/blocks/vars/course-details.d.ts +0 -16
- package/dist/_dts/theme-core/src/blocks/vars/course-registration.d.ts +0 -21
- package/dist/client/BookingConsentAgreement-BxgpGEFD.mjs +0 -160
- package/dist/client/WholeSeriesRegistrationWizard-DwtC7bCs.mjs +0 -2546
- package/dist/client/courseRegistration-A-Tg7qw_.mjs +0 -52
- package/dist/client/pricing-Caa0QWzh.mjs +0 -195
package/dist/client/bookings.mjs
CHANGED
|
@@ -2557,8 +2557,8 @@ const EVENTS = {
|
|
|
2557
2557
|
path: "/public/sites/{siteId}/events/checkout",
|
|
2558
2558
|
method: "POST"
|
|
2559
2559
|
},
|
|
2560
|
-
|
|
2561
|
-
path: "/public/sites/{siteId}/events/
|
|
2560
|
+
registrationOptions: {
|
|
2561
|
+
path: "/public/sites/{siteId}/events/registration-options",
|
|
2562
2562
|
method: "POST",
|
|
2563
2563
|
authScope: "portal"
|
|
2564
2564
|
},
|
|
@@ -2572,31 +2572,10 @@ const WHOLE_SERIES = {
|
|
|
2572
2572
|
path: "/public/sites/{siteId}/dated-offerings/whole-series",
|
|
2573
2573
|
method: "GET"
|
|
2574
2574
|
},
|
|
2575
|
-
enroll: {
|
|
2576
|
-
path: "/public/sites/{siteId}/dated-offerings/whole-series/enroll",
|
|
2577
|
-
method: "POST",
|
|
2578
|
-
authScope: "portal",
|
|
2579
|
-
skipPreviewStage: true
|
|
2580
|
-
},
|
|
2581
|
-
checkout: {
|
|
2582
|
-
path: "/public/sites/{siteId}/dated-offerings/whole-series/checkout",
|
|
2583
|
-
method: "POST",
|
|
2584
|
-
authScope: "portal"
|
|
2585
|
-
},
|
|
2586
|
-
checkEligibility: {
|
|
2587
|
-
path: "/public/sites/{siteId}/dated-offerings/whole-series/check-eligibility",
|
|
2588
|
-
method: "POST",
|
|
2589
|
-
authScope: "portal"
|
|
2590
|
-
},
|
|
2591
2575
|
waitlistClaimResolve: {
|
|
2592
2576
|
path: "/public/sites/{siteId}/waitlists/claim/resolve",
|
|
2593
2577
|
method: "POST",
|
|
2594
2578
|
authScope: "portal"
|
|
2595
|
-
},
|
|
2596
|
-
registrationStatus: {
|
|
2597
|
-
path: "/public/sites/{siteId}/dated-offerings/whole-series/registration-status",
|
|
2598
|
-
method: "GET",
|
|
2599
|
-
authScope: "portal"
|
|
2600
2579
|
}
|
|
2601
2580
|
};
|
|
2602
2581
|
const SHOP = {
|
|
@@ -2757,19 +2736,19 @@ const PORTAL = {
|
|
|
2757
2736
|
skipPreviewStage: true
|
|
2758
2737
|
},
|
|
2759
2738
|
getWholeSeriesBookingQuestions: {
|
|
2760
|
-
path: "/portal/dated-offerings/whole-series/{
|
|
2739
|
+
path: "/portal/dated-offerings/whole-series/{registrationId}/booking-questions",
|
|
2761
2740
|
method: "GET",
|
|
2762
2741
|
authScope: "portal",
|
|
2763
2742
|
skipPreviewStage: true
|
|
2764
2743
|
},
|
|
2765
2744
|
updateWholeSeriesBookingQuestions: {
|
|
2766
|
-
path: "/portal/dated-offerings/whole-series/{
|
|
2745
|
+
path: "/portal/dated-offerings/whole-series/{registrationId}/booking-questions",
|
|
2767
2746
|
method: "PUT",
|
|
2768
2747
|
authScope: "portal",
|
|
2769
2748
|
skipPreviewStage: true
|
|
2770
2749
|
},
|
|
2771
2750
|
cancelWholeSeriesRegistration: {
|
|
2772
|
-
path: "/portal/dated-offerings/whole-series/{
|
|
2751
|
+
path: "/portal/dated-offerings/whole-series/{registrationId}/cancel",
|
|
2773
2752
|
method: "POST",
|
|
2774
2753
|
authScope: "portal",
|
|
2775
2754
|
skipPreviewStage: true
|
|
@@ -3165,10 +3144,10 @@ function createBlockApi(config) {
|
|
|
3165
3144
|
body: data
|
|
3166
3145
|
});
|
|
3167
3146
|
},
|
|
3168
|
-
async
|
|
3147
|
+
async getRegistrationOptions(data) {
|
|
3169
3148
|
const sid = requireSiteId();
|
|
3170
|
-
const path = buildPath(EVENTS.
|
|
3171
|
-
return request(EVENTS.
|
|
3149
|
+
const path = buildPath(EVENTS.registrationOptions.path, { siteId: sid });
|
|
3150
|
+
return request(EVENTS.registrationOptions, {
|
|
3172
3151
|
path,
|
|
3173
3152
|
body: data
|
|
3174
3153
|
});
|
|
@@ -3178,26 +3157,10 @@ function createBlockApi(config) {
|
|
|
3178
3157
|
const path = buildPath(EVENTS.registrationStatus.path, { siteId: sid });
|
|
3179
3158
|
return request(EVENTS.registrationStatus, {
|
|
3180
3159
|
path,
|
|
3181
|
-
query:
|
|
3160
|
+
query: params,
|
|
3182
3161
|
skipDedup: true
|
|
3183
3162
|
});
|
|
3184
3163
|
},
|
|
3185
|
-
async registerForWholeSeries(data) {
|
|
3186
|
-
const sid = requireSiteId();
|
|
3187
|
-
const path = buildPath(WHOLE_SERIES.enroll.path, { siteId: sid });
|
|
3188
|
-
return request(WHOLE_SERIES.enroll, {
|
|
3189
|
-
path,
|
|
3190
|
-
body: data
|
|
3191
|
-
});
|
|
3192
|
-
},
|
|
3193
|
-
async checkWholeSeriesEligibility(data) {
|
|
3194
|
-
const sid = requireSiteId();
|
|
3195
|
-
const path = buildPath(WHOLE_SERIES.checkEligibility.path, { siteId: sid });
|
|
3196
|
-
return request(WHOLE_SERIES.checkEligibility, {
|
|
3197
|
-
path,
|
|
3198
|
-
body: data
|
|
3199
|
-
});
|
|
3200
|
-
},
|
|
3201
3164
|
async resolveWaitlistClaim(data) {
|
|
3202
3165
|
const sid = requireSiteId();
|
|
3203
3166
|
const path = buildPath(WHOLE_SERIES.waitlistClaimResolve.path, { siteId: sid });
|
|
@@ -3206,23 +3169,6 @@ function createBlockApi(config) {
|
|
|
3206
3169
|
body: { claimToken: data.claimToken }
|
|
3207
3170
|
});
|
|
3208
3171
|
},
|
|
3209
|
-
async createWholeSeriesCheckout(data) {
|
|
3210
|
-
const sid = requireSiteId();
|
|
3211
|
-
const path = buildPath(WHOLE_SERIES.checkout.path, { siteId: sid });
|
|
3212
|
-
return request(WHOLE_SERIES.checkout, {
|
|
3213
|
-
path,
|
|
3214
|
-
body: data
|
|
3215
|
-
});
|
|
3216
|
-
},
|
|
3217
|
-
async getWholeSeriesRegistrationStatus(params) {
|
|
3218
|
-
const sid = requireSiteId();
|
|
3219
|
-
const path = buildPath(WHOLE_SERIES.registrationStatus.path, { siteId: sid });
|
|
3220
|
-
return request(WHOLE_SERIES.registrationStatus, {
|
|
3221
|
-
path,
|
|
3222
|
-
query: { sessionId: params.sessionId },
|
|
3223
|
-
skipDedup: true
|
|
3224
|
-
});
|
|
3225
|
-
},
|
|
3226
3172
|
async getDiscountsAvailable(data) {
|
|
3227
3173
|
const sid = requireSiteId();
|
|
3228
3174
|
const path = buildPath(DISCOUNTS.available.path, { siteId: sid });
|
|
@@ -3393,19 +3339,19 @@ function createBlockApi(config) {
|
|
|
3393
3339
|
async getPortalWholeSeriesRegistrations() {
|
|
3394
3340
|
return (await request(PORTAL.getWholeSeriesRegistrations)).enrollments;
|
|
3395
3341
|
},
|
|
3396
|
-
async getPortalWholeSeriesBookingQuestions(
|
|
3397
|
-
const path = buildPath(PORTAL.getWholeSeriesBookingQuestions.path, {
|
|
3342
|
+
async getPortalWholeSeriesBookingQuestions(registrationId) {
|
|
3343
|
+
const path = buildPath(PORTAL.getWholeSeriesBookingQuestions.path, { registrationId });
|
|
3398
3344
|
return (await request(PORTAL.getWholeSeriesBookingQuestions, { path })).task;
|
|
3399
3345
|
},
|
|
3400
|
-
async updatePortalWholeSeriesBookingQuestions(
|
|
3401
|
-
const path = buildPath(PORTAL.updateWholeSeriesBookingQuestions.path, {
|
|
3346
|
+
async updatePortalWholeSeriesBookingQuestions(registrationId, data) {
|
|
3347
|
+
const path = buildPath(PORTAL.updateWholeSeriesBookingQuestions.path, { registrationId });
|
|
3402
3348
|
return (await request(PORTAL.updateWholeSeriesBookingQuestions, {
|
|
3403
3349
|
path,
|
|
3404
3350
|
body: data
|
|
3405
3351
|
})).task;
|
|
3406
3352
|
},
|
|
3407
|
-
async cancelWholeSeriesRegistration(
|
|
3408
|
-
const path = buildPath(PORTAL.cancelWholeSeriesRegistration.path, {
|
|
3353
|
+
async cancelWholeSeriesRegistration(registrationId, options) {
|
|
3354
|
+
const path = buildPath(PORTAL.cancelWholeSeriesRegistration.path, { registrationId });
|
|
3409
3355
|
return (await request(PORTAL.cancelWholeSeriesRegistration, {
|
|
3410
3356
|
path,
|
|
3411
3357
|
body: options ?? {}
|
|
@@ -3560,7 +3506,7 @@ function CheckIcon({ className, strokeWidth = 2 }) {
|
|
|
3560
3506
|
* Circular icon wrapper for terminal state screens (success, error, waitlist, etc.).
|
|
3561
3507
|
*
|
|
3562
3508
|
* Layout is provided by shared `rb-state-icon` CSS; color variants are
|
|
3563
|
-
* block-scoped
|
|
3509
|
+
* block-scoped by the owning registration surface.
|
|
3564
3510
|
*/
|
|
3565
3511
|
function StateIcon({ variant, children }) {
|
|
3566
3512
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -3714,11 +3660,6 @@ function subtractDaysFromIso(isoString, dayCount) {
|
|
|
3714
3660
|
return addDaysToIso(isoString, -dayCount);
|
|
3715
3661
|
}
|
|
3716
3662
|
//#endregion
|
|
3717
|
-
//#region ../core/src/assert-never.ts
|
|
3718
|
-
function assertNever$3(value, message = "Unexpected variant") {
|
|
3719
|
-
throw new Error(`${message}: ${String(value)}`);
|
|
3720
|
-
}
|
|
3721
|
-
//#endregion
|
|
3722
3663
|
//#region ../core/src/currency-format.ts
|
|
3723
3664
|
const CURRENCY_LOCALE_BY_CODE = {
|
|
3724
3665
|
USD: "en-US",
|
|
@@ -3773,7 +3714,7 @@ function publicEventPricingType(pricing) {
|
|
|
3773
3714
|
case "single_paid":
|
|
3774
3715
|
case "ticket_types":
|
|
3775
3716
|
case "sliding_scale":
|
|
3776
|
-
case "
|
|
3717
|
+
case "whole_series": return isFreePublicEventPriceDisplay(pricing.display) ? "free" : "paid";
|
|
3777
3718
|
case "external": return "external";
|
|
3778
3719
|
}
|
|
3779
3720
|
}
|
|
@@ -3787,7 +3728,7 @@ function publicEventPricingMode(pricing) {
|
|
|
3787
3728
|
case "ticket_types": return "ticket_types";
|
|
3788
3729
|
case "sliding_scale": return "sliding_scale";
|
|
3789
3730
|
case "drop_in":
|
|
3790
|
-
case "
|
|
3731
|
+
case "whole_series":
|
|
3791
3732
|
case "external": return;
|
|
3792
3733
|
}
|
|
3793
3734
|
}
|
|
@@ -3797,7 +3738,7 @@ function publicEventTicketTypes(pricing) {
|
|
|
3797
3738
|
function isFreePublicEventPriceDisplay(display) {
|
|
3798
3739
|
switch (display.kind) {
|
|
3799
3740
|
case "free": return true;
|
|
3800
|
-
case "
|
|
3741
|
+
case "whole_series": return display.display.kind === "free";
|
|
3801
3742
|
case "exact":
|
|
3802
3743
|
case "from":
|
|
3803
3744
|
case "range":
|
|
@@ -5629,6 +5570,22 @@ function formatPrice(cents, currency = "GBP", locale) {
|
|
|
5629
5570
|
}
|
|
5630
5571
|
//#endregion
|
|
5631
5572
|
//#region ../blocks/src/system/runtime/shared/bookingPaymentOptions.ts
|
|
5573
|
+
function resolveBookingPaymentDueNowCents(input) {
|
|
5574
|
+
switch (input.option.kind) {
|
|
5575
|
+
case "upfront": return input.totalCents;
|
|
5576
|
+
case "deferred_manual": return 0;
|
|
5577
|
+
case "instalment_plan": return buildInstalmentSchedulePreview({
|
|
5578
|
+
totalCents: input.totalCents,
|
|
5579
|
+
option: input.option,
|
|
5580
|
+
bookingStartAt: input.bookingStartAt
|
|
5581
|
+
})[0]?.amountCents ?? input.totalCents;
|
|
5582
|
+
case "flexible_balance": return resolveFlexibleBalanceInitialPaymentCents({
|
|
5583
|
+
totalAmountCents: input.totalCents,
|
|
5584
|
+
config: input.option.config
|
|
5585
|
+
});
|
|
5586
|
+
default: return assertNever(input.option);
|
|
5587
|
+
}
|
|
5588
|
+
}
|
|
5632
5589
|
function buildBookingPaymentSelectionViewModel(input) {
|
|
5633
5590
|
const currency = input.priceCurrency ?? "USD";
|
|
5634
5591
|
const totalCents = Math.max(0, input.priceAmount ?? 0);
|
|
@@ -5690,7 +5647,11 @@ function buildBookingPaymentOptionViewModel(input) {
|
|
|
5690
5647
|
option: input.option,
|
|
5691
5648
|
bookingStartAt: input.bookingStartAt
|
|
5692
5649
|
});
|
|
5693
|
-
const dueToday =
|
|
5650
|
+
const dueToday = resolveBookingPaymentDueNowCents({
|
|
5651
|
+
option: input.option,
|
|
5652
|
+
totalCents: input.totalCents,
|
|
5653
|
+
bookingStartAt: input.bookingStartAt
|
|
5654
|
+
});
|
|
5694
5655
|
const futureRows = schedulePreview.slice(1);
|
|
5695
5656
|
const formattedTotal = formatPrice(input.totalCents, input.currency, input.locale);
|
|
5696
5657
|
const formattedDueToday = formatPrice(dueToday, input.currency, input.locale);
|
|
@@ -12412,32 +12373,18 @@ function StepIndicator({ currentStep, totalSteps, stepLabels, classPrefix, emitS
|
|
|
12412
12373
|
}
|
|
12413
12374
|
//#endregion
|
|
12414
12375
|
//#region ../blocks/src/system/runtime/shared/components/DiscountCodeDisclosure.tsx
|
|
12415
|
-
const BLOCK_DISCOUNT_CODE_DISCLOSURE_CLASSES = {
|
|
12416
|
-
"
|
|
12417
|
-
|
|
12418
|
-
|
|
12419
|
-
|
|
12420
|
-
|
|
12421
|
-
|
|
12422
|
-
|
|
12423
|
-
|
|
12424
|
-
|
|
12425
|
-
|
|
12426
|
-
|
|
12427
|
-
},
|
|
12428
|
-
"event-registration": {
|
|
12429
|
-
root: "er-discount",
|
|
12430
|
-
toggle: "er-discount__toggle",
|
|
12431
|
-
form: "er-discount__form",
|
|
12432
|
-
label: "er-discount__label",
|
|
12433
|
-
row: "er-discount__row",
|
|
12434
|
-
input: "er-discount__input",
|
|
12435
|
-
apply: "er-discount__apply",
|
|
12436
|
-
remove: "er-discount__remove",
|
|
12437
|
-
hint: "er-discount__hint",
|
|
12438
|
-
feedback: "er-discount__feedback"
|
|
12439
|
-
}
|
|
12440
|
-
};
|
|
12376
|
+
const BLOCK_DISCOUNT_CODE_DISCLOSURE_CLASSES = { "event-registration": {
|
|
12377
|
+
root: "er-discount",
|
|
12378
|
+
toggle: "er-discount__toggle",
|
|
12379
|
+
form: "er-discount__form",
|
|
12380
|
+
label: "er-discount__label",
|
|
12381
|
+
row: "er-discount__row",
|
|
12382
|
+
input: "er-discount__input",
|
|
12383
|
+
apply: "er-discount__apply",
|
|
12384
|
+
remove: "er-discount__remove",
|
|
12385
|
+
hint: "er-discount__hint",
|
|
12386
|
+
feedback: "er-discount__feedback"
|
|
12387
|
+
} };
|
|
12441
12388
|
const themeFormClasses = {
|
|
12442
12389
|
root: "rb-flex rb-flex-col rb-gap-2 rb-mb-4",
|
|
12443
12390
|
toggle: `${["button", "link"].join("-")} rb-self-start`,
|
|
@@ -14121,17 +14068,19 @@ const blockBookingPaymentTermsSchema = z.object({ allowedOptions: z.array(blockB
|
|
|
14121
14068
|
* and include the block anchor hash for post-redirect scroll targeting.
|
|
14122
14069
|
*
|
|
14123
14070
|
* @param paramName - Query parameter name to add (e.g., 'enrollment', 'registration')
|
|
14124
|
-
* @param anchorId - Block anchor ID for hash fragment
|
|
14071
|
+
* @param anchorId - Block anchor ID for the return URL hash fragment.
|
|
14125
14072
|
* @returns Object with success and cancel URLs
|
|
14126
14073
|
*/
|
|
14127
|
-
function buildCheckoutReturnUrls(paramName, anchorId) {
|
|
14074
|
+
function buildCheckoutReturnUrls(paramName, anchorId, returnParams = {}) {
|
|
14128
14075
|
const currentUrl = new URL(window.location.href);
|
|
14129
14076
|
const hash = `#${anchorId}`;
|
|
14130
14077
|
const successParams = new URLSearchParams(currentUrl.search);
|
|
14131
14078
|
successParams.set(paramName, "success");
|
|
14079
|
+
for (const [name, value] of Object.entries(returnParams)) successParams.set(name, value);
|
|
14132
14080
|
const successUrl = `${currentUrl.origin}${currentUrl.pathname}?${successParams.toString()}${hash}`;
|
|
14133
14081
|
const cancelParams = new URLSearchParams(currentUrl.search);
|
|
14134
14082
|
cancelParams.set(paramName, "cancelled");
|
|
14083
|
+
for (const [name, value] of Object.entries(returnParams)) cancelParams.set(name, value);
|
|
14135
14084
|
return {
|
|
14136
14085
|
successUrl,
|
|
14137
14086
|
cancelUrl: `${currentUrl.origin}${currentUrl.pathname}?${cancelParams.toString()}${hash}`
|
|
@@ -14156,65 +14105,24 @@ function scrollToBlock(anchorId) {
|
|
|
14156
14105
|
//#endregion
|
|
14157
14106
|
//#region ../blocks/src/system/runtime/shared/utils/urlParams.ts
|
|
14158
14107
|
/**
|
|
14159
|
-
*
|
|
14160
|
-
*
|
|
14161
|
-
* Used for flows like magic-link login or Stripe checkout return URLs where
|
|
14162
|
-
* we want to:
|
|
14163
|
-
* - read a query param once
|
|
14164
|
-
* - remove it from the URL (so refresh doesn't re-trigger)
|
|
14165
|
-
* - preserve hash fragments
|
|
14166
|
-
*/
|
|
14167
|
-
/**
|
|
14168
|
-
* Consume a query param from the current URL's search string.
|
|
14108
|
+
* Consume multiple query params from the current URL's search string.
|
|
14169
14109
|
*
|
|
14170
|
-
* Returns
|
|
14171
|
-
*
|
|
14110
|
+
* Returns a record of consumed values (missing params are null) and removes
|
|
14111
|
+
* all provided params from the URL in a single replaceState call.
|
|
14172
14112
|
*/
|
|
14173
|
-
function
|
|
14113
|
+
function consumeSearchParams(paramNames) {
|
|
14174
14114
|
const url = new URL(window.location.href);
|
|
14175
|
-
const
|
|
14176
|
-
|
|
14177
|
-
url.searchParams.
|
|
14178
|
-
|
|
14179
|
-
|
|
14180
|
-
|
|
14181
|
-
|
|
14182
|
-
|
|
14183
|
-
|
|
14184
|
-
|
|
14185
|
-
|
|
14186
|
-
* Validate registration form data.
|
|
14187
|
-
*
|
|
14188
|
-
* Only `name` and `email` are required fields. The `phone` and `notes` fields
|
|
14189
|
-
* are optional and not validated by this function.
|
|
14190
|
-
*
|
|
14191
|
-
* @param data - Form data to validate
|
|
14192
|
-
* @returns Object with field errors (empty if valid)
|
|
14193
|
-
*/
|
|
14194
|
-
function validateFormData$1(data) {
|
|
14195
|
-
const errors = {};
|
|
14196
|
-
if (!data.name.trim()) errors.name = "Name is required";
|
|
14197
|
-
if (!data.email.trim()) errors.email = "Email is required";
|
|
14198
|
-
else if (!EMAIL_REGEX.test(data.email.trim())) errors.email = "Please enter a valid email";
|
|
14199
|
-
return errors;
|
|
14200
|
-
}
|
|
14201
|
-
//#endregion
|
|
14202
|
-
//#region ../blocks/src/system/runtime/shared/utils/wizardSteps.ts
|
|
14203
|
-
/**
|
|
14204
|
-
* Shared Wizard Step Utilities
|
|
14205
|
-
*
|
|
14206
|
-
* Helpers for wizard step navigation in registration blocks.
|
|
14207
|
-
*/
|
|
14208
|
-
/**
|
|
14209
|
-
* Get the 1-based step number for a step in the wizard.
|
|
14210
|
-
*
|
|
14211
|
-
* @param step - The step to find
|
|
14212
|
-
* @param wizardSteps - Array of wizard steps
|
|
14213
|
-
* @returns 1-based step number, or 1 if step not found
|
|
14214
|
-
*/
|
|
14215
|
-
function getStepNumber(step, wizardSteps) {
|
|
14216
|
-
const index = wizardSteps.indexOf(step);
|
|
14217
|
-
return index >= 0 ? index + 1 : 1;
|
|
14115
|
+
const values = Object.fromEntries(paramNames.map((name) => [name, url.searchParams.get(name)]));
|
|
14116
|
+
let changed = false;
|
|
14117
|
+
for (const name of paramNames) if (url.searchParams.has(name)) {
|
|
14118
|
+
url.searchParams.delete(name);
|
|
14119
|
+
changed = true;
|
|
14120
|
+
}
|
|
14121
|
+
if (changed) {
|
|
14122
|
+
const newUrl = url.pathname + (url.search ? url.search : "") + url.hash;
|
|
14123
|
+
window.history.replaceState({}, "", newUrl);
|
|
14124
|
+
}
|
|
14125
|
+
return values;
|
|
14218
14126
|
}
|
|
14219
14127
|
//#endregion
|
|
14220
14128
|
//#region ../blocks/src/system/runtime/nodes/booking-form.client.tsx
|
|
@@ -14414,7 +14322,7 @@ function resolveRuntimeEventDestination(event) {
|
|
|
14414
14322
|
}
|
|
14415
14323
|
//#endregion
|
|
14416
14324
|
//#region ../blocks/src/system/runtime/nodes/events/shared/pricing.ts
|
|
14417
|
-
const DEFAULT_EVENT_CURRENCY
|
|
14325
|
+
const DEFAULT_EVENT_CURRENCY = "USD";
|
|
14418
14326
|
function resolveRuntimeEventPricing(event) {
|
|
14419
14327
|
if (isPublicEventPricing(event.pricing)) return event.pricing;
|
|
14420
14328
|
if (resolveRuntimeEventDestination(event).kind === "external") return {
|
|
@@ -14461,21 +14369,21 @@ function resolveRuntimeEventPricing(event) {
|
|
|
14461
14369
|
};
|
|
14462
14370
|
}
|
|
14463
14371
|
function readCurrency(value) {
|
|
14464
|
-
return typeof value === "string" && value.trim().length > 0 ? value : DEFAULT_EVENT_CURRENCY
|
|
14372
|
+
return typeof value === "string" && value.trim().length > 0 ? value : DEFAULT_EVENT_CURRENCY;
|
|
14465
14373
|
}
|
|
14466
14374
|
function isRecord$1(value) {
|
|
14467
14375
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
14468
14376
|
}
|
|
14469
14377
|
function isPublicEventPricing(value) {
|
|
14470
14378
|
if (!isRecord$1(value) || typeof value.kind !== "string") return false;
|
|
14471
|
-
return value.kind === "drop_in" || value.kind === "free_registration" || value.kind === "single_paid" || value.kind === "sliding_scale" || value.kind === "ticket_types" || value.kind === "
|
|
14379
|
+
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";
|
|
14472
14380
|
}
|
|
14473
14381
|
function isPublicEventTicketType(value) {
|
|
14474
14382
|
return isRecord$1(value) && typeof value.id === "string";
|
|
14475
14383
|
}
|
|
14476
14384
|
function readTicketTypePriceDisplay(value, currency) {
|
|
14477
14385
|
const display = readLegacyPriceDisplay(value, currency);
|
|
14478
|
-
return display.kind === "
|
|
14386
|
+
return display.kind === "whole_series" || display.kind === "external" ? {
|
|
14479
14387
|
kind: "unavailable",
|
|
14480
14388
|
currency
|
|
14481
14389
|
} : display;
|
|
@@ -14533,11 +14441,11 @@ function readLegacyPriceDisplay(value, currency) {
|
|
|
14533
14441
|
kind: "unavailable",
|
|
14534
14442
|
currency: displayCurrency
|
|
14535
14443
|
};
|
|
14536
|
-
case "
|
|
14537
|
-
kind: "
|
|
14444
|
+
case "whole_series": return isRecord$1(value.display) ? {
|
|
14445
|
+
kind: "whole_series",
|
|
14538
14446
|
display: readCoursePriceDisplay(value.display, displayCurrency)
|
|
14539
14447
|
} : {
|
|
14540
|
-
kind: "
|
|
14448
|
+
kind: "whole_series",
|
|
14541
14449
|
display: {
|
|
14542
14450
|
kind: "unavailable",
|
|
14543
14451
|
currency: displayCurrency
|
|
@@ -14599,50 +14507,107 @@ function validateFormData(formData, requiresConsent = false) {
|
|
|
14599
14507
|
if (requiresConsent && formData.consentAccepted !== true) errors.consentAccepted = "Please read and accept the agreement before continuing.";
|
|
14600
14508
|
return errors;
|
|
14601
14509
|
}
|
|
14602
|
-
|
|
14603
|
-
|
|
14604
|
-
|
|
14605
|
-
|
|
14606
|
-
|
|
14607
|
-
|
|
14608
|
-
|
|
14609
|
-
const
|
|
14610
|
-
const eligiblePasses =
|
|
14611
|
-
id:
|
|
14612
|
-
passName:
|
|
14613
|
-
creditsRemaining:
|
|
14510
|
+
//#endregion
|
|
14511
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
|
|
14512
|
+
function getPortalSubjectEmail(profile) {
|
|
14513
|
+
return profile?.email ?? null;
|
|
14514
|
+
}
|
|
14515
|
+
function transformRegistrationOptionsResponse(response) {
|
|
14516
|
+
const canJoinWaitlist = response.availability.kind === "waitlist";
|
|
14517
|
+
const isFull = response.availability.remainingPlaces === 0 || response.availability.kind === "unavailable" && response.availability.reason === "full";
|
|
14518
|
+
const eligiblePasses = response.entitlements.passes.map((pass) => ({
|
|
14519
|
+
id: pass.customerPassId,
|
|
14520
|
+
passName: pass.passName,
|
|
14521
|
+
creditsRemaining: pass.creditsRemaining
|
|
14614
14522
|
}));
|
|
14615
|
-
const eligibleMemberships =
|
|
14616
|
-
id:
|
|
14617
|
-
membershipName:
|
|
14618
|
-
}
|
|
14619
|
-
const
|
|
14620
|
-
const
|
|
14621
|
-
const
|
|
14622
|
-
const
|
|
14523
|
+
const eligibleMemberships = response.entitlements.memberships.map((membership) => ({
|
|
14524
|
+
id: membership.customerMembershipId,
|
|
14525
|
+
membershipName: membership.membershipName
|
|
14526
|
+
}));
|
|
14527
|
+
const eventAcceptsPasses = response.entitlements.requiresLoginForPasses || eligiblePasses.length > 0 || response.entitlements.availableForPurchase.passes.length > 0;
|
|
14528
|
+
const eventAcceptsMemberships = response.entitlements.requiresLoginForMemberships || eligibleMemberships.length > 0 || response.entitlements.availableForPurchase.memberships.length > 0;
|
|
14529
|
+
const monetaryPaymentAvailable = hasMonetaryPaymentOption(response);
|
|
14530
|
+
const registrationAvailable = response.availability.kind === "available" || response.availability.kind === "waitlist";
|
|
14623
14531
|
return {
|
|
14624
|
-
|
|
14625
|
-
|
|
14626
|
-
|
|
14627
|
-
|
|
14628
|
-
|
|
14629
|
-
|
|
14630
|
-
|
|
14631
|
-
|
|
14632
|
-
|
|
14633
|
-
|
|
14634
|
-
|
|
14635
|
-
|
|
14636
|
-
|
|
14637
|
-
|
|
14532
|
+
availability: response.availability,
|
|
14533
|
+
registration: response.registration,
|
|
14534
|
+
paymentOptions: response.paymentOptions,
|
|
14535
|
+
isFree: response.paymentOptions.some((option) => option.kind === "free"),
|
|
14536
|
+
credit: response.customer.credit ? {
|
|
14537
|
+
summary: {
|
|
14538
|
+
currency: response.customer.credit.currency,
|
|
14539
|
+
balanceCents: response.customer.credit.availableCents,
|
|
14540
|
+
reservedCents: 0,
|
|
14541
|
+
availableCents: response.customer.credit.availableCents
|
|
14542
|
+
},
|
|
14543
|
+
transactions: []
|
|
14544
|
+
} : null,
|
|
14545
|
+
eligible: response.registration.kind === "none" && registrationAvailable,
|
|
14546
|
+
requiresPayment: monetaryPaymentAvailable,
|
|
14547
|
+
pricingMode: response.pricing.mode,
|
|
14548
|
+
paymentTerms: response.pricing.paymentTerms,
|
|
14549
|
+
selectedTicketTypeId: response.pricing.lines.length === 1 ? response.pricing.lines[0]?.pricingOptionId ?? null : null,
|
|
14550
|
+
ticketLines: response.pricing.lines.map((line) => ({
|
|
14551
|
+
ticketTypeId: line.pricingOptionId,
|
|
14552
|
+
label: line.label,
|
|
14553
|
+
description: line.description,
|
|
14554
|
+
quantity: line.quantity,
|
|
14555
|
+
unitPriceCents: line.unitPriceCents,
|
|
14556
|
+
subtotalCents: line.subtotalCents,
|
|
14557
|
+
currency: response.pricing.currency
|
|
14558
|
+
})),
|
|
14559
|
+
ticketTypes: projectRegistrationPricingOptions(response.pricing.options),
|
|
14560
|
+
isFull,
|
|
14561
|
+
waitlistEnabled: response.availability.waitlistEnabled,
|
|
14562
|
+
canJoinWaitlist,
|
|
14563
|
+
price: response.pricing.subtotalCents,
|
|
14564
|
+
currency: response.pricing.currency,
|
|
14565
|
+
requiresAuthForPasses: response.entitlements.requiresLoginForPasses,
|
|
14566
|
+
requiresAuthForMemberships: response.entitlements.requiresLoginForMemberships,
|
|
14638
14567
|
eligiblePasses,
|
|
14639
14568
|
eligibleMemberships,
|
|
14640
|
-
canPayDirectly,
|
|
14641
|
-
eventAcceptsPasses
|
|
14642
|
-
eventAcceptsMemberships
|
|
14643
|
-
availablePasses:
|
|
14644
|
-
availableMemberships:
|
|
14645
|
-
};
|
|
14569
|
+
canPayDirectly: monetaryPaymentAvailable,
|
|
14570
|
+
eventAcceptsPasses,
|
|
14571
|
+
eventAcceptsMemberships,
|
|
14572
|
+
availablePasses: [...response.entitlements.availableForPurchase.passes],
|
|
14573
|
+
availableMemberships: [...response.entitlements.availableForPurchase.memberships]
|
|
14574
|
+
};
|
|
14575
|
+
}
|
|
14576
|
+
function hasMonetaryPaymentOption(response) {
|
|
14577
|
+
return response.paymentOptions.some((option) => option.kind === "payInFull" || option.kind === "deferredManual" || option.kind === "instalmentPlan" || option.kind === "flexibleBalance");
|
|
14578
|
+
}
|
|
14579
|
+
function projectRegistrationPricingOptions(options) {
|
|
14580
|
+
return options.map((option) => ({
|
|
14581
|
+
id: option.pricingOptionId,
|
|
14582
|
+
name: option.label,
|
|
14583
|
+
description: option.description,
|
|
14584
|
+
priceAmount: option.unitPriceCents,
|
|
14585
|
+
isActive: option.availability.kind === "available" || option.availability.reason !== "inactive",
|
|
14586
|
+
sortOrder: option.sortOrder,
|
|
14587
|
+
capacityMode: option.availability.remainingPlaces === null ? "unlimited" : "limited",
|
|
14588
|
+
capacityLimit: option.capacityLimit,
|
|
14589
|
+
attendanceScope: option.attendanceScope,
|
|
14590
|
+
saleStartsAt: option.saleStartsAt,
|
|
14591
|
+
saleEndsAt: option.saleEndsAt,
|
|
14592
|
+
availability: option.availability.kind === "available" ? {
|
|
14593
|
+
kind: "available",
|
|
14594
|
+
remainingCapacity: option.availability.remainingPlaces
|
|
14595
|
+
} : {
|
|
14596
|
+
kind: "unavailable",
|
|
14597
|
+
reason: toLegacyAvailabilityReason(option.availability.reason),
|
|
14598
|
+
remainingCapacity: option.availability.remainingPlaces
|
|
14599
|
+
}
|
|
14600
|
+
}));
|
|
14601
|
+
}
|
|
14602
|
+
function toLegacyAvailabilityReason(reason) {
|
|
14603
|
+
switch (reason) {
|
|
14604
|
+
case "inactive": return "inactive";
|
|
14605
|
+
case "notOnSaleYet": return "not_on_sale_yet";
|
|
14606
|
+
case "saleEnded": return "sale_ended";
|
|
14607
|
+
case "soldOut":
|
|
14608
|
+
case "attendanceModeUnavailable": return "sold_out";
|
|
14609
|
+
case "overallCapacityUnavailable": return "event_sold_out";
|
|
14610
|
+
}
|
|
14646
14611
|
}
|
|
14647
14612
|
function getVisibleTicketTypes(input) {
|
|
14648
14613
|
const eligibilityTicketTypes = input.eligibility?.ticketTypes;
|
|
@@ -14755,16 +14720,8 @@ function existingRegistrationLookupReducer(state, action) {
|
|
|
14755
14720
|
* Custom hooks for portal authentication and eligibility checking.
|
|
14756
14721
|
* Extracted from the main EventRegistrationClient for better separation of concerns.
|
|
14757
14722
|
*/
|
|
14758
|
-
function scopePortalCreditStateToSubject(state, subjectEmail) {
|
|
14759
|
-
if (!subjectEmail) return { kind: "not_authenticated" };
|
|
14760
|
-
if (state.kind === "not_authenticated") return state;
|
|
14761
|
-
const normalizedSubject = subjectEmail.trim().toLowerCase();
|
|
14762
|
-
return state.subjectEmail === normalizedSubject ? state : {
|
|
14763
|
-
kind: "loading",
|
|
14764
|
-
subjectEmail: normalizedSubject
|
|
14765
|
-
};
|
|
14766
|
-
}
|
|
14767
14723
|
const eventRegistrationHooksDeps = { useBlockApi };
|
|
14724
|
+
const REGISTRATION_OPTIONS_DEBOUNCE_MS = 150;
|
|
14768
14725
|
/**
|
|
14769
14726
|
* Hook for managing portal authentication state.
|
|
14770
14727
|
*
|
|
@@ -14778,54 +14735,29 @@ function usePortalAuthWithDeps(deps) {
|
|
|
14778
14735
|
const api = deps.useBlockApi();
|
|
14779
14736
|
const [authState, setAuthState] = useState("checking");
|
|
14780
14737
|
const [profile, setProfile] = useState(null);
|
|
14781
|
-
const [creditState, setCreditState] = useState({ kind: "not_authenticated" });
|
|
14782
14738
|
useEffect(() => {
|
|
14783
14739
|
let cancelled = false;
|
|
14784
14740
|
async function checkPortalAuth() {
|
|
14785
14741
|
if ((api.config.authOverrides?.portal ?? api.config.auth).type !== "bearer") {
|
|
14786
14742
|
setAuthState("unauthenticated");
|
|
14787
14743
|
setProfile(null);
|
|
14788
|
-
setCreditState({ kind: "not_authenticated" });
|
|
14789
14744
|
return;
|
|
14790
14745
|
}
|
|
14791
14746
|
setAuthState("checking");
|
|
14792
14747
|
setProfile(null);
|
|
14793
|
-
setCreditState({ kind: "not_authenticated" });
|
|
14794
14748
|
try {
|
|
14795
14749
|
const me = await api.getPortalProfile();
|
|
14796
14750
|
if (cancelled) return;
|
|
14797
|
-
|
|
14751
|
+
setProfile({
|
|
14798
14752
|
email: me.profile.email,
|
|
14799
14753
|
name: me.profile.name,
|
|
14800
14754
|
phone: me.profile.phone || ""
|
|
14801
|
-
};
|
|
14802
|
-
const subjectEmail = nextProfile.email.trim().toLowerCase();
|
|
14803
|
-
setProfile(nextProfile);
|
|
14804
|
-
setCreditState({
|
|
14805
|
-
kind: "loading",
|
|
14806
|
-
subjectEmail
|
|
14807
14755
|
});
|
|
14808
14756
|
setAuthState("authenticated");
|
|
14809
|
-
try {
|
|
14810
|
-
const credit = await api.getPortalCredit();
|
|
14811
|
-
if (cancelled) return;
|
|
14812
|
-
setCreditState({
|
|
14813
|
-
kind: "loaded",
|
|
14814
|
-
subjectEmail,
|
|
14815
|
-
credit
|
|
14816
|
-
});
|
|
14817
|
-
} catch {
|
|
14818
|
-
if (cancelled) return;
|
|
14819
|
-
setCreditState({
|
|
14820
|
-
kind: "unavailable",
|
|
14821
|
-
subjectEmail
|
|
14822
|
-
});
|
|
14823
|
-
}
|
|
14824
14757
|
} catch {
|
|
14825
14758
|
if (cancelled) return;
|
|
14826
14759
|
setAuthState("unauthenticated");
|
|
14827
14760
|
setProfile(null);
|
|
14828
|
-
setCreditState({ kind: "not_authenticated" });
|
|
14829
14761
|
}
|
|
14830
14762
|
}
|
|
14831
14763
|
checkPortalAuth();
|
|
@@ -14845,10 +14777,20 @@ function usePortalAuthWithDeps(deps) {
|
|
|
14845
14777
|
isAuthenticated: authState === "authenticated",
|
|
14846
14778
|
isChecking: authState === "checking",
|
|
14847
14779
|
profile,
|
|
14848
|
-
creditState: scopePortalCreditStateToSubject(creditState, authState === "authenticated" ? profile?.email ?? null : null),
|
|
14849
14780
|
logout
|
|
14850
14781
|
};
|
|
14851
14782
|
}
|
|
14783
|
+
function toRegistrationOptionsSubject(subject, attendanceMode) {
|
|
14784
|
+
return subject.kind === "occurrence" ? {
|
|
14785
|
+
kind: "occurrence",
|
|
14786
|
+
occurrenceId: subject.occurrenceId,
|
|
14787
|
+
attendanceMode: attendanceMode ?? void 0
|
|
14788
|
+
} : {
|
|
14789
|
+
kind: "wholeSeries",
|
|
14790
|
+
eventSeriesId: subject.eventSeriesId,
|
|
14791
|
+
attendanceMode: attendanceMode ?? void 0
|
|
14792
|
+
};
|
|
14793
|
+
}
|
|
14852
14794
|
function useEligibility(params) {
|
|
14853
14795
|
return useEligibilityWithDeps(params, eventRegistrationHooksDeps);
|
|
14854
14796
|
}
|
|
@@ -14866,7 +14808,7 @@ function useEligibilityWithDeps(params, deps) {
|
|
|
14866
14808
|
return;
|
|
14867
14809
|
}
|
|
14868
14810
|
const ticketSelections = JSON.parse(ticketSelectionsKey);
|
|
14869
|
-
if (!params.
|
|
14811
|
+
if (!params.subject || ticketSelections.length === 0) {
|
|
14870
14812
|
requestIdRef.current += 1;
|
|
14871
14813
|
dispatch({ type: "reset" });
|
|
14872
14814
|
return;
|
|
@@ -14875,17 +14817,19 @@ function useEligibilityWithDeps(params, deps) {
|
|
|
14875
14817
|
requestIdRef.current = requestId;
|
|
14876
14818
|
dispatch({ type: "loading-started" });
|
|
14877
14819
|
try {
|
|
14878
|
-
const
|
|
14879
|
-
|
|
14880
|
-
|
|
14881
|
-
ticketSelections
|
|
14882
|
-
|
|
14883
|
-
|
|
14820
|
+
const subject = toRegistrationOptionsSubject(params.subject, params.attendanceMode);
|
|
14821
|
+
const result = await api.getRegistrationOptions({
|
|
14822
|
+
subject,
|
|
14823
|
+
selections: ticketSelections.map((selection) => ({
|
|
14824
|
+
pricingOptionId: selection.ticketTypeId,
|
|
14825
|
+
quantity: selection.quantity
|
|
14826
|
+
})),
|
|
14827
|
+
selectedSlidingAmount: params.selectedSlidingAmount ?? void 0
|
|
14884
14828
|
});
|
|
14885
14829
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
14886
14830
|
dispatch({
|
|
14887
14831
|
type: "resolved",
|
|
14888
|
-
eligibility:
|
|
14832
|
+
eligibility: transformRegistrationOptionsResponse(result)
|
|
14889
14833
|
});
|
|
14890
14834
|
} catch (err) {
|
|
14891
14835
|
if (cancelled || requestIdRef.current !== requestId) return;
|
|
@@ -14895,24 +14839,44 @@ function useEligibilityWithDeps(params, deps) {
|
|
|
14895
14839
|
});
|
|
14896
14840
|
}
|
|
14897
14841
|
}
|
|
14898
|
-
fetchEligibility();
|
|
14842
|
+
const timeoutId = window.setTimeout(() => void fetchEligibility(), REGISTRATION_OPTIONS_DEBOUNCE_MS);
|
|
14899
14843
|
return () => {
|
|
14900
14844
|
cancelled = true;
|
|
14845
|
+
window.clearTimeout(timeoutId);
|
|
14901
14846
|
};
|
|
14902
14847
|
}, [
|
|
14903
14848
|
api,
|
|
14904
14849
|
params.enabled,
|
|
14905
|
-
params.
|
|
14850
|
+
params.subject?.kind,
|
|
14851
|
+
params.subject?.kind === "occurrence" ? params.subject.occurrenceId : params.subject?.eventSeriesId,
|
|
14906
14852
|
params.attendanceMode,
|
|
14907
14853
|
ticketSelectionsKey,
|
|
14908
|
-
params.selectedSlidingAmount
|
|
14909
|
-
params.email
|
|
14854
|
+
params.selectedSlidingAmount
|
|
14910
14855
|
]);
|
|
14856
|
+
const creditState = registrationOptionsCreditState(state, params.subjectEmail);
|
|
14911
14857
|
return {
|
|
14912
14858
|
state,
|
|
14913
14859
|
eligibility: state.eligibility,
|
|
14914
14860
|
isLoading: state.tag === "loading",
|
|
14915
|
-
error: state.error
|
|
14861
|
+
error: state.error,
|
|
14862
|
+
creditState
|
|
14863
|
+
};
|
|
14864
|
+
}
|
|
14865
|
+
function registrationOptionsCreditState(state, subjectEmail) {
|
|
14866
|
+
if (!subjectEmail) return { kind: "not_authenticated" };
|
|
14867
|
+
const normalizedEmail = subjectEmail.trim().toLowerCase();
|
|
14868
|
+
if (state.tag === "idle" || state.tag === "loading") return {
|
|
14869
|
+
kind: "loading",
|
|
14870
|
+
subjectEmail: normalizedEmail
|
|
14871
|
+
};
|
|
14872
|
+
if (state.tag === "failed") return {
|
|
14873
|
+
kind: "unavailable",
|
|
14874
|
+
subjectEmail: normalizedEmail
|
|
14875
|
+
};
|
|
14876
|
+
return {
|
|
14877
|
+
kind: "loaded",
|
|
14878
|
+
subjectEmail: normalizedEmail,
|
|
14879
|
+
credit: state.eligibility.credit ?? null
|
|
14916
14880
|
};
|
|
14917
14881
|
}
|
|
14918
14882
|
function useExistingEventRegistration({ isAuthenticated, occurrenceId }) {
|
|
@@ -15086,9 +15050,6 @@ function getWaitlistClaimTokenSnapshot() {
|
|
|
15086
15050
|
function useWaitlistClaim() {
|
|
15087
15051
|
return useWaitlistClaimWithDeps(useWaitlistClaimDeps);
|
|
15088
15052
|
}
|
|
15089
|
-
function useWaitlistClaimForToken(token) {
|
|
15090
|
-
return useResolvedWaitlistClaim(useWaitlistClaimDeps, token);
|
|
15091
|
-
}
|
|
15092
15053
|
function useWaitlistClaimWithDeps(deps) {
|
|
15093
15054
|
return useResolvedWaitlistClaim(deps, useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimTokenSnapshot, () => null));
|
|
15094
15055
|
}
|
|
@@ -15177,7 +15138,7 @@ function usePaymentVerificationWithDeps(config, deps) {
|
|
|
15177
15138
|
const polling = usePolling(useMemo(() => {
|
|
15178
15139
|
if (!config) return null;
|
|
15179
15140
|
return {
|
|
15180
|
-
pollFn: () => api.getEventRegistrationStatus(
|
|
15141
|
+
pollFn: () => api.getEventRegistrationStatus(config.reference),
|
|
15181
15142
|
isComplete: (result) => result.paymentStatus === "completed" || result.paymentStatus === "not_required",
|
|
15182
15143
|
isFailed: (result) => result.paymentStatus === "failed" || result.paymentStatus === "refunded",
|
|
15183
15144
|
maxAttempts: config.maxAttempts,
|
|
@@ -15201,6 +15162,7 @@ function usePaymentVerificationWithDeps(config, deps) {
|
|
|
15201
15162
|
//#endregion
|
|
15202
15163
|
//#region ../blocks/src/system/runtime/nodes/event-registration/constants.ts
|
|
15203
15164
|
const EVENT_REGISTRATION_ANCHOR_ID = "event-registration";
|
|
15165
|
+
const EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM = "registration_attempt";
|
|
15204
15166
|
//#endregion
|
|
15205
15167
|
//#region ../blocks/src/system/runtime/nodes/event-registration/sessionStorage.ts
|
|
15206
15168
|
const STORAGE_PREFIX = "riverbank:event-registration:";
|
|
@@ -15208,8 +15170,8 @@ const STALE_THRESHOLD_MS = 1440 * 60 * 1e3;
|
|
|
15208
15170
|
/**
|
|
15209
15171
|
* Build the sessionStorage key for a specific registration.
|
|
15210
15172
|
*/
|
|
15211
|
-
function getStorageKey(siteId,
|
|
15212
|
-
return `${STORAGE_PREFIX}${siteId}:${
|
|
15173
|
+
function getStorageKey(siteId, checkoutAttemptId) {
|
|
15174
|
+
return `${STORAGE_PREFIX}${siteId}:${checkoutAttemptId}`;
|
|
15213
15175
|
}
|
|
15214
15176
|
/**
|
|
15215
15177
|
* Check if sessionStorage is available.
|
|
@@ -15229,16 +15191,16 @@ function isStorageAvailable() {
|
|
|
15229
15191
|
* Save pending registration data before Stripe redirect.
|
|
15230
15192
|
*
|
|
15231
15193
|
* @param siteId - Site ID
|
|
15232
|
-
* @param
|
|
15194
|
+
* @param checkoutAttemptId - Correlation ID included in the checkout return URL
|
|
15233
15195
|
* @param data - Registration data to save (excluding version and timestamp)
|
|
15234
15196
|
*/
|
|
15235
|
-
function savePendingRegistration(siteId,
|
|
15197
|
+
function savePendingRegistration(siteId, checkoutAttemptId, data) {
|
|
15236
15198
|
if (!isStorageAvailable()) {
|
|
15237
15199
|
console.warn("[sessionStorage] Storage not available, skipping save");
|
|
15238
15200
|
return;
|
|
15239
15201
|
}
|
|
15240
15202
|
try {
|
|
15241
|
-
const key = getStorageKey(siteId,
|
|
15203
|
+
const key = getStorageKey(siteId, checkoutAttemptId);
|
|
15242
15204
|
const ticketSelections = normalizeTicketSelectionLines(data.ticketSelections);
|
|
15243
15205
|
if (ticketSelections.length === 0) {
|
|
15244
15206
|
console.warn("[sessionStorage] No ticket selections to save, skipping registration state");
|
|
@@ -15247,7 +15209,7 @@ function savePendingRegistration(siteId, occurrenceId, data) {
|
|
|
15247
15209
|
const entry = {
|
|
15248
15210
|
...data,
|
|
15249
15211
|
ticketSelections,
|
|
15250
|
-
version:
|
|
15212
|
+
version: 5,
|
|
15251
15213
|
timestamp: Date.now()
|
|
15252
15214
|
};
|
|
15253
15215
|
sessionStorage.setItem(key, JSON.stringify(entry));
|
|
@@ -15259,35 +15221,21 @@ function savePendingRegistration(siteId, occurrenceId, data) {
|
|
|
15259
15221
|
* Get pending registration data after returning from Stripe.
|
|
15260
15222
|
*
|
|
15261
15223
|
* Returns null if:
|
|
15262
|
-
* - No entry exists for this
|
|
15224
|
+
* - No entry exists for this checkout attempt
|
|
15263
15225
|
* - Entry is stale (> 24 hours old)
|
|
15264
15226
|
* - Entry is corrupt or wrong version
|
|
15265
15227
|
* - Storage is unavailable
|
|
15266
15228
|
*
|
|
15267
15229
|
* @param siteId - Site ID
|
|
15268
|
-
* @param
|
|
15230
|
+
* @param checkoutAttemptId - Correlation ID returned from checkout.
|
|
15269
15231
|
* @returns Pending registration data or null
|
|
15270
15232
|
*/
|
|
15271
|
-
function getPendingRegistration(siteId,
|
|
15233
|
+
function getPendingRegistration(siteId, checkoutAttemptId) {
|
|
15272
15234
|
if (!isStorageAvailable()) return null;
|
|
15273
15235
|
try {
|
|
15274
|
-
|
|
15275
|
-
|
|
15276
|
-
|
|
15277
|
-
if (stored) return parseAndValidateEntry(stored, key);
|
|
15278
|
-
return null;
|
|
15279
|
-
}
|
|
15280
|
-
const sitePrefix = `${STORAGE_PREFIX}${siteId}:`;
|
|
15281
|
-
for (let i = 0; i < sessionStorage.length; i++) {
|
|
15282
|
-
const key = sessionStorage.key(i);
|
|
15283
|
-
if (key?.startsWith(sitePrefix)) {
|
|
15284
|
-
const stored = sessionStorage.getItem(key);
|
|
15285
|
-
if (stored) {
|
|
15286
|
-
const entry = parseAndValidateEntry(stored, key);
|
|
15287
|
-
if (entry) return entry;
|
|
15288
|
-
}
|
|
15289
|
-
}
|
|
15290
|
-
}
|
|
15236
|
+
const key = getStorageKey(siteId, checkoutAttemptId);
|
|
15237
|
+
const stored = sessionStorage.getItem(key);
|
|
15238
|
+
if (stored) return parseAndValidateEntry(stored, key);
|
|
15291
15239
|
return null;
|
|
15292
15240
|
} catch (error) {
|
|
15293
15241
|
console.warn("[sessionStorage] Failed to read registration:", error);
|
|
@@ -15304,12 +15252,13 @@ function parseAndValidateEntry(stored, key) {
|
|
|
15304
15252
|
sessionStorage.removeItem(key);
|
|
15305
15253
|
return null;
|
|
15306
15254
|
}
|
|
15307
|
-
|
|
15255
|
+
const version = raw.version;
|
|
15256
|
+
if (version !== 4 && version !== 5) {
|
|
15308
15257
|
console.warn("[sessionStorage] Outdated version, ignoring entry");
|
|
15309
15258
|
sessionStorage.removeItem(key);
|
|
15310
15259
|
return null;
|
|
15311
15260
|
}
|
|
15312
|
-
const entry = raw;
|
|
15261
|
+
const entry = normalizeStoredRegistration(raw);
|
|
15313
15262
|
const timestamp = typeof entry.timestamp === "number" ? entry.timestamp : NaN;
|
|
15314
15263
|
if (!Number.isFinite(timestamp)) {
|
|
15315
15264
|
sessionStorage.removeItem(key);
|
|
@@ -15335,16 +15284,28 @@ function parseAndValidateEntry(stored, key) {
|
|
|
15335
15284
|
return null;
|
|
15336
15285
|
}
|
|
15337
15286
|
}
|
|
15287
|
+
function normalizeStoredRegistration(entry) {
|
|
15288
|
+
if (entry.version === 5) return entry;
|
|
15289
|
+
const { attendeeId, ...stored } = entry;
|
|
15290
|
+
return {
|
|
15291
|
+
...stored,
|
|
15292
|
+
version: 5,
|
|
15293
|
+
reference: {
|
|
15294
|
+
scope: "occurrence",
|
|
15295
|
+
attendeeId
|
|
15296
|
+
}
|
|
15297
|
+
};
|
|
15298
|
+
}
|
|
15338
15299
|
/**
|
|
15339
15300
|
* Clear pending registration data after successful verification.
|
|
15340
15301
|
*
|
|
15341
15302
|
* @param siteId - Site ID
|
|
15342
|
-
* @param
|
|
15303
|
+
* @param checkoutAttemptId - Checkout return correlation ID
|
|
15343
15304
|
*/
|
|
15344
|
-
function clearPendingRegistration(siteId,
|
|
15305
|
+
function clearPendingRegistration(siteId, checkoutAttemptId) {
|
|
15345
15306
|
if (!isStorageAvailable()) return;
|
|
15346
15307
|
try {
|
|
15347
|
-
const key = getStorageKey(siteId,
|
|
15308
|
+
const key = getStorageKey(siteId, checkoutAttemptId);
|
|
15348
15309
|
sessionStorage.removeItem(key);
|
|
15349
15310
|
} catch {}
|
|
15350
15311
|
}
|
|
@@ -15380,7 +15341,7 @@ function cleanupStaleRegistrations() {
|
|
|
15380
15341
|
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.ts
|
|
15381
15342
|
const eventRegistrationStripeReturnDeps = {
|
|
15382
15343
|
usePaymentVerification,
|
|
15383
|
-
|
|
15344
|
+
consumeReturnParams: () => consumeSearchParams(["registration", EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]),
|
|
15384
15345
|
scrollToBlock,
|
|
15385
15346
|
cleanupStaleRegistrations,
|
|
15386
15347
|
clearPendingRegistration,
|
|
@@ -15390,37 +15351,43 @@ function useEventRegistrationStripeReturn(options) {
|
|
|
15390
15351
|
return useEventRegistrationStripeReturnWithDeps(options, eventRegistrationStripeReturnDeps);
|
|
15391
15352
|
}
|
|
15392
15353
|
function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
15393
|
-
const { api, events,
|
|
15394
|
-
const
|
|
15354
|
+
const { api, events, pendingRegistrationReference, setErrorMessage, setFormData, setPaymentSelection, setPendingRegistrationReference, setRegistrationResult, setSelectedEvent, setSelectedAttendanceMode, setTicketSelections, setStep, setTicketsCount, step } = options;
|
|
15355
|
+
const checkoutAttemptIdRef = useRef(null);
|
|
15356
|
+
const verificationConfig = useMemo(() => step === "verifying-payment" && pendingRegistrationReference ? { reference: pendingRegistrationReference } : null, [step, pendingRegistrationReference]);
|
|
15395
15357
|
const verification = deps.usePaymentVerification(verificationConfig);
|
|
15396
15358
|
useEffect(() => {
|
|
15397
15359
|
deps.cleanupStaleRegistrations();
|
|
15398
|
-
const
|
|
15360
|
+
const returnParams = deps.consumeReturnParams();
|
|
15361
|
+
const registrationStatus = returnParams.registration;
|
|
15399
15362
|
if (registrationStatus !== "cancelled" && registrationStatus !== "success") return;
|
|
15400
15363
|
deps.scrollToBlock(EVENT_REGISTRATION_ANCHOR_ID);
|
|
15401
15364
|
const siteId = api.config.siteId;
|
|
15402
15365
|
if (!siteId) return;
|
|
15403
|
-
const
|
|
15366
|
+
const checkoutAttemptId = returnParams[EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM];
|
|
15367
|
+
if (!checkoutAttemptId) return;
|
|
15368
|
+
const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
|
|
15404
15369
|
if (!pending) return;
|
|
15370
|
+
checkoutAttemptIdRef.current = checkoutAttemptId;
|
|
15405
15371
|
setFormData(pending.formData);
|
|
15406
15372
|
setTicketSelections(pending.ticketSelections);
|
|
15407
15373
|
setTicketsCount(getTicketSelectionTotal(pending.ticketSelections));
|
|
15408
15374
|
if (pending.selectedEventId) {
|
|
15409
|
-
const event = events.find((e) => e.
|
|
15375
|
+
const event = events.find((e) => e.selectionId === pending.selectedEventId) ?? null;
|
|
15410
15376
|
if (event) setSelectedEvent(event);
|
|
15411
15377
|
}
|
|
15412
15378
|
setSelectedAttendanceMode(pending.selectedAttendanceMode ?? null);
|
|
15413
15379
|
setPaymentSelection(pending.paymentSelection);
|
|
15414
15380
|
if (registrationStatus === "cancelled") setStep("select-payment");
|
|
15415
15381
|
else if (registrationStatus === "success") {
|
|
15416
|
-
|
|
15382
|
+
setPendingRegistrationReference(pending.reference);
|
|
15417
15383
|
setStep("verifying-payment");
|
|
15418
15384
|
}
|
|
15419
15385
|
}, []);
|
|
15420
15386
|
useEffect(() => {
|
|
15421
15387
|
if (verification.status === "completed") {
|
|
15422
15388
|
const siteId = api.config.siteId;
|
|
15423
|
-
|
|
15389
|
+
const checkoutAttemptId = checkoutAttemptIdRef.current;
|
|
15390
|
+
if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
|
|
15424
15391
|
setRegistrationResult({ status: "confirmed" });
|
|
15425
15392
|
setStep("success");
|
|
15426
15393
|
} else if (verification.status === "failed") {
|
|
@@ -15433,7 +15400,6 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
|
15433
15400
|
verification.waitlistPosition,
|
|
15434
15401
|
verification.error,
|
|
15435
15402
|
api.config.siteId,
|
|
15436
|
-
occurrenceId,
|
|
15437
15403
|
setErrorMessage,
|
|
15438
15404
|
setRegistrationResult,
|
|
15439
15405
|
setStep
|
|
@@ -15442,7 +15408,21 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
|
|
|
15442
15408
|
}
|
|
15443
15409
|
//#endregion
|
|
15444
15410
|
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.ts
|
|
15445
|
-
|
|
15411
|
+
function createCheckoutAttemptId(cryptoSource = {
|
|
15412
|
+
randomUUID: globalThis.crypto.randomUUID?.bind(globalThis.crypto),
|
|
15413
|
+
getRandomValues: (bytes) => globalThis.crypto.getRandomValues(bytes)
|
|
15414
|
+
}) {
|
|
15415
|
+
if (cryptoSource.randomUUID) return cryptoSource.randomUUID();
|
|
15416
|
+
const bytes = cryptoSource.getRandomValues(/* @__PURE__ */ new Uint8Array(16));
|
|
15417
|
+
bytes[6] = (bytes[6] ?? 0) & 15 | 64;
|
|
15418
|
+
bytes[8] = (bytes[8] ?? 0) & 63 | 128;
|
|
15419
|
+
const hex = Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0"));
|
|
15420
|
+
return `${hex.slice(0, 4).join("")}-${hex.slice(4, 6).join("")}-${hex.slice(6, 8).join("")}-${hex.slice(8, 10).join("")}-${hex.slice(10).join("")}`;
|
|
15421
|
+
}
|
|
15422
|
+
const eventRegistrationSubmitDeps = {
|
|
15423
|
+
savePendingRegistration,
|
|
15424
|
+
createCheckoutAttemptId
|
|
15425
|
+
};
|
|
15446
15426
|
function useEventRegistrationSubmit(options) {
|
|
15447
15427
|
return useEventRegistrationSubmitWithDeps(options, eventRegistrationSubmitDeps);
|
|
15448
15428
|
}
|
|
@@ -15475,46 +15455,22 @@ function toRegistrationResult(result) {
|
|
|
15475
15455
|
}
|
|
15476
15456
|
function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
15477
15457
|
return async (method, passId, membershipId, selection, submitOptions) => {
|
|
15478
|
-
const
|
|
15479
|
-
if (!
|
|
15458
|
+
const target = options.registrationTarget;
|
|
15459
|
+
if (!target) return {
|
|
15480
15460
|
ok: false,
|
|
15481
15461
|
reason: "missing-target",
|
|
15482
15462
|
message: "Select an event to continue."
|
|
15483
15463
|
};
|
|
15484
15464
|
options.setStep("submitting");
|
|
15485
15465
|
try {
|
|
15486
|
-
const
|
|
15487
|
-
if (
|
|
15488
|
-
|
|
15489
|
-
|
|
15490
|
-
|
|
15491
|
-
if (method === "pass") return {
|
|
15492
|
-
method: "pass",
|
|
15493
|
-
passId: passId ?? void 0
|
|
15494
|
-
};
|
|
15495
|
-
if (method === "membership") return {
|
|
15496
|
-
method: "membership",
|
|
15497
|
-
membershipId: membershipId ?? void 0
|
|
15498
|
-
};
|
|
15499
|
-
if (method === "pass_bundle") return {
|
|
15500
|
-
method: "pass_bundle",
|
|
15501
|
-
bundlePassId: bundleProductId ?? void 0
|
|
15502
|
-
};
|
|
15503
|
-
if (method === "membership_bundle") return {
|
|
15504
|
-
method: "membership_bundle",
|
|
15505
|
-
bundleMembershipId: bundleProductId ?? void 0
|
|
15506
|
-
};
|
|
15507
|
-
return { method };
|
|
15508
|
-
})();
|
|
15509
|
-
const guestsPayload = options.requireGuestDetails && options.guests.length > 0 ? options.guests.map((guest) => ({
|
|
15510
|
-
name: guest.name.trim(),
|
|
15511
|
-
email: guest.email?.trim().toLowerCase() || void 0,
|
|
15512
|
-
phone: guest.phone?.trim() || void 0
|
|
15513
|
-
})) : void 0;
|
|
15466
|
+
const prepared = prepareSubmitContext(options, target, method, passId, membershipId, selection);
|
|
15467
|
+
if (prepared.subject.kind === "wholeSeries" && method === "stripe") return submitWholeSeriesCheckout(options, deps, {
|
|
15468
|
+
...prepared,
|
|
15469
|
+
subject: prepared.subject
|
|
15470
|
+
}, submitOptions);
|
|
15514
15471
|
const result = await options.api.registerForEvent({
|
|
15515
|
-
|
|
15516
|
-
|
|
15517
|
-
ticketSelections,
|
|
15472
|
+
subject: prepared.subject,
|
|
15473
|
+
ticketSelections: prepared.ticketSelections,
|
|
15518
15474
|
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
15519
15475
|
email: options.formData.email.trim().toLowerCase(),
|
|
15520
15476
|
name: options.formData.name.trim(),
|
|
@@ -15525,58 +15481,11 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
15525
15481
|
paymentMethod: method,
|
|
15526
15482
|
customerPassId: method === "pass" ? passId : void 0,
|
|
15527
15483
|
customerMembershipId: method === "membership" ? membershipId : void 0,
|
|
15528
|
-
bundleProductId,
|
|
15484
|
+
bundleProductId: prepared.bundleProductId,
|
|
15529
15485
|
claimToken: options.claimToken ?? void 0,
|
|
15530
|
-
guests: guestsPayload
|
|
15486
|
+
guests: prepared.guestsPayload
|
|
15531
15487
|
});
|
|
15532
|
-
if (
|
|
15533
|
-
options.setPendingAttendeeId(result.attendeeId);
|
|
15534
|
-
options.setStep("redirecting");
|
|
15535
|
-
const { successUrl, cancelUrl } = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID);
|
|
15536
|
-
const checkoutType = method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event";
|
|
15537
|
-
const checkoutResult = await options.api.createEventCheckout({
|
|
15538
|
-
attendeeId: result.attendeeId,
|
|
15539
|
-
checkoutType,
|
|
15540
|
-
productId: bundleProductId,
|
|
15541
|
-
discountCode: options.discountCode.trim() ? options.discountCode.trim() : void 0,
|
|
15542
|
-
collectionOptionKind: selectionSnapshot.collectionOptionKind,
|
|
15543
|
-
successUrl,
|
|
15544
|
-
cancelUrl
|
|
15545
|
-
});
|
|
15546
|
-
if (checkoutResult.bypassed) {
|
|
15547
|
-
options.setRegistrationResult({ status: "confirmed" });
|
|
15548
|
-
options.setStep("success");
|
|
15549
|
-
return {
|
|
15550
|
-
ok: true,
|
|
15551
|
-
outcome: { kind: "completed" }
|
|
15552
|
-
};
|
|
15553
|
-
}
|
|
15554
|
-
if (!checkoutResult.checkoutUrl) throw new Error("Checkout URL missing");
|
|
15555
|
-
const siteId = options.api.config.siteId;
|
|
15556
|
-
if (siteId && submitOccurrenceId) deps.savePendingRegistration(siteId, submitOccurrenceId, {
|
|
15557
|
-
attendeeId: result.attendeeId,
|
|
15558
|
-
formData: options.formData,
|
|
15559
|
-
ticketSelections,
|
|
15560
|
-
selectedEventId: options.registrationTarget?.selectedEventId ?? null,
|
|
15561
|
-
selectedAttendanceMode: options.selectedAttendanceMode,
|
|
15562
|
-
paymentSelection: selectionSnapshot
|
|
15563
|
-
});
|
|
15564
|
-
if (submitOptions?.redirect === "manual") return {
|
|
15565
|
-
ok: true,
|
|
15566
|
-
outcome: {
|
|
15567
|
-
kind: "checkout_redirect",
|
|
15568
|
-
checkoutUrl: checkoutResult.checkoutUrl
|
|
15569
|
-
}
|
|
15570
|
-
};
|
|
15571
|
-
window.location.href = checkoutResult.checkoutUrl;
|
|
15572
|
-
return {
|
|
15573
|
-
ok: true,
|
|
15574
|
-
outcome: {
|
|
15575
|
-
kind: "checkout_redirect",
|
|
15576
|
-
checkoutUrl: checkoutResult.checkoutUrl
|
|
15577
|
-
}
|
|
15578
|
-
};
|
|
15579
|
-
}
|
|
15488
|
+
if (needsOccurrenceCheckout(result, method)) return submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
|
|
15580
15489
|
options.setRegistrationResult(toRegistrationResult(result));
|
|
15581
15490
|
options.setStep("success");
|
|
15582
15491
|
return {
|
|
@@ -15595,6 +15504,264 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
|
|
|
15595
15504
|
}
|
|
15596
15505
|
};
|
|
15597
15506
|
}
|
|
15507
|
+
function prepareSubmitContext(options, target, method, passId, membershipId, selection) {
|
|
15508
|
+
const ticketSelections = normalizeTicketSelectionLines(options.ticketSelections);
|
|
15509
|
+
if (ticketSelections.length === 0) throw new Error("Choose at least one ticket to continue.");
|
|
15510
|
+
const bundleProductId = method === "pass_bundle" || method === "membership_bundle" ? passId || membershipId : void 0;
|
|
15511
|
+
return {
|
|
15512
|
+
ticketSelections,
|
|
15513
|
+
bundleProductId,
|
|
15514
|
+
selectionSnapshot: resolveSelectionSnapshot(method, passId, membershipId, bundleProductId, selection),
|
|
15515
|
+
guestsPayload: options.requireGuestDetails && options.guests.length > 0 ? options.guests.map((guest) => ({
|
|
15516
|
+
name: guest.name.trim(),
|
|
15517
|
+
email: guest.email?.trim().toLowerCase() || void 0,
|
|
15518
|
+
phone: guest.phone?.trim() || void 0
|
|
15519
|
+
})) : void 0,
|
|
15520
|
+
subject: target.subject.kind === "occurrence" ? {
|
|
15521
|
+
kind: "occurrence",
|
|
15522
|
+
occurrenceId: target.subject.occurrenceId,
|
|
15523
|
+
attendanceMode: options.selectedAttendanceMode ?? void 0
|
|
15524
|
+
} : {
|
|
15525
|
+
kind: "wholeSeries",
|
|
15526
|
+
eventSeriesId: target.subject.eventSeriesId,
|
|
15527
|
+
attendanceMode: options.selectedAttendanceMode ?? void 0
|
|
15528
|
+
}
|
|
15529
|
+
};
|
|
15530
|
+
}
|
|
15531
|
+
function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId, selection) {
|
|
15532
|
+
if (selection?.method) return selection;
|
|
15533
|
+
if (method === "pass" && passId) return {
|
|
15534
|
+
method,
|
|
15535
|
+
passId
|
|
15536
|
+
};
|
|
15537
|
+
if (method === "membership" && membershipId) return {
|
|
15538
|
+
method,
|
|
15539
|
+
membershipId
|
|
15540
|
+
};
|
|
15541
|
+
if (method === "pass_bundle" && bundleProductId) return {
|
|
15542
|
+
method,
|
|
15543
|
+
bundlePassId: bundleProductId
|
|
15544
|
+
};
|
|
15545
|
+
if (method === "membership_bundle" && bundleProductId) return {
|
|
15546
|
+
method,
|
|
15547
|
+
bundleMembershipId: bundleProductId
|
|
15548
|
+
};
|
|
15549
|
+
if (method === "free") return { method };
|
|
15550
|
+
throw new Error("Choose an available payment option.");
|
|
15551
|
+
}
|
|
15552
|
+
async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions) {
|
|
15553
|
+
options.setStep("redirecting");
|
|
15554
|
+
if (prepared.selectionSnapshot.method !== "stripe") throw new Error("Choose an available payment option.");
|
|
15555
|
+
const checkoutAttemptId = deps.createCheckoutAttemptId();
|
|
15556
|
+
const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
|
|
15557
|
+
const result = await options.api.createEventCheckout({
|
|
15558
|
+
subject: prepared.subject,
|
|
15559
|
+
ticketSelections: prepared.ticketSelections,
|
|
15560
|
+
selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
|
|
15561
|
+
email: options.formData.email.trim().toLowerCase(),
|
|
15562
|
+
name: options.formData.name.trim(),
|
|
15563
|
+
phone: options.formData.phone.trim() || void 0,
|
|
15564
|
+
formData: options.formData,
|
|
15565
|
+
consentAccepted: options.formData.consentAccepted,
|
|
15566
|
+
altchaSolution: options.altchaSolution,
|
|
15567
|
+
guests: prepared.guestsPayload,
|
|
15568
|
+
claimToken: options.claimToken ?? void 0,
|
|
15569
|
+
discountCode: options.discountCode.trim() || void 0,
|
|
15570
|
+
collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
|
|
15571
|
+
...urls
|
|
15572
|
+
});
|
|
15573
|
+
if (result.scope !== "wholeSeries") throw new Error("Unexpected registration scope for event checkout.");
|
|
15574
|
+
if ("waitlistEntryId" in result) {
|
|
15575
|
+
options.setRegistrationResult({
|
|
15576
|
+
status: "waitlist",
|
|
15577
|
+
variant: result.alreadyRegistered ? "info" : void 0,
|
|
15578
|
+
title: result.alreadyRegistered ? "Already waitlisted" : "Added to waitlist",
|
|
15579
|
+
message: result.alreadyRegistered ? "You are already on the waitlist for this event." : "You've been added to the waitlist."
|
|
15580
|
+
});
|
|
15581
|
+
options.setStep("success");
|
|
15582
|
+
return {
|
|
15583
|
+
ok: true,
|
|
15584
|
+
outcome: { kind: "completed" }
|
|
15585
|
+
};
|
|
15586
|
+
}
|
|
15587
|
+
if (result.bypassed) return completeBypassedCheckout(options);
|
|
15588
|
+
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
15589
|
+
savePendingCheckout(options, deps, prepared, checkoutAttemptId, {
|
|
15590
|
+
scope: "wholeSeries",
|
|
15591
|
+
registrationId: result.registrationId
|
|
15592
|
+
});
|
|
15593
|
+
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
15594
|
+
}
|
|
15595
|
+
function needsOccurrenceCheckout(result, method) {
|
|
15596
|
+
return result.scope === "occurrence" && !result.alreadyRegistered && result.status === "confirmed" && result.pendingPayment && [
|
|
15597
|
+
"stripe",
|
|
15598
|
+
"pass_bundle",
|
|
15599
|
+
"membership_bundle"
|
|
15600
|
+
].includes(method);
|
|
15601
|
+
}
|
|
15602
|
+
async function submitOccurrenceCheckout(options, deps, prepared, registration, method, submitOptions) {
|
|
15603
|
+
const reference = {
|
|
15604
|
+
scope: "occurrence",
|
|
15605
|
+
attendeeId: registration.attendeeId
|
|
15606
|
+
};
|
|
15607
|
+
options.setPendingRegistrationReference(reference);
|
|
15608
|
+
options.setStep("redirecting");
|
|
15609
|
+
const checkoutAttemptId = deps.createCheckoutAttemptId();
|
|
15610
|
+
const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
|
|
15611
|
+
const result = await options.api.createEventCheckout({
|
|
15612
|
+
subject: {
|
|
15613
|
+
kind: "occurrence",
|
|
15614
|
+
attendeeId: registration.attendeeId
|
|
15615
|
+
},
|
|
15616
|
+
checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
|
|
15617
|
+
productId: prepared.bundleProductId,
|
|
15618
|
+
discountCode: options.discountCode.trim() || void 0,
|
|
15619
|
+
collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0,
|
|
15620
|
+
...urls
|
|
15621
|
+
});
|
|
15622
|
+
if (result.scope !== "occurrence") throw new Error("Unexpected registration scope for event checkout.");
|
|
15623
|
+
if (result.bypassed) return completeBypassedCheckout(options);
|
|
15624
|
+
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
15625
|
+
if (prepared.subject.kind === "occurrence") savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference);
|
|
15626
|
+
return redirectToCheckout(result.checkoutUrl, submitOptions);
|
|
15627
|
+
}
|
|
15628
|
+
function savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference) {
|
|
15629
|
+
const siteId = options.api.config.siteId;
|
|
15630
|
+
if (!siteId) return;
|
|
15631
|
+
deps.savePendingRegistration(siteId, checkoutAttemptId, {
|
|
15632
|
+
reference,
|
|
15633
|
+
formData: options.formData,
|
|
15634
|
+
ticketSelections: prepared.ticketSelections,
|
|
15635
|
+
selectedEventId: options.registrationTarget?.selectedEventId ?? null,
|
|
15636
|
+
selectedAttendanceMode: options.selectedAttendanceMode,
|
|
15637
|
+
paymentSelection: prepared.selectionSnapshot
|
|
15638
|
+
});
|
|
15639
|
+
}
|
|
15640
|
+
function completeBypassedCheckout(options) {
|
|
15641
|
+
options.setRegistrationResult({ status: "confirmed" });
|
|
15642
|
+
options.setStep("success");
|
|
15643
|
+
return {
|
|
15644
|
+
ok: true,
|
|
15645
|
+
outcome: { kind: "completed" }
|
|
15646
|
+
};
|
|
15647
|
+
}
|
|
15648
|
+
function redirectToCheckout(checkoutUrl, submitOptions) {
|
|
15649
|
+
if (submitOptions?.redirect !== "manual") window.location.href = checkoutUrl;
|
|
15650
|
+
return {
|
|
15651
|
+
ok: true,
|
|
15652
|
+
outcome: {
|
|
15653
|
+
kind: "checkout_redirect",
|
|
15654
|
+
checkoutUrl
|
|
15655
|
+
}
|
|
15656
|
+
};
|
|
15657
|
+
}
|
|
15658
|
+
//#endregion
|
|
15659
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.ts
|
|
15660
|
+
function getApprovedDirectPaymentCollectionOptionKinds(paymentOptions) {
|
|
15661
|
+
return paymentOptions.flatMap((option) => {
|
|
15662
|
+
switch (option.kind) {
|
|
15663
|
+
case "payInFull": return ["upfront"];
|
|
15664
|
+
case "deferredManual": return ["deferred_manual"];
|
|
15665
|
+
case "instalmentPlan": return ["instalment_plan"];
|
|
15666
|
+
case "flexibleBalance": return ["flexible_balance"];
|
|
15667
|
+
case "free":
|
|
15668
|
+
case "ownedMembership":
|
|
15669
|
+
case "ownedPass":
|
|
15670
|
+
case "buyMembership":
|
|
15671
|
+
case "buyPass": return [];
|
|
15672
|
+
}
|
|
15673
|
+
});
|
|
15674
|
+
}
|
|
15675
|
+
function buildEventRegistrationPaymentOptionsViewModel(input) {
|
|
15676
|
+
const approvedOptions = selectApprovedEventDirectPaymentOptions(input.approvedPaymentOptions, input.paymentTerms);
|
|
15677
|
+
const selection = buildBookingPaymentSelectionViewModel({
|
|
15678
|
+
serviceTitle: input.eventTitle,
|
|
15679
|
+
paymentTerms: { allowedOptions: [...approvedOptions] },
|
|
15680
|
+
priceAmount: input.totalPriceCents,
|
|
15681
|
+
priceCurrency: input.currency,
|
|
15682
|
+
bookingStartAt: input.startsAt,
|
|
15683
|
+
locale: input.locale
|
|
15684
|
+
});
|
|
15685
|
+
return {
|
|
15686
|
+
mode: selection.mode,
|
|
15687
|
+
sectionTitle: selection.sectionTitle,
|
|
15688
|
+
options: selection.options.flatMap((option, index) => {
|
|
15689
|
+
const sourceOption = approvedOptions[index];
|
|
15690
|
+
return sourceOption ? [toEventDirectPaymentOption(option, sourceOption, selection.mode, input.totalPriceCents, input.startsAt)] : [];
|
|
15691
|
+
})
|
|
15692
|
+
};
|
|
15693
|
+
}
|
|
15694
|
+
function selectApprovedEventDirectPaymentOptions(approvedPaymentOptions, paymentTerms) {
|
|
15695
|
+
const approvedKinds = new Set(getApprovedDirectPaymentCollectionOptionKinds(approvedPaymentOptions));
|
|
15696
|
+
return paymentTerms.allowedOptions.filter((option) => approvedKinds.has(option.kind));
|
|
15697
|
+
}
|
|
15698
|
+
function toEventDirectPaymentOption(option, sourceOption, mode, totalCents, startsAt) {
|
|
15699
|
+
const configuredPaymentDueNowCents = resolveBookingPaymentDueNowCents({
|
|
15700
|
+
option: sourceOption,
|
|
15701
|
+
totalCents,
|
|
15702
|
+
bookingStartAt: startsAt
|
|
15703
|
+
});
|
|
15704
|
+
switch (option.kind) {
|
|
15705
|
+
case "upfront": return {
|
|
15706
|
+
...option,
|
|
15707
|
+
kind: "upfront",
|
|
15708
|
+
label: mode === "choice_required" ? "Pay in full now" : "Pay by card",
|
|
15709
|
+
totalCents,
|
|
15710
|
+
configuredPaymentDueNowCents
|
|
15711
|
+
};
|
|
15712
|
+
case "deferred_manual": return {
|
|
15713
|
+
...option,
|
|
15714
|
+
kind: "deferred_manual",
|
|
15715
|
+
label: option.title,
|
|
15716
|
+
totalCents,
|
|
15717
|
+
configuredPaymentDueNowCents
|
|
15718
|
+
};
|
|
15719
|
+
case "instalment_plan": return {
|
|
15720
|
+
...option,
|
|
15721
|
+
kind: "instalment_plan",
|
|
15722
|
+
label: option.title,
|
|
15723
|
+
totalCents,
|
|
15724
|
+
configuredPaymentDueNowCents
|
|
15725
|
+
};
|
|
15726
|
+
case "flexible_balance": return {
|
|
15727
|
+
...option,
|
|
15728
|
+
kind: "flexible_balance",
|
|
15729
|
+
label: "Pay deposit now",
|
|
15730
|
+
totalCents,
|
|
15731
|
+
configuredPaymentDueNowCents
|
|
15732
|
+
};
|
|
15733
|
+
}
|
|
15734
|
+
}
|
|
15735
|
+
function resolveEventRegistrationDirectPaymentSelection(input) {
|
|
15736
|
+
if (input.selection.method !== "stripe") return { kind: "not-stripe" };
|
|
15737
|
+
const fallbackOption = input.options[0];
|
|
15738
|
+
if (!fallbackOption) return { kind: "unavailable" };
|
|
15739
|
+
const requestedKind = input.selection.collectionOptionKind;
|
|
15740
|
+
const selectedOption = input.options.find((option) => option.kind === requestedKind);
|
|
15741
|
+
if (selectedOption) return {
|
|
15742
|
+
kind: "valid",
|
|
15743
|
+
selection: {
|
|
15744
|
+
method: "stripe",
|
|
15745
|
+
collectionOptionKind: selectedOption.kind
|
|
15746
|
+
}
|
|
15747
|
+
};
|
|
15748
|
+
return {
|
|
15749
|
+
kind: "invalid",
|
|
15750
|
+
fallbackSelection: {
|
|
15751
|
+
method: "stripe",
|
|
15752
|
+
collectionOptionKind: fallbackOption.kind
|
|
15753
|
+
}
|
|
15754
|
+
};
|
|
15755
|
+
}
|
|
15756
|
+
function normalizeEventRegistrationDirectPaymentSelection(input) {
|
|
15757
|
+
const selectionState = resolveEventRegistrationDirectPaymentSelection(input);
|
|
15758
|
+
switch (selectionState.kind) {
|
|
15759
|
+
case "valid": return selectionState.selection;
|
|
15760
|
+
case "invalid": return selectionState.fallbackSelection;
|
|
15761
|
+
case "not-stripe":
|
|
15762
|
+
case "unavailable": return input.selection;
|
|
15763
|
+
}
|
|
15764
|
+
}
|
|
15598
15765
|
//#endregion
|
|
15599
15766
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationStateMachine.ts
|
|
15600
15767
|
function createInitialRegistrationFlowState(hasPreSelectedContext) {
|
|
@@ -15609,14 +15776,19 @@ function createInitialRegistrationFlowState(hasPreSelectedContext) {
|
|
|
15609
15776
|
};
|
|
15610
15777
|
}
|
|
15611
15778
|
function selectionEquals(a, b) {
|
|
15612
|
-
|
|
15779
|
+
if (a.method !== b.method) return false;
|
|
15780
|
+
switch (a.method) {
|
|
15781
|
+
case null:
|
|
15782
|
+
case "free": return true;
|
|
15783
|
+
case "stripe": return b.method === "stripe" && a.collectionOptionKind === b.collectionOptionKind;
|
|
15784
|
+
case "pass": return b.method === "pass" && a.passId === b.passId;
|
|
15785
|
+
case "membership": return b.method === "membership" && a.membershipId === b.membershipId;
|
|
15786
|
+
case "pass_bundle": return b.method === "pass_bundle" && a.bundlePassId === b.bundlePassId;
|
|
15787
|
+
case "membership_bundle": return b.method === "membership_bundle" && a.bundleMembershipId === b.bundleMembershipId;
|
|
15788
|
+
}
|
|
15613
15789
|
}
|
|
15614
|
-
function
|
|
15790
|
+
function normalizePaymentSelection(selection) {
|
|
15615
15791
|
if (!selection || !selection.method) return { method: null };
|
|
15616
|
-
if (selection.method === "stripe") return {
|
|
15617
|
-
...selection,
|
|
15618
|
-
collectionOptionKind: selection.collectionOptionKind ?? "upfront"
|
|
15619
|
-
};
|
|
15620
15792
|
return selection;
|
|
15621
15793
|
}
|
|
15622
15794
|
function computeAutoSelection(input) {
|
|
@@ -15637,12 +15809,19 @@ function computeAutoSelection(input) {
|
|
|
15637
15809
|
productName: pass.passName
|
|
15638
15810
|
};
|
|
15639
15811
|
}
|
|
15640
|
-
|
|
15641
|
-
|
|
15642
|
-
collectionOptionKind: "upfront"
|
|
15643
|
-
};
|
|
15812
|
+
const directPaymentSelection = computeDirectPaymentSelection(eligibility);
|
|
15813
|
+
if (directPaymentSelection.method === "stripe" && eligibility.price) return directPaymentSelection;
|
|
15644
15814
|
return { method: null };
|
|
15645
15815
|
}
|
|
15816
|
+
function computeDirectPaymentSelection(eligibility) {
|
|
15817
|
+
if (!eligibility?.canPayDirectly) return { method: null };
|
|
15818
|
+
const approvedKinds = getApprovedDirectPaymentCollectionOptionKinds(eligibility.paymentOptions);
|
|
15819
|
+
const collectionOptionKind = approvedKinds.includes("upfront") ? "upfront" : approvedKinds[0];
|
|
15820
|
+
return collectionOptionKind ? {
|
|
15821
|
+
method: "stripe",
|
|
15822
|
+
collectionOptionKind
|
|
15823
|
+
} : { method: null };
|
|
15824
|
+
}
|
|
15646
15825
|
function isSelectionValid(input) {
|
|
15647
15826
|
const { selection, isAuthenticated, eligibility, ticketsCount } = input;
|
|
15648
15827
|
if (!selection.method) return false;
|
|
@@ -15676,7 +15855,7 @@ function normalizeRegistrationFlowState(state) {
|
|
|
15676
15855
|
});
|
|
15677
15856
|
const nextSelection = canKeepManualSelection ? state.paymentSelection : autoSelection;
|
|
15678
15857
|
const nextSource = canKeepManualSelection ? "manual" : "auto";
|
|
15679
|
-
const normalizedSelection =
|
|
15858
|
+
const normalizedSelection = normalizePaymentSelection(nextSelection);
|
|
15680
15859
|
if (nextPassOptOut === state.passOptOut && nextSource === state.selectionSource && selectionEquals(normalizedSelection, state.paymentSelection)) return state;
|
|
15681
15860
|
return {
|
|
15682
15861
|
...state,
|
|
@@ -15705,17 +15884,14 @@ function registrationFlowReducer(state, action) {
|
|
|
15705
15884
|
});
|
|
15706
15885
|
case "set-manual-payment-selection": return normalizeRegistrationFlowState({
|
|
15707
15886
|
...state,
|
|
15708
|
-
paymentSelection:
|
|
15887
|
+
paymentSelection: normalizePaymentSelection(action.selection),
|
|
15709
15888
|
selectionSource: "manual",
|
|
15710
15889
|
passOptOut: action.selection.method === "stripe" ? true : state.passOptOut
|
|
15711
15890
|
});
|
|
15712
15891
|
case "use-card-instead-of-pass": return normalizeRegistrationFlowState({
|
|
15713
15892
|
...state,
|
|
15714
15893
|
passOptOut: true,
|
|
15715
|
-
paymentSelection:
|
|
15716
|
-
method: "stripe",
|
|
15717
|
-
collectionOptionKind: "upfront"
|
|
15718
|
-
},
|
|
15894
|
+
paymentSelection: computeDirectPaymentSelection(state.eligibility),
|
|
15719
15895
|
selectionSource: "manual"
|
|
15720
15896
|
});
|
|
15721
15897
|
case "event-changed": return normalizeRegistrationFlowState({
|
|
@@ -15955,6 +16131,13 @@ const publicWholeSeriesOfferingSchema = z.object({
|
|
|
15955
16131
|
title: z.string(),
|
|
15956
16132
|
slug: z.string(),
|
|
15957
16133
|
description: z.unknown().nullable(),
|
|
16134
|
+
deliveryMode: z.enum([
|
|
16135
|
+
"in_person",
|
|
16136
|
+
"online",
|
|
16137
|
+
"hybrid"
|
|
16138
|
+
]),
|
|
16139
|
+
waitlistEnabled: z.boolean(),
|
|
16140
|
+
requireGuestDetails: z.boolean(),
|
|
15958
16141
|
teamMembers: z.array(wholeSeriesTeamMemberSummarySchema).optional(),
|
|
15959
16142
|
enrollmentOpen: z.boolean(),
|
|
15960
16143
|
pricing: wholeSeriesPricingSchema,
|
|
@@ -16070,7 +16253,7 @@ const mixedPriceDisplaySchema = z.object({
|
|
|
16070
16253
|
paidToAmount: z.number(),
|
|
16071
16254
|
currency: z.string()
|
|
16072
16255
|
});
|
|
16073
|
-
const
|
|
16256
|
+
const publicWholeSeriesPriceDisplaySchema = z.discriminatedUnion("kind", [
|
|
16074
16257
|
freePriceDisplaySchema,
|
|
16075
16258
|
exactPriceDisplaySchema,
|
|
16076
16259
|
fromPriceDisplaySchema,
|
|
@@ -16088,8 +16271,8 @@ z.discriminatedUnion("kind", [
|
|
|
16088
16271
|
label: z.string()
|
|
16089
16272
|
}),
|
|
16090
16273
|
z.object({
|
|
16091
|
-
kind: z.literal("
|
|
16092
|
-
display:
|
|
16274
|
+
kind: z.literal("whole_series"),
|
|
16275
|
+
display: publicWholeSeriesPriceDisplaySchema
|
|
16093
16276
|
})
|
|
16094
16277
|
]);
|
|
16095
16278
|
const publicEventTicketTypePriceDisplaySchema = z.union([
|
|
@@ -16191,10 +16374,10 @@ const publicEventPricingSchema = z.discriminatedUnion("kind", [
|
|
|
16191
16374
|
})
|
|
16192
16375
|
}),
|
|
16193
16376
|
z.object({
|
|
16194
|
-
kind: z.literal("
|
|
16377
|
+
kind: z.literal("whole_series"),
|
|
16195
16378
|
display: z.object({
|
|
16196
|
-
kind: z.literal("
|
|
16197
|
-
display:
|
|
16379
|
+
kind: z.literal("whole_series"),
|
|
16380
|
+
display: publicWholeSeriesPriceDisplaySchema
|
|
16198
16381
|
})
|
|
16199
16382
|
}),
|
|
16200
16383
|
z.object({
|
|
@@ -16359,7 +16542,8 @@ function resolveEventRegistrationScope(context) {
|
|
|
16359
16542
|
};
|
|
16360
16543
|
return { kind: "unscoped" };
|
|
16361
16544
|
}
|
|
16362
|
-
function
|
|
16545
|
+
function resolveEventRegistrationScopedEvents(events, context) {
|
|
16546
|
+
const scope = resolveEventRegistrationScope(context);
|
|
16363
16547
|
switch (scope.kind) {
|
|
16364
16548
|
case "occurrenceSeries":
|
|
16365
16549
|
case "pageSurfaceSeries": return events.filter((event) => event.seriesId === scope.seriesId);
|
|
@@ -16371,9 +16555,6 @@ function applyEventRegistrationScope(events, scope) {
|
|
|
16371
16555
|
case "unscoped": return [...events];
|
|
16372
16556
|
}
|
|
16373
16557
|
}
|
|
16374
|
-
function resolveEventRegistrationScopedEvents(events, context) {
|
|
16375
|
-
return applyEventRegistrationScope(events, resolveEventRegistrationScope(context));
|
|
16376
|
-
}
|
|
16377
16558
|
//#endregion
|
|
16378
16559
|
//#region ../blocks/src/system/runtime/nodes/event-registration/event-registration.headless.override.ts
|
|
16379
16560
|
function createEventRegistrationBlockApiConfig(input) {
|
|
@@ -16421,7 +16602,6 @@ function getEventRegistrationOverrideInput(props) {
|
|
|
16421
16602
|
...content.showVenue != null ? { showVenue: content.showVenue } : {},
|
|
16422
16603
|
...content.showCapacity != null ? { showCapacity: content.showCapacity } : {},
|
|
16423
16604
|
...content.successMessage ? { successMessage: content.successMessage } : {},
|
|
16424
|
-
...content.waitlistMessage ? { waitlistMessage: content.waitlistMessage } : {},
|
|
16425
16605
|
...content.buttonText != null ? { buttonText: content.buttonText } : {},
|
|
16426
16606
|
...content.buttonVariant ? { buttonVariant: content.buttonVariant } : {},
|
|
16427
16607
|
...content.spamProtectionEnabled != null ? { spamProtectionEnabled: content.spamProtectionEnabled } : {},
|
|
@@ -16499,7 +16679,7 @@ function toInternalPaymentSelection(selection) {
|
|
|
16499
16679
|
case "free": return { method: "free" };
|
|
16500
16680
|
case "stripe": return {
|
|
16501
16681
|
method: "stripe",
|
|
16502
|
-
collectionOptionKind: selection.collectionOptionKind
|
|
16682
|
+
collectionOptionKind: selection.collectionOptionKind
|
|
16503
16683
|
};
|
|
16504
16684
|
case "pass": return {
|
|
16505
16685
|
method: "pass",
|
|
@@ -16670,7 +16850,7 @@ function getStepLabel(step) {
|
|
|
16670
16850
|
//#endregion
|
|
16671
16851
|
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
|
|
16672
16852
|
function eventMatchesOccurrenceId(event, occurrenceId) {
|
|
16673
|
-
return event.
|
|
16853
|
+
return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
|
|
16674
16854
|
}
|
|
16675
16855
|
function findEventByOccurrenceId(events, occurrenceId) {
|
|
16676
16856
|
return events.find((event) => eventMatchesOccurrenceId(event, occurrenceId)) ?? null;
|
|
@@ -16688,11 +16868,14 @@ function findPreSelectedEvent(input) {
|
|
|
16688
16868
|
})) === contextDate) ?? null;
|
|
16689
16869
|
}
|
|
16690
16870
|
function resolveRegistrationTarget(input) {
|
|
16691
|
-
const
|
|
16692
|
-
|
|
16871
|
+
const subject = input.occurrenceContext ? {
|
|
16872
|
+
kind: "occurrence",
|
|
16873
|
+
occurrenceId: input.occurrenceContext.id
|
|
16874
|
+
} : input.selectedEvent?.registrationSubject ?? null;
|
|
16875
|
+
if (!subject) return null;
|
|
16693
16876
|
return {
|
|
16694
|
-
|
|
16695
|
-
selectedEventId: input.selectedEvent?.
|
|
16877
|
+
subject,
|
|
16878
|
+
selectedEventId: input.selectedEvent?.selectionId ?? null
|
|
16696
16879
|
};
|
|
16697
16880
|
}
|
|
16698
16881
|
function resolveEventRequiresPayment(input) {
|
|
@@ -16728,32 +16911,140 @@ function toRegistrationEvent(event) {
|
|
|
16728
16911
|
return {
|
|
16729
16912
|
...event,
|
|
16730
16913
|
pricing: resolveRuntimeEventPricing(event),
|
|
16731
|
-
|
|
16732
|
-
|
|
16914
|
+
selectionId: event.id,
|
|
16915
|
+
registrationSubject: {
|
|
16916
|
+
kind: "occurrence",
|
|
16917
|
+
occurrenceId: event.occurrenceId
|
|
16918
|
+
}
|
|
16733
16919
|
};
|
|
16734
16920
|
}
|
|
16735
16921
|
function toRegistrationEvents(events) {
|
|
16736
|
-
return events.map(toRegistrationEvent);
|
|
16922
|
+
return events.filter((event) => event.bookingScope === "single_occurrence").map(toRegistrationEvent);
|
|
16923
|
+
}
|
|
16924
|
+
function toWholeSeriesTicketType(option) {
|
|
16925
|
+
return {
|
|
16926
|
+
...option,
|
|
16927
|
+
capacityMode: option.capacityLimit === null ? "unlimited" : "limited",
|
|
16928
|
+
attendanceScope: option.attendanceScope ?? void 0,
|
|
16929
|
+
availability: {
|
|
16930
|
+
kind: "available",
|
|
16931
|
+
remainingCapacity: option.capacityLimit
|
|
16932
|
+
}
|
|
16933
|
+
};
|
|
16934
|
+
}
|
|
16935
|
+
function toWholeSeriesPricing(offering) {
|
|
16936
|
+
const resolved = resolveWholeSeriesPricingState(offering);
|
|
16937
|
+
switch (offering.pricing.pricingStrategy) {
|
|
16938
|
+
case "free": return {
|
|
16939
|
+
kind: "free_registration",
|
|
16940
|
+
currency: offering.currency,
|
|
16941
|
+
display: {
|
|
16942
|
+
kind: "free",
|
|
16943
|
+
currency: offering.currency
|
|
16944
|
+
}
|
|
16945
|
+
};
|
|
16946
|
+
case "single": {
|
|
16947
|
+
const amount = offering.pricing.singlePriceAmount ?? 0;
|
|
16948
|
+
return amount === 0 ? {
|
|
16949
|
+
kind: "free_registration",
|
|
16950
|
+
currency: offering.currency,
|
|
16951
|
+
display: {
|
|
16952
|
+
kind: "free",
|
|
16953
|
+
currency: offering.currency
|
|
16954
|
+
}
|
|
16955
|
+
} : {
|
|
16956
|
+
kind: "single_paid",
|
|
16957
|
+
amount,
|
|
16958
|
+
currency: offering.currency,
|
|
16959
|
+
display: {
|
|
16960
|
+
kind: "exact",
|
|
16961
|
+
amount,
|
|
16962
|
+
currency: offering.currency
|
|
16963
|
+
}
|
|
16964
|
+
};
|
|
16965
|
+
}
|
|
16966
|
+
case "tiered": return {
|
|
16967
|
+
kind: "ticket_types",
|
|
16968
|
+
currency: offering.currency,
|
|
16969
|
+
ticketTypes: resolved.selectableOptions.map((option) => toWholeSeriesTicketType(option)),
|
|
16970
|
+
display: resolved.display
|
|
16971
|
+
};
|
|
16972
|
+
case "sliding_scale": return {
|
|
16973
|
+
kind: "sliding_scale",
|
|
16974
|
+
minAmount: offering.pricing.slidingMinAmount ?? 0,
|
|
16975
|
+
maxAmount: offering.pricing.slidingMaxAmount ?? 0,
|
|
16976
|
+
suggestedAmount: offering.pricing.slidingSuggestedAmount ?? null,
|
|
16977
|
+
currency: offering.currency,
|
|
16978
|
+
display: {
|
|
16979
|
+
kind: "range",
|
|
16980
|
+
minAmount: offering.pricing.slidingMinAmount ?? 0,
|
|
16981
|
+
maxAmount: offering.pricing.slidingMaxAmount ?? 0,
|
|
16982
|
+
currency: offering.currency
|
|
16983
|
+
}
|
|
16984
|
+
};
|
|
16985
|
+
}
|
|
16986
|
+
}
|
|
16987
|
+
function toAttendanceModes(offering) {
|
|
16988
|
+
return (offering.deliveryMode === "hybrid" ? ["in_person", "online"] : [offering.deliveryMode]).map((mode) => ({
|
|
16989
|
+
mode,
|
|
16990
|
+
capacity: offering.enrollmentCapacity,
|
|
16991
|
+
registeredCount: offering.enrolledCount,
|
|
16992
|
+
availableSpots: offering.availableSpots,
|
|
16993
|
+
waitlistEnabled: offering.waitlistEnabled
|
|
16994
|
+
}));
|
|
16995
|
+
}
|
|
16996
|
+
function toWholeSeriesRegistrationEvent(offering) {
|
|
16997
|
+
const firstSession = offering.sessions[0];
|
|
16998
|
+
const lastSession = offering.sessions[offering.sessions.length - 1];
|
|
16999
|
+
return {
|
|
17000
|
+
selectionId: offering.eventSeriesId,
|
|
17001
|
+
registrationSubject: {
|
|
17002
|
+
kind: "wholeSeries",
|
|
17003
|
+
eventSeriesId: offering.eventSeriesId,
|
|
17004
|
+
sessions: offering.sessions
|
|
17005
|
+
},
|
|
17006
|
+
seriesId: offering.eventSeriesId,
|
|
17007
|
+
title: offering.title,
|
|
17008
|
+
startsAt: firstSession?.startsAt ?? "",
|
|
17009
|
+
endsAt: lastSession?.endsAt ?? firstSession?.endsAt ?? "",
|
|
17010
|
+
bookingAvailability: offering.enrollmentOpen ? { kind: "open" } : {
|
|
17011
|
+
kind: "closed",
|
|
17012
|
+
reason: "enrollment_closed"
|
|
17013
|
+
},
|
|
17014
|
+
deliveryMode: offering.deliveryMode,
|
|
17015
|
+
attendanceModes: toAttendanceModes(offering),
|
|
17016
|
+
capacity: offering.enrollmentCapacity,
|
|
17017
|
+
registeredCount: offering.enrolledCount,
|
|
17018
|
+
availableSpots: offering.availableSpots,
|
|
17019
|
+
waitlistEnabled: offering.waitlistEnabled,
|
|
17020
|
+
venue: offering.venue ? {
|
|
17021
|
+
...offering.venue,
|
|
17022
|
+
location: null
|
|
17023
|
+
} : null,
|
|
17024
|
+
eventCategory: null,
|
|
17025
|
+
teamMembers: offering.teamMembers,
|
|
17026
|
+
status: offering.status,
|
|
17027
|
+
timeZone: firstSession?.timeZone ?? "UTC",
|
|
17028
|
+
pricing: toWholeSeriesPricing(offering),
|
|
17029
|
+
paymentTerms: offering.paymentTerms,
|
|
17030
|
+
consent: offering.consent,
|
|
17031
|
+
requireGuestDetails: offering.requireGuestDetails,
|
|
17032
|
+
acceptsPasses: false,
|
|
17033
|
+
acceptsMemberships: offering.acceptsMemberships
|
|
17034
|
+
};
|
|
17035
|
+
}
|
|
17036
|
+
function toWholeSeriesRegistrationEvents(offerings) {
|
|
17037
|
+
return offerings.map(toWholeSeriesRegistrationEvent);
|
|
16737
17038
|
}
|
|
16738
17039
|
//#endregion
|
|
16739
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/
|
|
16740
|
-
|
|
16741
|
-
usePortalAuth,
|
|
16742
|
-
useEligibility,
|
|
16743
|
-
useExistingEventRegistration,
|
|
16744
|
-
useWaitlistClaim,
|
|
16745
|
-
useEventRegistrationStripeReturn,
|
|
16746
|
-
useEventRegistrationSubmit,
|
|
16747
|
-
useDiscountCodeUi
|
|
16748
|
-
};
|
|
16749
|
-
function parseCurrencyInputToCents$1(value) {
|
|
17040
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.ts
|
|
17041
|
+
function parseCurrencyInputToCents(value) {
|
|
16750
17042
|
const trimmed = value.trim();
|
|
16751
17043
|
if (!trimmed) return null;
|
|
16752
17044
|
const amount = Number(trimmed);
|
|
16753
|
-
|
|
16754
|
-
return Math.round(amount * 100);
|
|
17045
|
+
return Number.isFinite(amount) && amount >= 0 ? Math.round(amount * 100) : null;
|
|
16755
17046
|
}
|
|
16756
|
-
function formatCentsAsCurrencyInput
|
|
17047
|
+
function formatCentsAsCurrencyInput(amount) {
|
|
16757
17048
|
const major = amount / 100;
|
|
16758
17049
|
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
16759
17050
|
}
|
|
@@ -16768,15 +17059,127 @@ function getSlidingScaleForEvent(event) {
|
|
|
16768
17059
|
function getSlidingScaleSelectionMessage(input) {
|
|
16769
17060
|
if (!input.slidingScale) return null;
|
|
16770
17061
|
if (input.selectedAmount === null) return "Choose an amount to continue.";
|
|
16771
|
-
|
|
16772
|
-
return null;
|
|
17062
|
+
const { minAmount, maxAmount } = input.slidingScale;
|
|
17063
|
+
return input.selectedAmount < minAmount || input.selectedAmount > maxAmount ? "Choose an amount within the sliding scale." : null;
|
|
17064
|
+
}
|
|
17065
|
+
function getRegistrationOccurrenceId(target) {
|
|
17066
|
+
return target?.subject.kind === "occurrence" ? target.subject.occurrenceId : "";
|
|
17067
|
+
}
|
|
17068
|
+
function shouldLoadRegistrationOptions(authState, step) {
|
|
17069
|
+
return authState === "authenticated" || step === "select-tickets" || step === "enter-details" || step === "select-payment";
|
|
17070
|
+
}
|
|
17071
|
+
function getEligibilityFlowFlags(input) {
|
|
17072
|
+
const hasPass = (input.eligibility?.eligiblePasses.length ?? 0) > 0;
|
|
17073
|
+
const hasMembership = (input.eligibility?.eligibleMemberships.length ?? 0) > 0;
|
|
17074
|
+
return {
|
|
17075
|
+
hasEligibility: hasPass || hasMembership,
|
|
17076
|
+
hasMembershipEligibility: hasMembership,
|
|
17077
|
+
isMembershipFastTrack: input.portalAuthState === "authenticated" && hasMembership && input.ticketsCount === 1 && input.paymentMethod === "membership"
|
|
17078
|
+
};
|
|
17079
|
+
}
|
|
17080
|
+
//#endregion
|
|
17081
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/waitlistClaimRestoration.ts
|
|
17082
|
+
function resolveWaitlistClaimRestoration(input) {
|
|
17083
|
+
const { subject } = input.claim;
|
|
17084
|
+
if (subject.kind === "event_occurrence") {
|
|
17085
|
+
const event = findEventByOccurrenceId(input.scopedEvents, subject.occurrenceId);
|
|
17086
|
+
if (!event && input.occurrenceContextId !== subject.occurrenceId) return {
|
|
17087
|
+
ok: false,
|
|
17088
|
+
message: "This waitlist claim is for a different event."
|
|
17089
|
+
};
|
|
17090
|
+
return {
|
|
17091
|
+
ok: true,
|
|
17092
|
+
event,
|
|
17093
|
+
attendanceMode: subject.attendanceMode,
|
|
17094
|
+
ticketSelections: [{
|
|
17095
|
+
ticketTypeId: null,
|
|
17096
|
+
quantity: 1
|
|
17097
|
+
}],
|
|
17098
|
+
ticketsCount: 1,
|
|
17099
|
+
slidingAmountInput: null
|
|
17100
|
+
};
|
|
17101
|
+
}
|
|
17102
|
+
const event = input.scopedEvents.find((candidate) => candidate.registrationSubject.kind === "wholeSeries" && candidate.registrationSubject.eventSeriesId === subject.eventSeriesId);
|
|
17103
|
+
if (!event) return {
|
|
17104
|
+
ok: false,
|
|
17105
|
+
message: "This waitlist claim is for a different event run."
|
|
17106
|
+
};
|
|
17107
|
+
return {
|
|
17108
|
+
ok: true,
|
|
17109
|
+
event,
|
|
17110
|
+
attendanceMode: subject.attendanceMode,
|
|
17111
|
+
ticketSelections: subject.ticketSelections,
|
|
17112
|
+
ticketsCount: subject.seatCount,
|
|
17113
|
+
slidingAmountInput: subject.selectedSlidingAmount === null ? null : formatCentsAsCurrencyInput(subject.selectedSlidingAmount)
|
|
17114
|
+
};
|
|
17115
|
+
}
|
|
17116
|
+
function resolveClaimedTicketSelections(claim) {
|
|
17117
|
+
if (!claim) return null;
|
|
17118
|
+
return claim.subject.kind === "whole_series" ? claim.subject.ticketSelections : [{
|
|
17119
|
+
ticketTypeId: null,
|
|
17120
|
+
quantity: 1
|
|
17121
|
+
}];
|
|
17122
|
+
}
|
|
17123
|
+
function resolveClaimTicketCount(claim, fallback) {
|
|
17124
|
+
if (!claim) return fallback;
|
|
17125
|
+
return claim.subject.kind === "whole_series" ? claim.subject.seatCount : 1;
|
|
17126
|
+
}
|
|
17127
|
+
//#endregion
|
|
17128
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.ts
|
|
17129
|
+
function useWaitlistClaimRestoration(input) {
|
|
17130
|
+
useEffect(() => {
|
|
17131
|
+
if (!input.claim) return;
|
|
17132
|
+
const restoration = resolveWaitlistClaimRestoration({
|
|
17133
|
+
claim: input.claim,
|
|
17134
|
+
scopedEvents: input.scopedEvents,
|
|
17135
|
+
occurrenceContextId: input.occurrenceContextId
|
|
17136
|
+
});
|
|
17137
|
+
if (!restoration.ok) {
|
|
17138
|
+
input.setters.setErrorMessage(restoration.message);
|
|
17139
|
+
input.setters.setStep("error");
|
|
17140
|
+
return;
|
|
17141
|
+
}
|
|
17142
|
+
if (restoration.event) input.setters.setSelectedEvent(restoration.event);
|
|
17143
|
+
input.setters.setAttendanceMode(restoration.attendanceMode);
|
|
17144
|
+
input.setters.setTicketSelections([...restoration.ticketSelections]);
|
|
17145
|
+
if (restoration.slidingAmountInput !== null) input.setters.setSlidingAmountInput(restoration.slidingAmountInput);
|
|
17146
|
+
input.setters.setTicketsCount(restoration.ticketsCount);
|
|
17147
|
+
input.setters.setFormData((previous) => ({
|
|
17148
|
+
...previous,
|
|
17149
|
+
email: input.claim?.prefill.email ?? "",
|
|
17150
|
+
name: input.claim?.prefill.name ?? "",
|
|
17151
|
+
phone: input.claim?.prefill.phone ?? "",
|
|
17152
|
+
notes: input.claim?.prefill.notes ?? ""
|
|
17153
|
+
}));
|
|
17154
|
+
input.setters.setGuests(input.claim.prefill.guests.map((guest) => ({
|
|
17155
|
+
name: guest.name,
|
|
17156
|
+
email: guest.email ?? "",
|
|
17157
|
+
phone: guest.phone ?? ""
|
|
17158
|
+
})));
|
|
17159
|
+
}, [
|
|
17160
|
+
input.claim,
|
|
17161
|
+
input.occurrenceContextId,
|
|
17162
|
+
input.scopedEvents,
|
|
17163
|
+
input.setters
|
|
17164
|
+
]);
|
|
16773
17165
|
}
|
|
17166
|
+
//#endregion
|
|
17167
|
+
//#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
|
|
17168
|
+
const eventRegistrationWizardDeps = {
|
|
17169
|
+
usePortalAuth,
|
|
17170
|
+
useEligibility,
|
|
17171
|
+
useExistingEventRegistration,
|
|
17172
|
+
useWaitlistClaim,
|
|
17173
|
+
useEventRegistrationStripeReturn,
|
|
17174
|
+
useEventRegistrationSubmit,
|
|
17175
|
+
useDiscountCodeUi
|
|
17176
|
+
};
|
|
16774
17177
|
function useEventRegistrationWizard(options) {
|
|
16775
17178
|
return useEventRegistrationWizardWithDeps(options, eventRegistrationWizardDeps);
|
|
16776
17179
|
}
|
|
16777
17180
|
function useEventRegistrationWizardWithDeps(options, deps) {
|
|
16778
17181
|
const api = useBlockApi();
|
|
16779
|
-
const registrationEvents = useMemo(() => toRegistrationEvents(options.events ?? []), [options.events]);
|
|
17182
|
+
const registrationEvents = useMemo(() => [...toRegistrationEvents(options.events ?? []), ...toWholeSeriesRegistrationEvents(options.wholeSeriesOfferings ?? [])], [options.events, options.wholeSeriesOfferings]);
|
|
16780
17183
|
const scopedEvents = useMemo(() => {
|
|
16781
17184
|
return resolveEventRegistrationScopedEvents(registrationEvents, {
|
|
16782
17185
|
occurrenceContext: options.occurrenceContext,
|
|
@@ -16806,15 +17209,15 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
16806
17209
|
const [selectedTicketLines, setSelectedTicketLines] = useState([]);
|
|
16807
17210
|
const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState(() => {
|
|
16808
17211
|
const slidingScale = getSlidingScaleForEvent(preSelectedEvent ?? null);
|
|
16809
|
-
return slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput
|
|
17212
|
+
return slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : "";
|
|
16810
17213
|
});
|
|
16811
17214
|
const [registrationResult, setRegistrationResult] = useState(null);
|
|
16812
17215
|
const [errorMessage, setErrorMessage] = useState("");
|
|
16813
17216
|
const [altchaSolution, setAltchaSolution] = useState(null);
|
|
16814
|
-
const { authState: portalAuthState, profile: portalProfile
|
|
17217
|
+
const { authState: portalAuthState, profile: portalProfile } = deps.usePortalAuth();
|
|
16815
17218
|
const waitlistClaim = deps.useWaitlistClaim();
|
|
16816
17219
|
const [showMagicLinkModal, setShowMagicLinkModal] = useState(false);
|
|
16817
|
-
const [
|
|
17220
|
+
const [pendingRegistrationReference, setPendingRegistrationReference] = useState(null);
|
|
16818
17221
|
const [paymentStepState, setPaymentStepState] = useState({
|
|
16819
17222
|
status: "loading",
|
|
16820
17223
|
canContinue: false,
|
|
@@ -16835,7 +17238,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
16835
17238
|
occurrenceContext: options.occurrenceContext,
|
|
16836
17239
|
selectedEvent
|
|
16837
17240
|
}), [options.occurrenceContext, selectedEvent]);
|
|
16838
|
-
const
|
|
17241
|
+
const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
|
|
16839
17242
|
const currentEvent = selectedEvent ?? preSelectedEvent;
|
|
16840
17243
|
const currentEventPricing = currentEvent ? resolveRuntimeEventPricing(currentEvent) : null;
|
|
16841
17244
|
const currentEventUsesTicketTypes = currentEventPricing !== null && publicEventPricingMode(currentEventPricing) === "ticket_types";
|
|
@@ -16851,11 +17254,9 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
16851
17254
|
const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
|
|
16852
17255
|
const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
|
|
16853
17256
|
const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
|
|
17257
|
+
const claimedTicketSelections = useMemo(() => resolveClaimedTicketSelections(waitlistClaim.claim), [waitlistClaim.claim]);
|
|
16854
17258
|
const ticketSelections = useMemo(() => {
|
|
16855
|
-
if (
|
|
16856
|
-
ticketTypeId: null,
|
|
16857
|
-
quantity: 1
|
|
16858
|
-
}];
|
|
17259
|
+
if (claimedTicketSelections) return [...claimedTicketSelections];
|
|
16859
17260
|
if (usesTicketTypeSelections) return normalizedSelectedTicketLines;
|
|
16860
17261
|
return [{
|
|
16861
17262
|
ticketTypeId: null,
|
|
@@ -16865,7 +17266,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
16865
17266
|
normalizedSelectedTicketLines,
|
|
16866
17267
|
ticketsCount,
|
|
16867
17268
|
usesTicketTypeSelections,
|
|
16868
|
-
|
|
17269
|
+
claimedTicketSelections
|
|
16869
17270
|
]);
|
|
16870
17271
|
useEffect(() => {
|
|
16871
17272
|
if (flowState.ticketsCount === ticketsCount) return;
|
|
@@ -16875,20 +17276,22 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
16875
17276
|
});
|
|
16876
17277
|
}, [flowState.ticketsCount, ticketsCount]);
|
|
16877
17278
|
const eligibilityResult = deps.useEligibility({
|
|
16878
|
-
enabled: portalAuthState
|
|
16879
|
-
|
|
17279
|
+
enabled: shouldLoadRegistrationOptions(portalAuthState, step),
|
|
17280
|
+
subject: registrationTarget?.subject ?? null,
|
|
16880
17281
|
attendanceMode: selectedAttendanceMode,
|
|
16881
17282
|
ticketSelections,
|
|
16882
|
-
selectedSlidingAmount: parseCurrencyInputToCents
|
|
16883
|
-
|
|
17283
|
+
selectedSlidingAmount: parseCurrencyInputToCents(selectedSlidingAmountInput),
|
|
17284
|
+
subjectEmail: getPortalSubjectEmail(portalProfile)
|
|
16884
17285
|
});
|
|
16885
17286
|
const existingRegistrationResult = deps.useExistingEventRegistration({
|
|
16886
17287
|
isAuthenticated: portalAuthState === "authenticated",
|
|
16887
|
-
occurrenceId
|
|
17288
|
+
occurrenceId: registrationOccurrenceId
|
|
16888
17289
|
});
|
|
16889
17290
|
const eligibility = eligibilityResult.eligibility;
|
|
16890
17291
|
const eligibilityLoading = eligibilityResult.isLoading;
|
|
16891
17292
|
const eligibilityError = eligibilityResult.error;
|
|
17293
|
+
const portalCreditState = eligibilityResult.creditState;
|
|
17294
|
+
const registrationState = eligibility?.registration ?? { kind: "none" };
|
|
16892
17295
|
const setStep = useCallback((nextStep) => {
|
|
16893
17296
|
dispatchFlow({
|
|
16894
17297
|
type: "set-step",
|
|
@@ -16898,43 +17301,29 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
16898
17301
|
const setTicketsCount = useCallback((nextTicketsCount) => {
|
|
16899
17302
|
dispatchFlow({
|
|
16900
17303
|
type: "set-tickets-count",
|
|
16901
|
-
ticketsCount: waitlistClaim.claim
|
|
17304
|
+
ticketsCount: resolveClaimTicketCount(waitlistClaim.claim, nextTicketsCount)
|
|
16902
17305
|
});
|
|
16903
17306
|
}, [waitlistClaim.claim]);
|
|
16904
|
-
|
|
16905
|
-
|
|
16906
|
-
|
|
16907
|
-
|
|
16908
|
-
|
|
16909
|
-
|
|
16910
|
-
|
|
16911
|
-
|
|
16912
|
-
return;
|
|
16913
|
-
}
|
|
16914
|
-
if (matchedEvent) setSelectedEvent(matchedEvent);
|
|
16915
|
-
setSelectedAttendanceMode(claim.subject.attendanceMode);
|
|
16916
|
-
dispatchFlow({
|
|
17307
|
+
const waitlistRestorationSetters = useMemo(() => ({
|
|
17308
|
+
setErrorMessage,
|
|
17309
|
+
setStep,
|
|
17310
|
+
setSelectedEvent,
|
|
17311
|
+
setAttendanceMode: setSelectedAttendanceMode,
|
|
17312
|
+
setTicketSelections: setSelectedTicketLines,
|
|
17313
|
+
setSlidingAmountInput: setSelectedSlidingAmountInput,
|
|
17314
|
+
setTicketsCount: (count) => dispatchFlow({
|
|
16917
17315
|
type: "set-tickets-count",
|
|
16918
|
-
ticketsCount:
|
|
16919
|
-
})
|
|
16920
|
-
setFormData
|
|
16921
|
-
|
|
16922
|
-
|
|
16923
|
-
|
|
16924
|
-
|
|
16925
|
-
notes: claim.prefill.notes ?? ""
|
|
16926
|
-
}));
|
|
16927
|
-
setGuests(claim.prefill.guests.map((guest) => ({
|
|
16928
|
-
name: guest.name,
|
|
16929
|
-
email: guest.email ?? "",
|
|
16930
|
-
phone: guest.phone ?? ""
|
|
16931
|
-
})));
|
|
16932
|
-
}, [
|
|
16933
|
-
waitlistClaim.claim,
|
|
17316
|
+
ticketsCount: count
|
|
17317
|
+
}),
|
|
17318
|
+
setFormData,
|
|
17319
|
+
setGuests
|
|
17320
|
+
}), [setStep]);
|
|
17321
|
+
useWaitlistClaimRestoration({
|
|
17322
|
+
claim: waitlistClaim.claim,
|
|
16934
17323
|
scopedEvents,
|
|
16935
|
-
options.occurrenceContext?.id,
|
|
16936
|
-
|
|
16937
|
-
|
|
17324
|
+
occurrenceContextId: options.occurrenceContext?.id,
|
|
17325
|
+
setters: waitlistRestorationSetters
|
|
17326
|
+
});
|
|
16938
17327
|
useEffect(() => {
|
|
16939
17328
|
if (waitlistClaim.requiresPortalLogin) return;
|
|
16940
17329
|
if (!waitlistClaim.error) return;
|
|
@@ -16990,9 +17379,9 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
16990
17379
|
const verification = deps.useEventRegistrationStripeReturn({
|
|
16991
17380
|
api,
|
|
16992
17381
|
events: registrationEvents,
|
|
16993
|
-
|
|
17382
|
+
registrationSubject: registrationTarget?.subject ?? null,
|
|
16994
17383
|
step,
|
|
16995
|
-
|
|
17384
|
+
pendingRegistrationReference,
|
|
16996
17385
|
setFormData,
|
|
16997
17386
|
setTicketsCount,
|
|
16998
17387
|
setSelectedEvent,
|
|
@@ -17002,7 +17391,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17002
17391
|
type: "set-manual-payment-selection",
|
|
17003
17392
|
selection
|
|
17004
17393
|
}),
|
|
17005
|
-
|
|
17394
|
+
setPendingRegistrationReference,
|
|
17006
17395
|
setStep,
|
|
17007
17396
|
setRegistrationResult: (result) => setRegistrationResult(result),
|
|
17008
17397
|
setErrorMessage
|
|
@@ -17031,7 +17420,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17031
17420
|
selectedAttendanceMode,
|
|
17032
17421
|
singleSelectedTicketTypeId
|
|
17033
17422
|
]);
|
|
17034
|
-
const selectedSlidingAmount = useMemo(() => parseCurrencyInputToCents
|
|
17423
|
+
const selectedSlidingAmount = useMemo(() => parseCurrencyInputToCents(selectedSlidingAmountInput), [selectedSlidingAmountInput]);
|
|
17035
17424
|
const selectedEventSlidingScale = useMemo(() => getSlidingScaleForEvent(selectedEvent ?? preSelectedEvent), [selectedEvent, preSelectedEvent]);
|
|
17036
17425
|
const slidingScaleSelectionMessage = getSlidingScaleSelectionMessage({
|
|
17037
17426
|
slidingScale: selectedEventSlidingScale,
|
|
@@ -17277,7 +17666,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17277
17666
|
guests,
|
|
17278
17667
|
discountCode: discountUi.discountCode,
|
|
17279
17668
|
claimToken: waitlistClaim.token,
|
|
17280
|
-
|
|
17669
|
+
setPendingRegistrationReference,
|
|
17281
17670
|
setStep,
|
|
17282
17671
|
setRegistrationResult: (result) => setRegistrationResult(result),
|
|
17283
17672
|
setErrorMessage
|
|
@@ -17289,7 +17678,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17289
17678
|
consentAccepted: false
|
|
17290
17679
|
}));
|
|
17291
17680
|
const slidingScale = getSlidingScaleForEvent(event);
|
|
17292
|
-
setSelectedSlidingAmountInput(slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput
|
|
17681
|
+
setSelectedSlidingAmountInput(slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : "");
|
|
17293
17682
|
setSelectedAttendanceMode((event.deliveryMode ?? "in_person") === "hybrid" ? null : (event.deliveryMode ?? "in_person") === "online" ? "online" : "in_person");
|
|
17294
17683
|
setSelectedTicketLines([]);
|
|
17295
17684
|
dispatchFlow({
|
|
@@ -17306,7 +17695,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17306
17695
|
setSelectedSlidingAmountInput("");
|
|
17307
17696
|
setSelectedAttendanceMode(preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null);
|
|
17308
17697
|
setErrorMessage("");
|
|
17309
|
-
|
|
17698
|
+
setPendingRegistrationReference(null);
|
|
17310
17699
|
};
|
|
17311
17700
|
const handlePaymentStepStateChange = useCallback((state) => {
|
|
17312
17701
|
setPaymentStepState(state);
|
|
@@ -17317,9 +17706,12 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17317
17706
|
selection
|
|
17318
17707
|
});
|
|
17319
17708
|
}, []);
|
|
17320
|
-
const hasEligibility
|
|
17321
|
-
|
|
17322
|
-
|
|
17709
|
+
const { hasEligibility, hasMembershipEligibility, isMembershipFastTrack } = getEligibilityFlowFlags({
|
|
17710
|
+
eligibility,
|
|
17711
|
+
portalAuthState,
|
|
17712
|
+
ticketsCount,
|
|
17713
|
+
paymentMethod: paymentSelection.method
|
|
17714
|
+
});
|
|
17323
17715
|
return {
|
|
17324
17716
|
api,
|
|
17325
17717
|
anchorId: options.anchorId,
|
|
@@ -17327,7 +17719,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17327
17719
|
registrationTarget,
|
|
17328
17720
|
subject: options.subject,
|
|
17329
17721
|
events: options.events,
|
|
17330
|
-
maxTicketsNum: waitlistClaim.claim
|
|
17722
|
+
maxTicketsNum: resolveClaimTicketCount(waitlistClaim.claim, options.maxTicketsNum),
|
|
17331
17723
|
scopedEvents,
|
|
17332
17724
|
preSelectedEvent,
|
|
17333
17725
|
hasPreSelectedContext,
|
|
@@ -17341,7 +17733,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17341
17733
|
setSelectedAttendanceMode,
|
|
17342
17734
|
ticketSelections,
|
|
17343
17735
|
selectedTicketLines: normalizedSelectedTicketLines,
|
|
17344
|
-
setSelectedTicketLines: (lines) =>
|
|
17736
|
+
setSelectedTicketLines: (lines) => {
|
|
17737
|
+
if (waitlistClaim.claim) return;
|
|
17738
|
+
setSelectedTicketLines(normalizeTicketSelectionLines(lines));
|
|
17739
|
+
},
|
|
17345
17740
|
selectedSlidingAmountInput,
|
|
17346
17741
|
setSelectedSlidingAmountInput,
|
|
17347
17742
|
selectedSlidingAmount,
|
|
@@ -17382,8 +17777,9 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17382
17777
|
eligibilityLoading,
|
|
17383
17778
|
eligibilityError,
|
|
17384
17779
|
existingRegistration: existingRegistrationResult.registration,
|
|
17385
|
-
existingRegistrationLoading: existingRegistrationResult.isLoading,
|
|
17780
|
+
existingRegistrationLoading: existingRegistrationResult.isLoading || portalAuthState === "authenticated" && eligibilityLoading,
|
|
17386
17781
|
existingRegistrationState: existingRegistrationResult.state,
|
|
17782
|
+
registrationState,
|
|
17387
17783
|
hasEligibility,
|
|
17388
17784
|
hasMembershipEligibility,
|
|
17389
17785
|
requireGuestDetails,
|
|
@@ -17408,85 +17804,6 @@ function useEventRegistrationWizardWithDeps(options, deps) {
|
|
|
17408
17804
|
};
|
|
17409
17805
|
}
|
|
17410
17806
|
//#endregion
|
|
17411
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.ts
|
|
17412
|
-
const DEFAULT_EVENT_DIRECT_PAYMENT_OPTION = { kind: "upfront" };
|
|
17413
|
-
function buildEventRegistrationPaymentOptionsViewModel(input) {
|
|
17414
|
-
const supportedOptions = selectSupportedEventDirectPaymentOptions(input.paymentTerms);
|
|
17415
|
-
const selection = buildBookingPaymentSelectionViewModel({
|
|
17416
|
-
serviceTitle: input.eventTitle,
|
|
17417
|
-
paymentTerms: { allowedOptions: [...supportedOptions] },
|
|
17418
|
-
priceAmount: input.totalPriceCents,
|
|
17419
|
-
priceCurrency: input.currency,
|
|
17420
|
-
bookingStartAt: input.startsAt,
|
|
17421
|
-
locale: input.locale
|
|
17422
|
-
});
|
|
17423
|
-
return {
|
|
17424
|
-
mode: selection.mode,
|
|
17425
|
-
sectionTitle: selection.sectionTitle,
|
|
17426
|
-
options: selection.options.map((option, index) => toEventDirectPaymentOption(option, supportedOptions[index] ?? DEFAULT_EVENT_DIRECT_PAYMENT_OPTION, selection.mode, input.totalPriceCents))
|
|
17427
|
-
};
|
|
17428
|
-
}
|
|
17429
|
-
function selectSupportedEventDirectPaymentOptions(paymentTerms) {
|
|
17430
|
-
const supported = paymentTerms?.allowedOptions.filter(isSupportedEventDirectPaymentOption) ?? [];
|
|
17431
|
-
return supported.length > 0 ? supported : [DEFAULT_EVENT_DIRECT_PAYMENT_OPTION];
|
|
17432
|
-
}
|
|
17433
|
-
function isSupportedEventDirectPaymentOption(option) {
|
|
17434
|
-
return option.kind === "upfront" || option.kind === "flexible_balance";
|
|
17435
|
-
}
|
|
17436
|
-
function toEventDirectPaymentOption(option, sourceOption, mode, totalCents) {
|
|
17437
|
-
switch (option.kind) {
|
|
17438
|
-
case "upfront": return {
|
|
17439
|
-
...option,
|
|
17440
|
-
kind: "upfront",
|
|
17441
|
-
label: mode === "choice_required" ? "Pay in full now" : "Pay by card",
|
|
17442
|
-
totalCents,
|
|
17443
|
-
configuredPaymentDueNowCents: totalCents
|
|
17444
|
-
};
|
|
17445
|
-
case "flexible_balance": return {
|
|
17446
|
-
...option,
|
|
17447
|
-
kind: "flexible_balance",
|
|
17448
|
-
label: "Pay deposit now",
|
|
17449
|
-
totalCents,
|
|
17450
|
-
configuredPaymentDueNowCents: sourceOption.kind === "flexible_balance" ? resolveFlexibleBalanceInitialPaymentCents({
|
|
17451
|
-
totalAmountCents: totalCents,
|
|
17452
|
-
config: sourceOption.config
|
|
17453
|
-
}) : totalCents
|
|
17454
|
-
};
|
|
17455
|
-
case "deferred_manual":
|
|
17456
|
-
case "instalment_plan": throw new Error(`Unsupported event registration payment option: ${option.kind}`);
|
|
17457
|
-
}
|
|
17458
|
-
}
|
|
17459
|
-
function resolveEventRegistrationDirectPaymentSelection(input) {
|
|
17460
|
-
if (input.selection.method !== "stripe") return { kind: "not-stripe" };
|
|
17461
|
-
const fallbackOption = input.options[0];
|
|
17462
|
-
if (!fallbackOption) return { kind: "unavailable" };
|
|
17463
|
-
const requestedKind = input.selection.collectionOptionKind;
|
|
17464
|
-
const selectedOption = requestedKind == null ? input.options.find((option) => option.kind === "upfront") : input.options.find((option) => option.kind === requestedKind);
|
|
17465
|
-
if (selectedOption) return {
|
|
17466
|
-
kind: "valid",
|
|
17467
|
-
selection: {
|
|
17468
|
-
method: "stripe",
|
|
17469
|
-
collectionOptionKind: selectedOption.kind
|
|
17470
|
-
}
|
|
17471
|
-
};
|
|
17472
|
-
return {
|
|
17473
|
-
kind: "invalid",
|
|
17474
|
-
fallbackSelection: {
|
|
17475
|
-
method: "stripe",
|
|
17476
|
-
collectionOptionKind: fallbackOption.kind
|
|
17477
|
-
}
|
|
17478
|
-
};
|
|
17479
|
-
}
|
|
17480
|
-
function normalizeEventRegistrationDirectPaymentSelection(input) {
|
|
17481
|
-
const selectionState = resolveEventRegistrationDirectPaymentSelection(input);
|
|
17482
|
-
switch (selectionState.kind) {
|
|
17483
|
-
case "valid": return selectionState.selection;
|
|
17484
|
-
case "invalid": return selectionState.fallbackSelection;
|
|
17485
|
-
case "not-stripe":
|
|
17486
|
-
case "unavailable": return input.selection;
|
|
17487
|
-
}
|
|
17488
|
-
}
|
|
17489
|
-
//#endregion
|
|
17490
17807
|
//#region ../blocks/src/system/runtime/hooks/useHeadlessEventRegistrationFlow.ts
|
|
17491
17808
|
const eventRegistrationControllerDeps = { useEventRegistrationWizard };
|
|
17492
17809
|
function HeadlessEventRegistrationProvider$1({ config, children }) {
|
|
@@ -17776,1338 +18093,30 @@ function resolveHeadlessDirectPaymentOptions(wizard) {
|
|
|
17776
18093
|
const event = wizard.selectedEvent ?? wizard.preSelectedEvent;
|
|
17777
18094
|
return buildEventRegistrationPaymentOptionsViewModel({
|
|
17778
18095
|
eventTitle: event?.title ?? "Event",
|
|
17779
|
-
|
|
18096
|
+
approvedPaymentOptions: eligibility.paymentOptions,
|
|
18097
|
+
paymentTerms: eligibility.paymentTerms,
|
|
17780
18098
|
totalPriceCents: eligibility.price,
|
|
17781
18099
|
currency: eligibility.currency,
|
|
17782
18100
|
startsAt: wizard.occurrenceContext?.startsAt ?? event?.startsAt
|
|
17783
18101
|
}).options;
|
|
17784
18102
|
}
|
|
17785
18103
|
//#endregion
|
|
17786
|
-
//#region ../blocks/src/system/runtime/
|
|
17787
|
-
|
|
17788
|
-
|
|
17789
|
-
|
|
17790
|
-
|
|
17791
|
-
|
|
17792
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/pricing.ts
|
|
17793
|
-
function parseCurrencyInputToCents(value) {
|
|
17794
|
-
const trimmed = value.trim();
|
|
17795
|
-
if (!trimmed) return null;
|
|
17796
|
-
const amount = Number(trimmed);
|
|
17797
|
-
if (!Number.isFinite(amount) || amount < 0) return null;
|
|
17798
|
-
return Math.round(amount * 100);
|
|
17799
|
-
}
|
|
17800
|
-
function formatCentsAsCurrencyInput(amount) {
|
|
17801
|
-
const major = amount / 100;
|
|
17802
|
-
return Number.isInteger(major) ? String(major) : major.toFixed(2);
|
|
17803
|
-
}
|
|
17804
|
-
function getMissingWholeSeriesPricingSelectionMessage(pricing) {
|
|
17805
|
-
if (pricing?.requiresSelection && !pricing.selectedOption) return pricing.slidingScale ? "Choose an amount to continue." : "Choose a pricing option to continue.";
|
|
17806
|
-
const selectedAmount = pricing?.selectedSlidingAmount;
|
|
17807
|
-
const scale = pricing?.slidingScale;
|
|
17808
|
-
if (scale && selectedAmount !== null && selectedAmount !== void 0 && (selectedAmount < scale.minAmount || selectedAmount > scale.maxAmount)) return "Choose an amount within the sliding scale.";
|
|
17809
|
-
return null;
|
|
17810
|
-
}
|
|
17811
|
-
function buildWholeSeriesPricingOptionPayload(pricing) {
|
|
17812
|
-
if (pricing?.selectedOption) return { pricingOptionId: pricing.selectedOption.id };
|
|
17813
|
-
if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null) return { selectedSlidingAmount: pricing.selectedSlidingAmount };
|
|
17814
|
-
return {};
|
|
17815
|
-
}
|
|
17816
|
-
function defaultWholeSeriesPricingSelection(pricing, previousOptionId) {
|
|
17817
|
-
return {
|
|
17818
|
-
pricingOptionId: previousOptionId && pricing.selectableOptions.some((option) => option.id === previousOptionId) ? previousOptionId : pricing.selectedOption?.id ?? null,
|
|
17819
|
-
slidingAmountInput: pricing.slidingScale?.suggestedAmount !== null && pricing.slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(pricing.slidingScale.suggestedAmount) : ""
|
|
17820
|
-
};
|
|
17821
|
-
}
|
|
17822
|
-
//#endregion
|
|
17823
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/wizardSteps.ts
|
|
17824
|
-
/**
|
|
17825
|
-
* Step labels for the wizard indicator
|
|
17826
|
-
*/
|
|
17827
|
-
const STEP_LABELS = {
|
|
17828
|
-
"select-run": "Run",
|
|
17829
|
-
"enter-details": "Details",
|
|
17830
|
-
"booking-mode": "Method",
|
|
17831
|
-
"select-payment": "Payment",
|
|
17832
|
-
submitting: "Booking",
|
|
17833
|
-
redirecting: "Redirecting",
|
|
17834
|
-
"verifying-payment": "Verifying",
|
|
17835
|
-
"verifying-timeout": "Timeout",
|
|
17836
|
-
"payment-failed": "Failed",
|
|
17837
|
-
success: "Complete",
|
|
17838
|
-
waitlist: "Waitlist",
|
|
17839
|
-
error: "Error"
|
|
17840
|
-
};
|
|
17841
|
-
/**
|
|
17842
|
-
* Determine which wizard steps to show based on context and eligibility.
|
|
17843
|
-
*
|
|
17844
|
-
* @param hasPreSelectedRun - Whether run is pre-selected (skips run selection)
|
|
17845
|
-
* @param requiresPayment - Whether the run requires payment
|
|
17846
|
-
* @param hasEligibleMemberships - Whether user has eligible memberships
|
|
17847
|
-
* @param bookingMode - Current booking mode selection
|
|
17848
|
-
* @param isMembershipFastTrack - Whether user qualifies for single-step membership flow
|
|
17849
|
-
* @returns Array of wizard steps to display
|
|
17850
|
-
*/
|
|
17851
|
-
function getWizardStepsForContext(hasPreSelectedRun, requiresPayment, hasEligibleMemberships, bookingMode, isMembershipFastTrack) {
|
|
17852
|
-
if (isMembershipFastTrack) return hasPreSelectedRun ? ["enter-details"] : ["select-run", "enter-details"];
|
|
17853
|
-
if (!requiresPayment) return hasPreSelectedRun ? ["enter-details"] : ["select-run", "enter-details"];
|
|
17854
|
-
if (hasEligibleMemberships) {
|
|
17855
|
-
const skipPayment = bookingMode === "membership";
|
|
17856
|
-
if (hasPreSelectedRun) return skipPayment ? ["enter-details", "booking-mode"] : [
|
|
17857
|
-
"enter-details",
|
|
17858
|
-
"booking-mode",
|
|
17859
|
-
"select-payment"
|
|
17860
|
-
];
|
|
17861
|
-
return skipPayment ? [
|
|
17862
|
-
"select-run",
|
|
17863
|
-
"enter-details",
|
|
17864
|
-
"booking-mode"
|
|
17865
|
-
] : [
|
|
17866
|
-
"select-run",
|
|
17867
|
-
"enter-details",
|
|
17868
|
-
"booking-mode",
|
|
17869
|
-
"select-payment"
|
|
17870
|
-
];
|
|
17871
|
-
}
|
|
17872
|
-
return hasPreSelectedRun ? ["enter-details", "select-payment"] : [
|
|
17873
|
-
"select-run",
|
|
17874
|
-
"enter-details",
|
|
17875
|
-
"select-payment"
|
|
17876
|
-
];
|
|
17877
|
-
}
|
|
17878
|
-
/**
|
|
17879
|
-
* Get labels for a list of wizard steps
|
|
17880
|
-
*/
|
|
17881
|
-
function getStepLabels(steps) {
|
|
17882
|
-
return steps.map((step) => STEP_LABELS[step] ?? step);
|
|
17883
|
-
}
|
|
17884
|
-
//#endregion
|
|
17885
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/wholeSeriesRegistrationViewState.ts
|
|
17886
|
-
function deriveWholeSeriesRegistrationViewState(input) {
|
|
17887
|
-
const hasRunPayment = resolveWholeSeriesPaymentRequirement(input.pricing);
|
|
17888
|
-
const canUseMembership = hasRunPayment && input.selectedRun?.acceptsMemberships === true && input.portalAuthState === "authenticated" && input.eligibleMembershipCount > 0;
|
|
17889
|
-
const hasPreSelectedRun = input.scopedRuns.length === 1;
|
|
17890
|
-
const fastTrack = canUseMembership && input.eligibleMembershipCount === 1 && input.bookingMode === "membership";
|
|
17891
|
-
const wizardSteps = getWizardStepsForContext(hasPreSelectedRun, hasRunPayment, canUseMembership, input.bookingMode, fastTrack);
|
|
17892
|
-
const showPortalAuthSidebar = shouldShowPortalAuthSidebar({
|
|
17893
|
-
...input,
|
|
17894
|
-
hasRunPayment
|
|
17895
|
-
});
|
|
18104
|
+
//#region ../blocks/src/system/runtime/hooks/useBookingFormConfig.state.ts
|
|
18105
|
+
const EMPTY_SNAPSHOT = Object.freeze({
|
|
18106
|
+
formConfig: null,
|
|
18107
|
+
services: []
|
|
18108
|
+
});
|
|
18109
|
+
function createInitialBookingFormConfigState() {
|
|
17896
18110
|
return {
|
|
17897
|
-
|
|
17898
|
-
|
|
17899
|
-
hasPreSelectedRun,
|
|
17900
|
-
wizardSteps,
|
|
17901
|
-
currentStepNumber: getStepNumber(input.step, wizardSteps),
|
|
17902
|
-
totalSteps: wizardSteps.length,
|
|
17903
|
-
stepLabels: getStepLabels(wizardSteps),
|
|
17904
|
-
showPortalAuthSidebar
|
|
18111
|
+
tag: "loading",
|
|
18112
|
+
previous: EMPTY_SNAPSHOT
|
|
17905
18113
|
};
|
|
17906
18114
|
}
|
|
17907
|
-
function
|
|
17908
|
-
|
|
17909
|
-
|
|
17910
|
-
|
|
17911
|
-
|
|
17912
|
-
if (input.portalAuthState !== "unauthenticated") return false;
|
|
17913
|
-
if (input.step === "success" || input.step === "waitlist" || input.step === "error") return false;
|
|
17914
|
-
return input.waitlistRequiresPortalLogin || input.hasRunPayment && input.selectedRun?.acceptsMemberships === true && input.step !== "select-run";
|
|
17915
|
-
}
|
|
17916
|
-
//#endregion
|
|
17917
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesEligibility.ts
|
|
17918
|
-
function shouldFetchEligibility(input) {
|
|
17919
|
-
if (!input.run || input.portalAuthState === "checking" || input.hasWaitlistClaimToken) return false;
|
|
17920
|
-
const membershipCheck = input.portalAuthState === "authenticated" && input.hasPaidSelection && input.run.acceptsMemberships;
|
|
17921
|
-
const capacityCheck = input.run.availableSpots !== null && input.run.availableSpots <= 0;
|
|
17922
|
-
return membershipCheck || capacityCheck;
|
|
17923
|
-
}
|
|
17924
|
-
function useWholeSeriesEligibility(input) {
|
|
17925
|
-
const [loading, setLoading] = useState(false);
|
|
17926
|
-
const [error, setError] = useState(null);
|
|
17927
|
-
const [eligibility, setEligibility] = useState(null);
|
|
17928
|
-
const [memberships, setMemberships] = useState([]);
|
|
17929
|
-
const [paymentChoice, setPaymentChoice] = useState("checkout");
|
|
17930
|
-
const [selectedMembershipId, setSelectedMembershipId] = useState(null);
|
|
17931
|
-
const choosePaymentChoice = useCallback((choice) => {
|
|
17932
|
-
setPaymentChoice(choice);
|
|
17933
|
-
}, []);
|
|
17934
|
-
const chooseMembership = useCallback((membershipId) => {
|
|
17935
|
-
setSelectedMembershipId(membershipId);
|
|
17936
|
-
}, []);
|
|
17937
|
-
useEffect(() => {
|
|
17938
|
-
let cancelled = false;
|
|
17939
|
-
setEligibility(null);
|
|
17940
|
-
setMemberships([]);
|
|
17941
|
-
setSelectedMembershipId(null);
|
|
17942
|
-
setError(null);
|
|
17943
|
-
setPaymentChoice("checkout");
|
|
17944
|
-
const eligibilityInput = {
|
|
17945
|
-
run: input.selectedRun,
|
|
17946
|
-
hasPaidSelection: input.hasPaidSelection,
|
|
17947
|
-
portalAuthState: input.portalAuthState,
|
|
17948
|
-
hasWaitlistClaimToken: input.waitlistClaimToken !== null
|
|
17949
|
-
};
|
|
17950
|
-
if (!shouldFetchEligibility(eligibilityInput)) return;
|
|
17951
|
-
const run = eligibilityInput.run;
|
|
17952
|
-
setLoading(true);
|
|
17953
|
-
input.api.checkWholeSeriesEligibility({ eventSeriesId: run.eventSeriesId }).then((result) => {
|
|
17954
|
-
if (cancelled) return;
|
|
17955
|
-
const eligibleMemberships = result.eligibleMemberships ?? [];
|
|
17956
|
-
setEligibility(result);
|
|
17957
|
-
setMemberships(eligibleMemberships);
|
|
17958
|
-
if (input.portalAuthState === "authenticated" && eligibleMemberships.length > 0) {
|
|
17959
|
-
setPaymentChoice("membership");
|
|
17960
|
-
if (eligibleMemberships.length === 1) setSelectedMembershipId(eligibleMemberships[0]?.customerMembershipId ?? null);
|
|
17961
|
-
}
|
|
17962
|
-
}).catch((cause) => {
|
|
17963
|
-
if (!cancelled) setError(cause instanceof Error ? cause.message : "Failed to check membership eligibility");
|
|
17964
|
-
}).finally(() => {
|
|
17965
|
-
if (!cancelled) setLoading(false);
|
|
17966
|
-
});
|
|
17967
|
-
return () => {
|
|
17968
|
-
cancelled = true;
|
|
17969
|
-
};
|
|
17970
|
-
}, [
|
|
17971
|
-
input.api,
|
|
17972
|
-
input.hasPaidSelection,
|
|
17973
|
-
input.portalAuthState,
|
|
17974
|
-
input.selectedRun,
|
|
17975
|
-
input.waitlistClaimToken
|
|
17976
|
-
]);
|
|
17977
|
-
return {
|
|
17978
|
-
eligibilityLoading: loading,
|
|
17979
|
-
eligibilityError: error,
|
|
17980
|
-
runEligibility: eligibility,
|
|
17981
|
-
eligibleMemberships: memberships,
|
|
17982
|
-
paymentChoice,
|
|
17983
|
-
choosePaymentChoice,
|
|
17984
|
-
selectedMembershipId,
|
|
17985
|
-
chooseMembership
|
|
17986
|
-
};
|
|
17987
|
-
}
|
|
17988
|
-
//#endregion
|
|
17989
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/wholeSeriesPageSurfaceScope.ts
|
|
17990
|
-
/**
|
|
17991
|
-
* Resolves native run-page ownership without falling back to entry or slug
|
|
17992
|
-
* coincidence when a page-surface subject is present but invalid.
|
|
17993
|
-
*/
|
|
17994
|
-
function resolveWholeSeriesPageSurfaceScope(runs, subjectValue) {
|
|
17995
|
-
if (subjectValue === null || subjectValue === void 0) return { kind: "absent" };
|
|
17996
|
-
const parsed = parseEventPageSurfaceSubject(subjectValue);
|
|
17997
|
-
if (!parsed.ok) return {
|
|
17998
|
-
kind: "unsupported",
|
|
17999
|
-
reason: parsed.error.kind
|
|
18000
|
-
};
|
|
18001
|
-
const seriesIds = eventSeriesIdsForSubject(parsed.value);
|
|
18002
|
-
const allowedSeriesIds = new Set(seriesIds);
|
|
18003
|
-
return {
|
|
18004
|
-
kind: "scoped",
|
|
18005
|
-
subject: parsed.value,
|
|
18006
|
-
runs: runs.filter((run) => allowedSeriesIds.has(run.eventSeriesId))
|
|
18007
|
-
};
|
|
18008
|
-
}
|
|
18009
|
-
function eventSeriesIdsForSubject(subject) {
|
|
18010
|
-
switch (subject.kind) {
|
|
18011
|
-
case "eventSeries": return [subject.eventSeriesId];
|
|
18012
|
-
case "eventOffering": return subject.availableEventSeriesIds;
|
|
18013
|
-
default: return assertNever$3(subject);
|
|
18014
|
-
}
|
|
18015
|
-
}
|
|
18016
|
-
//#endregion
|
|
18017
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationSelection.ts
|
|
18018
|
-
function selectScopedRuns(props) {
|
|
18019
|
-
const surfaceScope = resolveWholeSeriesPageSurfaceScope(props.runs ?? [], props.subject);
|
|
18020
|
-
if (surfaceScope.kind === "unsupported") return [];
|
|
18021
|
-
if (surfaceScope.kind === "scoped") return surfaceScope.runs;
|
|
18022
|
-
return [];
|
|
18023
|
-
}
|
|
18024
|
-
function getWholeSeriesCheckoutSessionId(location = window.location) {
|
|
18025
|
-
const fromSearch = new URLSearchParams(location.search).get("session_id");
|
|
18026
|
-
if (fromSearch) return fromSearch;
|
|
18027
|
-
return location.hash.match(/[?&]session_id=([^&]+)/)?.[1] ?? null;
|
|
18028
|
-
}
|
|
18029
|
-
function initialStep(runs, location) {
|
|
18030
|
-
if (new URLSearchParams(location.search).get("enrollment") === "success" && getWholeSeriesCheckoutSessionId(location)) return "verifying-payment";
|
|
18031
|
-
return runs.length === 1 ? "enter-details" : "select-run";
|
|
18032
|
-
}
|
|
18033
|
-
function useWholeSeriesRegistrationSelection(props, location = window.location) {
|
|
18034
|
-
const scopeSnapshot = JSON.stringify({
|
|
18035
|
-
runs: props.runs ?? [],
|
|
18036
|
-
subject: props.subject ?? null
|
|
18037
|
-
});
|
|
18038
|
-
const stableScope = useRef(null);
|
|
18039
|
-
if (stableScope.current?.snapshot !== scopeSnapshot) stableScope.current = {
|
|
18040
|
-
snapshot: scopeSnapshot,
|
|
18041
|
-
runs: selectScopedRuns(props)
|
|
18042
|
-
};
|
|
18043
|
-
const scopedRuns = stableScope.current.runs;
|
|
18044
|
-
const [step, setStep] = useState(() => initialStep(scopedRuns, location));
|
|
18045
|
-
const [selectedRunId, setSelectedRunId] = useState(scopedRuns.length === 1 ? scopedRuns[0]?.eventSeriesId ?? null : null);
|
|
18046
|
-
const selectedRun = useMemo(() => scopedRuns.find((run) => run.eventSeriesId === selectedRunId) ?? (scopedRuns.length === 1 ? scopedRuns[0] ?? null : null), [scopedRuns, selectedRunId]);
|
|
18047
|
-
const [selectedPricingOptionId, setSelectedPricingOptionId] = useState(null);
|
|
18048
|
-
const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState("");
|
|
18049
|
-
const goToStep = useCallback((nextStep) => {
|
|
18050
|
-
setStep(nextStep);
|
|
18051
|
-
}, []);
|
|
18052
|
-
const chooseRun = useCallback((run) => {
|
|
18053
|
-
setSelectedRunId(run.eventSeriesId);
|
|
18054
|
-
}, []);
|
|
18055
|
-
const choosePricingOption = useCallback((pricingOptionId) => {
|
|
18056
|
-
setSelectedPricingOptionId(pricingOptionId);
|
|
18057
|
-
}, []);
|
|
18058
|
-
const changeSlidingAmount = useCallback((amount) => {
|
|
18059
|
-
setSelectedSlidingAmountInput(amount);
|
|
18060
|
-
}, []);
|
|
18061
|
-
const selectedRunPricing = useMemo(() => selectedRun ? resolveWholeSeriesPricingState(selectedRun, selectedPricingOptionId, parseCurrencyInputToCents(selectedSlidingAmountInput)) : null, [
|
|
18062
|
-
selectedRun,
|
|
18063
|
-
selectedPricingOptionId,
|
|
18064
|
-
selectedSlidingAmountInput
|
|
18065
|
-
]);
|
|
18066
|
-
useEffect(() => {
|
|
18067
|
-
if (!selectedRun) {
|
|
18068
|
-
setSelectedPricingOptionId(null);
|
|
18069
|
-
setSelectedSlidingAmountInput("");
|
|
18070
|
-
return;
|
|
18071
|
-
}
|
|
18072
|
-
const selection = defaultWholeSeriesPricingSelection(resolveWholeSeriesPricingState(selectedRun, null), selectedPricingOptionId);
|
|
18073
|
-
setSelectedPricingOptionId(selection.pricingOptionId);
|
|
18074
|
-
setSelectedSlidingAmountInput(selection.slidingAmountInput);
|
|
18075
|
-
}, [selectedRun?.eventSeriesId]);
|
|
18076
|
-
return {
|
|
18077
|
-
scopedRuns,
|
|
18078
|
-
step,
|
|
18079
|
-
goToStep,
|
|
18080
|
-
selectedRun,
|
|
18081
|
-
chooseRun,
|
|
18082
|
-
selectedPricingOptionId,
|
|
18083
|
-
choosePricingOption,
|
|
18084
|
-
selectedSlidingAmountInput,
|
|
18085
|
-
changeSlidingAmount,
|
|
18086
|
-
selectedRunPricing
|
|
18087
|
-
};
|
|
18088
|
-
}
|
|
18089
|
-
//#endregion
|
|
18090
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesPaymentVerification.ts
|
|
18091
|
-
function applyTerminalStatus(status, setters) {
|
|
18092
|
-
if (status === "enrolled" || status === "completed") {
|
|
18093
|
-
setters.setEnrollmentResult({
|
|
18094
|
-
status: "enrolled",
|
|
18095
|
-
usedMembership: false
|
|
18096
|
-
});
|
|
18097
|
-
setters.setStep("success");
|
|
18098
|
-
return true;
|
|
18099
|
-
}
|
|
18100
|
-
if (status === "waitlist") {
|
|
18101
|
-
setters.setEnrollmentResult({
|
|
18102
|
-
status: "waitlist",
|
|
18103
|
-
usedMembership: false
|
|
18104
|
-
});
|
|
18105
|
-
setters.setStep("waitlist");
|
|
18106
|
-
return true;
|
|
18107
|
-
}
|
|
18108
|
-
setters.setErrorMessage("Payment did not complete. Please try again.");
|
|
18109
|
-
setters.setStep("error");
|
|
18110
|
-
return true;
|
|
18111
|
-
}
|
|
18112
|
-
async function pollWholeSeriesRegistrationStatus(api, sessionId, setters, isCancelled) {
|
|
18113
|
-
const startedAt = Date.now();
|
|
18114
|
-
while (!isCancelled()) {
|
|
18115
|
-
try {
|
|
18116
|
-
const result = await api.getWholeSeriesRegistrationStatus({ sessionId });
|
|
18117
|
-
if (isCancelled()) return;
|
|
18118
|
-
if (result.status !== "pending_payment") {
|
|
18119
|
-
applyTerminalStatus(result.status, setters);
|
|
18120
|
-
return;
|
|
18121
|
-
}
|
|
18122
|
-
} catch (cause) {
|
|
18123
|
-
setters.setErrorMessage(cause instanceof Error ? cause.message : "Failed to verify payment");
|
|
18124
|
-
}
|
|
18125
|
-
if (Date.now() - startedAt > 3e4) {
|
|
18126
|
-
setters.setErrorMessage("Payment is still processing. Please check your email for confirmation.");
|
|
18127
|
-
setters.setStep("error");
|
|
18128
|
-
return;
|
|
18129
|
-
}
|
|
18130
|
-
await new Promise((resolve) => setTimeout(resolve, 1500));
|
|
18131
|
-
}
|
|
18132
|
-
}
|
|
18133
|
-
function useWholeSeriesPaymentVerification(api, setters, anchorId = WHOLE_SERIES_REGISTRATION_ANCHOR_ID, location = window.location) {
|
|
18134
|
-
useEffect(() => {
|
|
18135
|
-
let cancelled = false;
|
|
18136
|
-
const enrollment = new URLSearchParams(location.search).get("enrollment");
|
|
18137
|
-
const sessionId = getWholeSeriesCheckoutSessionId(location);
|
|
18138
|
-
if (enrollment === "cancelled") {
|
|
18139
|
-
scrollToBlock(anchorId);
|
|
18140
|
-
setters.setErrorMessage("Payment was cancelled. You can try again.");
|
|
18141
|
-
setters.setStep("error");
|
|
18142
|
-
return;
|
|
18143
|
-
}
|
|
18144
|
-
if (enrollment !== "success" || !sessionId) return;
|
|
18145
|
-
scrollToBlock(anchorId);
|
|
18146
|
-
setters.setStep("verifying-payment");
|
|
18147
|
-
pollWholeSeriesRegistrationStatus(api, sessionId, setters, () => cancelled);
|
|
18148
|
-
return () => {
|
|
18149
|
-
cancelled = true;
|
|
18150
|
-
};
|
|
18151
|
-
}, [
|
|
18152
|
-
api,
|
|
18153
|
-
setters.setEnrollmentResult,
|
|
18154
|
-
setters.setErrorMessage,
|
|
18155
|
-
setters.setStep,
|
|
18156
|
-
anchorId,
|
|
18157
|
-
location
|
|
18158
|
-
]);
|
|
18159
|
-
}
|
|
18160
|
-
//#endregion
|
|
18161
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationActions.ts
|
|
18162
|
-
function blocked(message, setters) {
|
|
18163
|
-
setters.setErrorMessage(message);
|
|
18164
|
-
setters.setStep("error");
|
|
18165
|
-
return {
|
|
18166
|
-
kind: "blocked",
|
|
18167
|
-
message
|
|
18168
|
-
};
|
|
18169
|
-
}
|
|
18170
|
-
function validateSubmission(state, setters) {
|
|
18171
|
-
if (!state.selectedRun) return {
|
|
18172
|
-
kind: "blocked",
|
|
18173
|
-
message: "Choose an available set of dates to continue."
|
|
18174
|
-
};
|
|
18175
|
-
const errors = validateFormData$1(state.formData);
|
|
18176
|
-
if (state.selectedRun.consent && state.formData.consentAccepted !== true) errors.consentAccepted = "Please read and accept the agreement before continuing.";
|
|
18177
|
-
setters.setErrors(errors);
|
|
18178
|
-
if (Object.keys(errors).length > 0) return { kind: "validation-failed" };
|
|
18179
|
-
const pricingMessage = getMissingWholeSeriesPricingSelectionMessage(state.pricing);
|
|
18180
|
-
if (pricingMessage) return blocked(pricingMessage, setters);
|
|
18181
|
-
if (!state.hasClaim && state.eligibility?.isFull && !state.eligibility.canJoinWaitlist) return blocked(state.eligibility.reason ?? "This run is fully booked.", setters);
|
|
18182
|
-
if (isSpamProtectionEnabled() && !state.altchaSolution) return blocked("Please complete the verification check.", setters);
|
|
18183
|
-
return null;
|
|
18184
|
-
}
|
|
18185
|
-
function enrollmentPayload(state, payment) {
|
|
18186
|
-
return {
|
|
18187
|
-
...registrantPayload(state),
|
|
18188
|
-
paymentMethod: payment.method,
|
|
18189
|
-
...payment.method === "membership" ? { customerMembershipId: payment.membershipId } : {}
|
|
18190
|
-
};
|
|
18191
|
-
}
|
|
18192
|
-
function registrantPayload(state) {
|
|
18193
|
-
return {
|
|
18194
|
-
eventSeriesId: state.selectedRun.eventSeriesId,
|
|
18195
|
-
...buildWholeSeriesPricingOptionPayload(state.pricing),
|
|
18196
|
-
email: state.formData.email.trim().toLowerCase(),
|
|
18197
|
-
name: state.formData.name.trim(),
|
|
18198
|
-
phone: state.formData.phone.trim() || void 0,
|
|
18199
|
-
formData: { notes: state.formData.notes.trim() || void 0 },
|
|
18200
|
-
consentAccepted: state.formData.consentAccepted,
|
|
18201
|
-
altchaSolution: state.altchaSolution,
|
|
18202
|
-
claimToken: state.claimToken ?? void 0
|
|
18203
|
-
};
|
|
18204
|
-
}
|
|
18205
|
-
async function enroll(state, setters, payment) {
|
|
18206
|
-
setters.setStep("submitting");
|
|
18207
|
-
try {
|
|
18208
|
-
const result = await state.api.registerForWholeSeries(enrollmentPayload(state, payment));
|
|
18209
|
-
setters.setEnrollmentResult({
|
|
18210
|
-
status: result.status,
|
|
18211
|
-
waitlistPosition: result.waitlistPosition ?? void 0,
|
|
18212
|
-
usedMembership: payment.method === "membership"
|
|
18213
|
-
});
|
|
18214
|
-
setters.setStep(result.status === "waitlist" ? "waitlist" : "success");
|
|
18215
|
-
return { kind: "state-updated" };
|
|
18216
|
-
} catch (cause) {
|
|
18217
|
-
const message = cause instanceof Error ? cause.message : "Booking failed";
|
|
18218
|
-
setters.setErrorMessage(message);
|
|
18219
|
-
setters.setStep("error");
|
|
18220
|
-
return {
|
|
18221
|
-
kind: "failed",
|
|
18222
|
-
message
|
|
18223
|
-
};
|
|
18224
|
-
}
|
|
18225
|
-
}
|
|
18226
|
-
async function checkout(state, setters) {
|
|
18227
|
-
setters.setStep("submitting");
|
|
18228
|
-
try {
|
|
18229
|
-
const urls = buildCheckoutReturnUrls("enrollment", state.options.anchorId ?? "event-registration");
|
|
18230
|
-
const result = await state.api.createWholeSeriesCheckout({
|
|
18231
|
-
...registrantPayload(state),
|
|
18232
|
-
discountCode: state.discountCode.trim() || void 0,
|
|
18233
|
-
successUrl: urls.successUrl,
|
|
18234
|
-
cancelUrl: urls.cancelUrl
|
|
18235
|
-
});
|
|
18236
|
-
if (result.bypassed) {
|
|
18237
|
-
setters.setEnrollmentResult({
|
|
18238
|
-
status: "enrolled",
|
|
18239
|
-
usedMembership: false
|
|
18240
|
-
});
|
|
18241
|
-
setters.setStep("success");
|
|
18242
|
-
return { kind: "state-updated" };
|
|
18243
|
-
}
|
|
18244
|
-
if (!result.checkoutUrl) throw new Error("Checkout URL missing");
|
|
18245
|
-
setters.setStep("redirecting");
|
|
18246
|
-
if (state.options.onCheckoutRedirect) state.options.onCheckoutRedirect(result.checkoutUrl);
|
|
18247
|
-
else window.location.href = result.checkoutUrl;
|
|
18248
|
-
return {
|
|
18249
|
-
kind: "checkout-redirect",
|
|
18250
|
-
checkoutUrl: result.checkoutUrl
|
|
18251
|
-
};
|
|
18252
|
-
} catch (cause) {
|
|
18253
|
-
const message = cause instanceof Error ? cause.message : "Checkout failed";
|
|
18254
|
-
setters.setErrorMessage(message);
|
|
18255
|
-
setters.setStep("error");
|
|
18256
|
-
return {
|
|
18257
|
-
kind: "failed",
|
|
18258
|
-
message
|
|
18259
|
-
};
|
|
18260
|
-
}
|
|
18261
|
-
}
|
|
18262
|
-
async function submitDetails(state, setters) {
|
|
18263
|
-
const invalid = validateSubmission(state, setters);
|
|
18264
|
-
if (invalid || !state.selectedRun) return invalid ?? { kind: "validation-failed" };
|
|
18265
|
-
if (state.eligibility?.canJoinWaitlist) return enroll(state, setters, { method: "free" });
|
|
18266
|
-
const requiresPayment = state.pricing?.selectedRequiresPayment ?? false;
|
|
18267
|
-
const canUseMembership = requiresPayment && state.selectedRun.acceptsMemberships && state.portalAuthState === "authenticated" && state.eligibleMemberships.length > 0;
|
|
18268
|
-
if (requiresPayment && canUseMembership) {
|
|
18269
|
-
setters.setStep("select-payment");
|
|
18270
|
-
return { kind: "state-updated" };
|
|
18271
|
-
}
|
|
18272
|
-
if (requiresPayment) return checkout(state, setters);
|
|
18273
|
-
return enroll(state, setters, { method: "free" });
|
|
18274
|
-
}
|
|
18275
|
-
async function continuePayment(state, setters) {
|
|
18276
|
-
const invalid = validateSubmission(state, setters);
|
|
18277
|
-
if (invalid || !state.selectedRun) return invalid ?? { kind: "validation-failed" };
|
|
18278
|
-
if (!state.pricing?.selectedRequiresPayment) {
|
|
18279
|
-
setters.setStep("enter-details");
|
|
18280
|
-
return { kind: "state-updated" };
|
|
18281
|
-
}
|
|
18282
|
-
const selectedState = state;
|
|
18283
|
-
if (state.paymentChoice === "membership") {
|
|
18284
|
-
if (!state.selectedMembershipId) return blocked("Select a membership to sign up.", setters);
|
|
18285
|
-
return enroll(selectedState, setters, {
|
|
18286
|
-
method: "membership",
|
|
18287
|
-
membershipId: state.selectedMembershipId
|
|
18288
|
-
});
|
|
18289
|
-
}
|
|
18290
|
-
return checkout(selectedState, setters);
|
|
18291
|
-
}
|
|
18292
|
-
function useWholeSeriesRegistrationActions(state, setStep) {
|
|
18293
|
-
const [errors, setErrors] = useState({});
|
|
18294
|
-
const [enrollmentResult, setEnrollmentResult] = useState(null);
|
|
18295
|
-
const [errorMessage, setErrorMessage] = useState("");
|
|
18296
|
-
const reportError = useCallback((message) => {
|
|
18297
|
-
setErrorMessage(message);
|
|
18298
|
-
}, []);
|
|
18299
|
-
const recordEnrollmentResult = useCallback((result) => {
|
|
18300
|
-
setEnrollmentResult(result);
|
|
18301
|
-
}, []);
|
|
18302
|
-
const setters = {
|
|
18303
|
-
setStep,
|
|
18304
|
-
setErrors,
|
|
18305
|
-
setEnrollmentResult,
|
|
18306
|
-
setErrorMessage
|
|
18307
|
-
};
|
|
18308
|
-
return {
|
|
18309
|
-
errors,
|
|
18310
|
-
enrollmentResult,
|
|
18311
|
-
errorMessage,
|
|
18312
|
-
reportError,
|
|
18313
|
-
recordEnrollmentResult,
|
|
18314
|
-
handleSubmit: () => submitDetails(state, setters),
|
|
18315
|
-
handlePaymentContinue: () => continuePayment(state, setters)
|
|
18316
|
-
};
|
|
18317
|
-
}
|
|
18318
|
-
//#endregion
|
|
18319
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationPortal.ts
|
|
18320
|
-
const EMPTY_FORM = {
|
|
18321
|
-
name: "",
|
|
18322
|
-
email: "",
|
|
18323
|
-
phone: "",
|
|
18324
|
-
notes: "",
|
|
18325
|
-
consentAccepted: false
|
|
18326
|
-
};
|
|
18327
|
-
function useWholeSeriesRegistrationPortal(api) {
|
|
18328
|
-
const [formData, setFormData] = useState(EMPTY_FORM);
|
|
18329
|
-
const [portalAuthState, setPortalAuthState] = useState("checking");
|
|
18330
|
-
const updateFormData = useCallback((updater) => {
|
|
18331
|
-
setFormData(updater);
|
|
18332
|
-
}, []);
|
|
18333
|
-
useEffect(() => {
|
|
18334
|
-
let cancelled = false;
|
|
18335
|
-
if (!(api.config.auth.type === "bearer" || api.config.authOverrides?.portal?.type === "bearer")) {
|
|
18336
|
-
setPortalAuthState("unauthenticated");
|
|
18337
|
-
return;
|
|
18338
|
-
}
|
|
18339
|
-
setPortalAuthState("checking");
|
|
18340
|
-
api.getPortalProfile().then((result) => {
|
|
18341
|
-
if (cancelled) return;
|
|
18342
|
-
setPortalAuthState("authenticated");
|
|
18343
|
-
setFormData((current) => ({
|
|
18344
|
-
...current,
|
|
18345
|
-
email: result.profile.email,
|
|
18346
|
-
name: current.name || result.profile.name,
|
|
18347
|
-
phone: current.phone || result.profile.phone || ""
|
|
18348
|
-
}));
|
|
18349
|
-
}).catch(() => {
|
|
18350
|
-
if (!cancelled) setPortalAuthState("unauthenticated");
|
|
18351
|
-
});
|
|
18352
|
-
return () => {
|
|
18353
|
-
cancelled = true;
|
|
18354
|
-
};
|
|
18355
|
-
}, [api]);
|
|
18356
|
-
return {
|
|
18357
|
-
formData,
|
|
18358
|
-
updateFormData,
|
|
18359
|
-
portalAuthState
|
|
18360
|
-
};
|
|
18361
|
-
}
|
|
18362
|
-
//#endregion
|
|
18363
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesWaitlistSelection.ts
|
|
18364
|
-
function useWholeSeriesWaitlistSelection(input) {
|
|
18365
|
-
useEffect(() => {
|
|
18366
|
-
const claim = input.waitlistClaim.claim;
|
|
18367
|
-
if (!claim || claim.subject.kind !== "whole_series") return;
|
|
18368
|
-
const eventSeriesId = claim.subject.eventSeriesId;
|
|
18369
|
-
const run = input.scopedRuns.find((candidate) => candidate.eventSeriesId === eventSeriesId);
|
|
18370
|
-
if (!run) {
|
|
18371
|
-
input.reportError("This waitlist claim is for a different run.");
|
|
18372
|
-
input.goToStep("error");
|
|
18373
|
-
return;
|
|
18374
|
-
}
|
|
18375
|
-
input.chooseRun(run);
|
|
18376
|
-
input.updateFormData((current) => ({
|
|
18377
|
-
...current,
|
|
18378
|
-
email: claim.prefill.email,
|
|
18379
|
-
name: claim.prefill.name,
|
|
18380
|
-
phone: claim.prefill.phone ?? "",
|
|
18381
|
-
notes: claim.prefill.notes ?? ""
|
|
18382
|
-
}));
|
|
18383
|
-
if (input.step === "select-run") input.goToStep("enter-details");
|
|
18384
|
-
}, [
|
|
18385
|
-
input.chooseRun,
|
|
18386
|
-
input.goToStep,
|
|
18387
|
-
input.reportError,
|
|
18388
|
-
input.scopedRuns,
|
|
18389
|
-
input.step,
|
|
18390
|
-
input.updateFormData,
|
|
18391
|
-
input.waitlistClaim.claim
|
|
18392
|
-
]);
|
|
18393
|
-
useEffect(() => {
|
|
18394
|
-
if (input.waitlistClaim.requiresPortalLogin || !input.waitlistClaim.error) return;
|
|
18395
|
-
input.reportError(input.waitlistClaim.error);
|
|
18396
|
-
input.goToStep("error");
|
|
18397
|
-
}, [
|
|
18398
|
-
input.goToStep,
|
|
18399
|
-
input.reportError,
|
|
18400
|
-
input.waitlistClaim.error,
|
|
18401
|
-
input.waitlistClaim.requiresPortalLogin
|
|
18402
|
-
]);
|
|
18403
|
-
}
|
|
18404
|
-
//#endregion
|
|
18405
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationWizard.ts
|
|
18406
|
-
function useWholeSeriesRegistrationWizard(props, options = {}) {
|
|
18407
|
-
return useWholeSeriesRegistrationWizardWithDeps(wholeSeriesRegistrationWizardDeps, props, options);
|
|
18408
|
-
}
|
|
18409
|
-
const wholeSeriesRegistrationWizardDeps = { readLocation: () => ({
|
|
18410
|
-
search: window.location.search,
|
|
18411
|
-
hash: window.location.hash
|
|
18412
|
-
}) };
|
|
18413
|
-
function useWholeSeriesRegistrationWizardWithDeps(deps, props, options = {}) {
|
|
18414
|
-
const api = useBlockApi();
|
|
18415
|
-
const [location] = useState(deps.readLocation);
|
|
18416
|
-
const selection = useWholeSeriesRegistrationSelection(props, location);
|
|
18417
|
-
const portal = useWholeSeriesRegistrationPortal(api);
|
|
18418
|
-
const waitlistClaim = useWaitlistClaimForToken(new URLSearchParams(location.search).get("waitlist_claim")?.trim() || null);
|
|
18419
|
-
const [bookingMode, setBookingMode] = useState(null);
|
|
18420
|
-
const [altchaSolution, setAltchaSolution] = useState(null);
|
|
18421
|
-
const eligibility = useWholeSeriesEligibility({
|
|
18422
|
-
api,
|
|
18423
|
-
selectedRun: selection.selectedRun,
|
|
18424
|
-
hasPaidSelection: selection.selectedRunPricing?.hasPaidSelection ?? false,
|
|
18425
|
-
portalAuthState: portal.portalAuthState,
|
|
18426
|
-
waitlistClaimToken: waitlistClaim.token
|
|
18427
|
-
});
|
|
18428
|
-
const discountUi = useDiscountCodeUi({
|
|
18429
|
-
api,
|
|
18430
|
-
discountContext: useMemo(() => selection.selectedRun && selection.selectedRunPricing?.selectedRequiresPayment && eligibility.paymentChoice === "checkout" ? {
|
|
18431
|
-
type: "whole_series",
|
|
18432
|
-
eventSeriesId: selection.selectedRun.eventSeriesId
|
|
18433
|
-
} : null, [
|
|
18434
|
-
eligibility.paymentChoice,
|
|
18435
|
-
selection.selectedRun,
|
|
18436
|
-
selection.selectedRunPricing?.selectedRequiresPayment
|
|
18437
|
-
]),
|
|
18438
|
-
subtotalCents: selection.selectedRunPricing?.selectedPriceAmount ?? void 0
|
|
18439
|
-
});
|
|
18440
|
-
const actions = useWholeSeriesRegistrationActions({
|
|
18441
|
-
api,
|
|
18442
|
-
selectedRun: selection.selectedRun,
|
|
18443
|
-
pricing: selection.selectedRunPricing,
|
|
18444
|
-
formData: portal.formData,
|
|
18445
|
-
portalAuthState: portal.portalAuthState,
|
|
18446
|
-
eligibility: eligibility.runEligibility,
|
|
18447
|
-
eligibleMemberships: eligibility.eligibleMemberships,
|
|
18448
|
-
paymentChoice: eligibility.paymentChoice,
|
|
18449
|
-
selectedMembershipId: eligibility.selectedMembershipId,
|
|
18450
|
-
claimToken: waitlistClaim.token,
|
|
18451
|
-
hasClaim: waitlistClaim.claim !== null,
|
|
18452
|
-
altchaSolution,
|
|
18453
|
-
discountCode: discountUi.discountCode,
|
|
18454
|
-
options
|
|
18455
|
-
}, selection.goToStep);
|
|
18456
|
-
useWholeSeriesRegistrationEffects({
|
|
18457
|
-
api,
|
|
18458
|
-
actions,
|
|
18459
|
-
portal,
|
|
18460
|
-
selection,
|
|
18461
|
-
waitlistClaim,
|
|
18462
|
-
anchorId: options.anchorId ?? "event-registration",
|
|
18463
|
-
location
|
|
18464
|
-
});
|
|
18465
|
-
return buildWholeSeriesRegistrationWizardResult({
|
|
18466
|
-
api,
|
|
18467
|
-
selection,
|
|
18468
|
-
portal,
|
|
18469
|
-
eligibility,
|
|
18470
|
-
actions,
|
|
18471
|
-
discountUi,
|
|
18472
|
-
waitlistClaim,
|
|
18473
|
-
view: deriveWholeSeriesRegistrationViewState({
|
|
18474
|
-
scopedRuns: selection.scopedRuns,
|
|
18475
|
-
selectedRun: selection.selectedRun,
|
|
18476
|
-
pricing: selection.selectedRunPricing,
|
|
18477
|
-
portalAuthState: portal.portalAuthState,
|
|
18478
|
-
eligibleMembershipCount: eligibility.eligibleMemberships.length,
|
|
18479
|
-
bookingMode,
|
|
18480
|
-
step: selection.step,
|
|
18481
|
-
waitlistRequiresPortalLogin: waitlistClaim.requiresPortalLogin
|
|
18482
|
-
}),
|
|
18483
|
-
bookingMode,
|
|
18484
|
-
setBookingMode,
|
|
18485
|
-
altchaSolution,
|
|
18486
|
-
setAltchaSolution,
|
|
18487
|
-
anchorId: options.anchorId ?? "event-registration"
|
|
18488
|
-
});
|
|
18489
|
-
}
|
|
18490
|
-
function useWholeSeriesRegistrationEffects(input) {
|
|
18491
|
-
useWholeSeriesPaymentVerification(input.api, {
|
|
18492
|
-
setStep: input.selection.goToStep,
|
|
18493
|
-
setErrorMessage: input.actions.reportError,
|
|
18494
|
-
setEnrollmentResult: input.actions.recordEnrollmentResult
|
|
18495
|
-
}, input.anchorId, input.location);
|
|
18496
|
-
useWholeSeriesWaitlistSelection({
|
|
18497
|
-
waitlistClaim: input.waitlistClaim,
|
|
18498
|
-
scopedRuns: input.selection.scopedRuns,
|
|
18499
|
-
step: input.selection.step,
|
|
18500
|
-
goToStep: input.selection.goToStep,
|
|
18501
|
-
chooseRun: input.selection.chooseRun,
|
|
18502
|
-
updateFormData: input.portal.updateFormData,
|
|
18503
|
-
reportError: input.actions.reportError
|
|
18504
|
-
});
|
|
18505
|
-
}
|
|
18506
|
-
function buildWholeSeriesRegistrationWizardResult(parts) {
|
|
18507
|
-
const handleBookingModeChange = (mode) => {
|
|
18508
|
-
parts.setBookingMode(mode);
|
|
18509
|
-
parts.eligibility.choosePaymentChoice(mode === "membership" ? "membership" : "checkout");
|
|
18510
|
-
};
|
|
18511
|
-
return {
|
|
18512
|
-
api: parts.api,
|
|
18513
|
-
...parts.selection,
|
|
18514
|
-
...parts.portal,
|
|
18515
|
-
...parts.eligibility,
|
|
18516
|
-
...parts.actions,
|
|
18517
|
-
waitlistClaim: parts.waitlistClaim,
|
|
18518
|
-
bookingMode: parts.bookingMode,
|
|
18519
|
-
altchaSolution: parts.altchaSolution,
|
|
18520
|
-
setAltchaSolution: parts.setAltchaSolution,
|
|
18521
|
-
showSpamProtection: isSpamProtectionEnabled(),
|
|
18522
|
-
discountUiOpen: parts.discountUi.discountUiOpen,
|
|
18523
|
-
setDiscountUiOpen: parts.discountUi.setDiscountUiOpen,
|
|
18524
|
-
discountCode: parts.discountUi.discountCode,
|
|
18525
|
-
setDiscountCode: parts.discountUi.setDiscountCode,
|
|
18526
|
-
discountsAvailable: parts.discountUi.discountsAvailable,
|
|
18527
|
-
manualCodeEntryAllowed: parts.discountUi.manualCodeEntryAllowed,
|
|
18528
|
-
discountsAvailableLoading: parts.discountUi.discountsAvailableLoading,
|
|
18529
|
-
...parts.view,
|
|
18530
|
-
handleRunSelect: (run) => {
|
|
18531
|
-
parts.selection.chooseRun(run);
|
|
18532
|
-
parts.selection.goToStep("enter-details");
|
|
18533
|
-
},
|
|
18534
|
-
handleRetry: () => {
|
|
18535
|
-
parts.selection.goToStep(parts.selection.scopedRuns.length === 1 ? "enter-details" : "select-run");
|
|
18536
|
-
parts.actions.reportError("");
|
|
18537
|
-
},
|
|
18538
|
-
handleBookingModeChange,
|
|
18539
|
-
handleLogout: parts.portal.portalAuthState === "authenticated" ? () => logoutPortal(parts.anchorId) : void 0,
|
|
18540
|
-
selectedRunPricingPayload: buildWholeSeriesPricingOptionPayload(parts.selection.selectedRunPricing)
|
|
18541
|
-
};
|
|
18542
|
-
}
|
|
18543
|
-
//#endregion
|
|
18544
|
-
//#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/whole-series-registration.headless.planning.ts
|
|
18545
|
-
const STEP_IDS = {
|
|
18546
|
-
"select-run": "select-run",
|
|
18547
|
-
"enter-details": "enter-details",
|
|
18548
|
-
"booking-mode": "select-booking-method",
|
|
18549
|
-
"select-payment": "select-payment"
|
|
18550
|
-
};
|
|
18551
|
-
function toPublicStepId(step) {
|
|
18552
|
-
switch (step) {
|
|
18553
|
-
case "select-run":
|
|
18554
|
-
case "enter-details":
|
|
18555
|
-
case "booking-mode":
|
|
18556
|
-
case "select-payment": return STEP_IDS[step];
|
|
18557
|
-
case "submitting":
|
|
18558
|
-
case "redirecting":
|
|
18559
|
-
case "verifying-payment":
|
|
18560
|
-
case "verifying-timeout":
|
|
18561
|
-
case "payment-failed":
|
|
18562
|
-
case "success":
|
|
18563
|
-
case "waitlist":
|
|
18564
|
-
case "error": return null;
|
|
18565
|
-
}
|
|
18566
|
-
}
|
|
18567
|
-
function deriveWholeSeriesRegistrationSteps(input) {
|
|
18568
|
-
const currentId = toPublicStepId(input.step);
|
|
18569
|
-
const currentIndex = currentId ? input.wizardSteps.findIndex((step) => toPublicStepId(step) === currentId) : input.step === "success" || input.step === "waitlist" ? input.wizardSteps.length : -1;
|
|
18570
|
-
return input.wizardSteps.flatMap((step, index) => {
|
|
18571
|
-
const id = toPublicStepId(step);
|
|
18572
|
-
if (!id) return [];
|
|
18573
|
-
const state = index < currentIndex ? "complete" : index === currentIndex ? "active" : currentIndex >= 0 ? "available" : "blocked";
|
|
18574
|
-
return [{
|
|
18575
|
-
id,
|
|
18576
|
-
state,
|
|
18577
|
-
index,
|
|
18578
|
-
canEnter: state === "active" || state === "complete"
|
|
18579
|
-
}];
|
|
18580
|
-
});
|
|
18581
|
-
}
|
|
18582
|
-
function resolveWholeSeriesRegistrationStatus(wizard) {
|
|
18583
|
-
switch (wizard.step) {
|
|
18584
|
-
case "submitting": return { tag: "submitting" };
|
|
18585
|
-
case "redirecting": return { tag: "redirecting" };
|
|
18586
|
-
case "verifying-payment": return { tag: "verifying-payment" };
|
|
18587
|
-
case "verifying-timeout": return {
|
|
18588
|
-
tag: "verifying-timeout",
|
|
18589
|
-
message: wizard.errorMessage
|
|
18590
|
-
};
|
|
18591
|
-
case "payment-failed": return {
|
|
18592
|
-
tag: "payment-failed",
|
|
18593
|
-
message: wizard.errorMessage
|
|
18594
|
-
};
|
|
18595
|
-
case "success": return wizard.enrollmentResult ? {
|
|
18596
|
-
tag: "success",
|
|
18597
|
-
result: wizard.enrollmentResult
|
|
18598
|
-
} : {
|
|
18599
|
-
tag: "error",
|
|
18600
|
-
message: "Registration completed without a result."
|
|
18601
|
-
};
|
|
18602
|
-
case "waitlist": return wizard.enrollmentResult ? {
|
|
18603
|
-
tag: "waitlist",
|
|
18604
|
-
result: wizard.enrollmentResult
|
|
18605
|
-
} : {
|
|
18606
|
-
tag: "error",
|
|
18607
|
-
message: "Waitlist registration completed without a result."
|
|
18608
|
-
};
|
|
18609
|
-
case "error": return {
|
|
18610
|
-
tag: "error",
|
|
18611
|
-
message: wizard.errorMessage
|
|
18612
|
-
};
|
|
18613
|
-
case "select-run":
|
|
18614
|
-
case "enter-details":
|
|
18615
|
-
case "booking-mode":
|
|
18616
|
-
case "select-payment": return { tag: "ready" };
|
|
18617
|
-
}
|
|
18618
|
-
}
|
|
18619
|
-
function resolveWholeSeriesRegistrationView(wizard) {
|
|
18620
|
-
switch (wizard.step) {
|
|
18621
|
-
case "submitting":
|
|
18622
|
-
case "redirecting":
|
|
18623
|
-
case "verifying-payment": return {
|
|
18624
|
-
kind: "verifying",
|
|
18625
|
-
message: "Completing your sign-up."
|
|
18626
|
-
};
|
|
18627
|
-
case "verifying-timeout":
|
|
18628
|
-
case "payment-failed":
|
|
18629
|
-
case "error": return {
|
|
18630
|
-
kind: "error",
|
|
18631
|
-
message: wizard.errorMessage
|
|
18632
|
-
};
|
|
18633
|
-
case "success": return wizard.enrollmentResult ? {
|
|
18634
|
-
kind: "success",
|
|
18635
|
-
result: wizard.enrollmentResult
|
|
18636
|
-
} : {
|
|
18637
|
-
kind: "error",
|
|
18638
|
-
message: "Registration completed without a result."
|
|
18639
|
-
};
|
|
18640
|
-
case "waitlist": return wizard.enrollmentResult ? {
|
|
18641
|
-
kind: "waitlist",
|
|
18642
|
-
result: wizard.enrollmentResult
|
|
18643
|
-
} : {
|
|
18644
|
-
kind: "error",
|
|
18645
|
-
message: "Waitlist registration completed without a result."
|
|
18646
|
-
};
|
|
18647
|
-
case "select-run":
|
|
18648
|
-
case "enter-details":
|
|
18649
|
-
case "booking-mode":
|
|
18650
|
-
case "select-payment":
|
|
18651
|
-
if (wizard.scopedRunsCount === 0) return {
|
|
18652
|
-
kind: "empty",
|
|
18653
|
-
message: "There are no dates available to sign up for."
|
|
18654
|
-
};
|
|
18655
|
-
if (wizard.selectedRun && !wizard.selectedRun.enrollmentOpen) return {
|
|
18656
|
-
kind: "unavailable",
|
|
18657
|
-
message: "Sign-up is closed."
|
|
18658
|
-
};
|
|
18659
|
-
return { kind: "form" };
|
|
18660
|
-
}
|
|
18661
|
-
}
|
|
18662
|
-
function resolveWholeSeriesPricingSelection(pricing) {
|
|
18663
|
-
if (!pricing) return { tag: "not-required" };
|
|
18664
|
-
if (pricing.display.kind === "unavailable") return { tag: "unavailable" };
|
|
18665
|
-
if (pricing.slidingScale && pricing.selectedSlidingAmount !== null) {
|
|
18666
|
-
if (pricing.selectedSlidingAmount < pricing.slidingScale.minAmount || pricing.selectedSlidingAmount > pricing.slidingScale.maxAmount) return {
|
|
18667
|
-
tag: "invalid",
|
|
18668
|
-
message: "Choose an amount within the available range."
|
|
18669
|
-
};
|
|
18670
|
-
}
|
|
18671
|
-
if (pricing.requiresSelection && !pricing.selectedOption && pricing.selectedSlidingAmount === null) return { tag: "required" };
|
|
18672
|
-
return pricing.requiresSelection || pricing.selectedOption || pricing.selectedSlidingAmount !== null ? { tag: "valid" } : { tag: "not-required" };
|
|
18673
|
-
}
|
|
18674
|
-
function resolveWholeSeriesPaymentSelection(input) {
|
|
18675
|
-
if (!input.required) return { method: "none" };
|
|
18676
|
-
if (input.paymentChoice === "membership") return {
|
|
18677
|
-
method: "membership",
|
|
18678
|
-
membershipId: input.selectedMembershipId
|
|
18679
|
-
};
|
|
18680
|
-
return { method: "card" };
|
|
18681
|
-
}
|
|
18682
|
-
//#endregion
|
|
18683
|
-
//#region ../blocks/src/system/runtime/hooks/useHeadlessWholeSeriesRegistrationFlow.ts
|
|
18684
|
-
const wholeSeriesRegistrationControllerDeps = { useWholeSeriesRegistrationWizard };
|
|
18685
|
-
function createWholeSeriesRegistrationBlockApiConfig(input) {
|
|
18686
|
-
return {
|
|
18687
|
-
baseUrl: input.apiBaseUrl,
|
|
18688
|
-
auth: input.previewToken ? {
|
|
18689
|
-
type: "bearer",
|
|
18690
|
-
token: input.previewToken
|
|
18691
|
-
} : { type: "none" },
|
|
18692
|
-
siteId: input.siteId,
|
|
18693
|
-
isPreview: input.stage === "preview",
|
|
18694
|
-
...input.portalToken ? { authOverrides: { portal: {
|
|
18695
|
-
type: "bearer",
|
|
18696
|
-
token: input.portalToken
|
|
18697
|
-
} } } : {}
|
|
18698
|
-
};
|
|
18699
|
-
}
|
|
18700
|
-
function HeadlessWholeSeriesRegistrationProvider$1({ config, children }) {
|
|
18701
|
-
return React.createElement(BlockApiProvider, {
|
|
18702
|
-
config,
|
|
18703
|
-
children
|
|
18704
|
-
});
|
|
18705
|
-
}
|
|
18706
|
-
function useHeadlessWholeSeriesRegistrationFlow(options) {
|
|
18707
|
-
return useWholeSeriesRegistrationControllerWithDeps(options, wholeSeriesRegistrationControllerDeps);
|
|
18708
|
-
}
|
|
18709
|
-
function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
|
|
18710
|
-
const wizard = deps.useWholeSeriesRegistrationWizard({
|
|
18711
|
-
runs: (options.runs ?? []).map(toPublicWholeSeriesOffering),
|
|
18712
|
-
subject: options.subject ?? null
|
|
18713
|
-
}, { onCheckoutRedirect: () => {} });
|
|
18714
|
-
const steps = useMemo(() => deriveWholeSeriesRegistrationSteps({
|
|
18715
|
-
wizardSteps: wizard.wizardSteps,
|
|
18716
|
-
step: wizard.step
|
|
18717
|
-
}), [wizard.step, wizard.wizardSteps]);
|
|
18718
|
-
const currentStep = steps.find((step) => step.state === "active") ?? null;
|
|
18719
|
-
const pricingSelection = resolveWholeSeriesPricingSelection(wizard.selectedRunPricing);
|
|
18720
|
-
const paymentSelection = resolveWholeSeriesPaymentSelection({
|
|
18721
|
-
paymentChoice: wizard.paymentChoice,
|
|
18722
|
-
selectedMembershipId: wizard.selectedMembershipId,
|
|
18723
|
-
required: wizard.selectedRunPricing?.selectedRequiresPayment ?? false
|
|
18724
|
-
});
|
|
18725
|
-
const updateRegistrant = useCallback((values) => wizard.updateFormData(values), [wizard]);
|
|
18726
|
-
const setSlidingAmountCents = useCallback((amount) => {
|
|
18727
|
-
wizard.changeSlidingAmount(amount === null || !Number.isFinite(amount) || amount < 0 ? "" : String(amount / 100));
|
|
18728
|
-
}, [wizard]);
|
|
18729
|
-
const selectPayment = useCallback((selection) => {
|
|
18730
|
-
switch (selection.method) {
|
|
18731
|
-
case "none":
|
|
18732
|
-
wizard.handleBookingModeChange(null);
|
|
18733
|
-
wizard.chooseMembership(null);
|
|
18734
|
-
return;
|
|
18735
|
-
case "card":
|
|
18736
|
-
wizard.handleBookingModeChange("card");
|
|
18737
|
-
wizard.chooseMembership(null);
|
|
18738
|
-
return;
|
|
18739
|
-
case "membership":
|
|
18740
|
-
wizard.handleBookingModeChange("membership");
|
|
18741
|
-
wizard.chooseMembership(selection.membershipId);
|
|
18742
|
-
return;
|
|
18743
|
-
}
|
|
18744
|
-
}, [wizard]);
|
|
18745
|
-
const runCurrentAction = useCallback(async () => {
|
|
18746
|
-
const blocked = resolveActionBlocker(wizard);
|
|
18747
|
-
if (blocked) return blocked;
|
|
18748
|
-
switch (wizard.step) {
|
|
18749
|
-
case "select-run":
|
|
18750
|
-
if (!wizard.selectedRun) return {
|
|
18751
|
-
ok: false,
|
|
18752
|
-
reason: "blocked",
|
|
18753
|
-
message: "Choose an available set of dates to continue."
|
|
18754
|
-
};
|
|
18755
|
-
wizard.goToStep("enter-details");
|
|
18756
|
-
return {
|
|
18757
|
-
ok: true,
|
|
18758
|
-
outcome: { kind: "state-updated" }
|
|
18759
|
-
};
|
|
18760
|
-
case "enter-details": return toHeadlessActionResult(await wizard.handleSubmit());
|
|
18761
|
-
case "booking-mode":
|
|
18762
|
-
case "select-payment": return toHeadlessActionResult(await wizard.handlePaymentContinue());
|
|
18763
|
-
case "submitting":
|
|
18764
|
-
case "redirecting":
|
|
18765
|
-
case "verifying-payment":
|
|
18766
|
-
case "verifying-timeout":
|
|
18767
|
-
case "payment-failed":
|
|
18768
|
-
case "success":
|
|
18769
|
-
case "waitlist":
|
|
18770
|
-
case "error": return {
|
|
18771
|
-
ok: false,
|
|
18772
|
-
reason: "blocked",
|
|
18773
|
-
message: "This registration step cannot continue."
|
|
18774
|
-
};
|
|
18775
|
-
}
|
|
18776
|
-
}, [pricingSelection, wizard]);
|
|
18777
|
-
const back = useCallback(() => {
|
|
18778
|
-
switch (wizard.step) {
|
|
18779
|
-
case "enter-details":
|
|
18780
|
-
if (!wizard.hasPreSelectedRun) wizard.goToStep("select-run");
|
|
18781
|
-
return;
|
|
18782
|
-
case "booking-mode":
|
|
18783
|
-
wizard.goToStep("enter-details");
|
|
18784
|
-
return;
|
|
18785
|
-
case "select-payment":
|
|
18786
|
-
wizard.goToStep(wizard.canUseMembership ? "booking-mode" : "enter-details");
|
|
18787
|
-
return;
|
|
18788
|
-
case "select-run":
|
|
18789
|
-
case "submitting":
|
|
18790
|
-
case "redirecting":
|
|
18791
|
-
case "verifying-payment":
|
|
18792
|
-
case "verifying-timeout":
|
|
18793
|
-
case "payment-failed":
|
|
18794
|
-
case "success":
|
|
18795
|
-
case "waitlist":
|
|
18796
|
-
case "error": return;
|
|
18797
|
-
}
|
|
18798
|
-
}, [wizard]);
|
|
18799
|
-
const payment = {
|
|
18800
|
-
required: wizard.selectedRunPricing?.selectedRequiresPayment ?? false,
|
|
18801
|
-
selection: paymentSelection,
|
|
18802
|
-
canUseMembership: wizard.canUseMembership,
|
|
18803
|
-
eligibleMemberships: wizard.eligibleMemberships.map((membership) => ({
|
|
18804
|
-
id: membership.customerMembershipId,
|
|
18805
|
-
name: membership.membershipName
|
|
18806
|
-
})),
|
|
18807
|
-
eligibility: wizard.eligibilityLoading ? { tag: "loading" } : wizard.eligibilityError ? {
|
|
18808
|
-
tag: "error",
|
|
18809
|
-
message: wizard.eligibilityError
|
|
18810
|
-
} : wizard.runEligibility || wizard.portalAuthState !== "checking" ? { tag: "loaded" } : { tag: "idle" }
|
|
18811
|
-
};
|
|
18812
|
-
const spamProtection = wizard.showSpamProtection ? {
|
|
18813
|
-
enabled: true,
|
|
18814
|
-
provider: "altcha",
|
|
18815
|
-
challenge: {
|
|
18816
|
-
url: getChallengeUrl(),
|
|
18817
|
-
auto: "onfocus"
|
|
18818
|
-
},
|
|
18819
|
-
solution: wizard.altchaSolution
|
|
18820
|
-
} : { enabled: false };
|
|
18821
|
-
const selectedRun = wizard.selectedRun;
|
|
18822
|
-
const isFull = wizard.runEligibility?.isFull ?? (selectedRun?.availableSpots !== null && selectedRun?.availableSpots !== void 0 ? selectedRun.availableSpots <= 0 : false);
|
|
18823
|
-
return {
|
|
18824
|
-
status: resolveWholeSeriesRegistrationStatus(wizard),
|
|
18825
|
-
view: resolveWholeSeriesRegistrationView({
|
|
18826
|
-
step: wizard.step,
|
|
18827
|
-
scopedRunsCount: wizard.scopedRuns.length,
|
|
18828
|
-
selectedRun,
|
|
18829
|
-
enrollmentResult: wizard.enrollmentResult,
|
|
18830
|
-
errorMessage: wizard.errorMessage
|
|
18831
|
-
}),
|
|
18832
|
-
steps,
|
|
18833
|
-
currentStep,
|
|
18834
|
-
runs: {
|
|
18835
|
-
items: (options.runs ?? []).map((run) => toWholeSeriesRegistrationRun(toPublicWholeSeriesOffering(run))),
|
|
18836
|
-
scoped: wizard.scopedRuns.map(toWholeSeriesRegistrationRun),
|
|
18837
|
-
selected: selectedRun ? toWholeSeriesRegistrationRun(selectedRun) : null,
|
|
18838
|
-
hasPreSelectedRun: wizard.hasPreSelectedRun,
|
|
18839
|
-
subject: options.subject ?? null
|
|
18840
|
-
},
|
|
18841
|
-
registrant: {
|
|
18842
|
-
values: wizard.formData,
|
|
18843
|
-
errors: wizard.errors
|
|
18844
|
-
},
|
|
18845
|
-
pricing: {
|
|
18846
|
-
...toWholeSeriesRegistrationPricing(wizard.selectedRunPricing),
|
|
18847
|
-
selectedOptionId: wizard.selectedPricingOptionId,
|
|
18848
|
-
selection: pricingSelection
|
|
18849
|
-
},
|
|
18850
|
-
payment,
|
|
18851
|
-
discount: {
|
|
18852
|
-
code: wizard.discountCode,
|
|
18853
|
-
isOpen: wizard.discountUiOpen,
|
|
18854
|
-
available: wizard.discountsAvailable,
|
|
18855
|
-
manualCodeEntryAllowed: wizard.manualCodeEntryAllowed,
|
|
18856
|
-
loading: wizard.discountsAvailableLoading
|
|
18857
|
-
},
|
|
18858
|
-
availability: {
|
|
18859
|
-
enrollmentOpen: selectedRun?.enrollmentOpen ?? false,
|
|
18860
|
-
availableSpots: selectedRun?.availableSpots ?? null,
|
|
18861
|
-
isFull,
|
|
18862
|
-
canJoinWaitlist: wizard.runEligibility?.canJoinWaitlist ?? false,
|
|
18863
|
-
message: wizard.runEligibility?.reason ?? null
|
|
18864
|
-
},
|
|
18865
|
-
portalAuth: {
|
|
18866
|
-
state: wizard.portalAuthState,
|
|
18867
|
-
isAuthenticated: wizard.portalAuthState === "authenticated"
|
|
18868
|
-
},
|
|
18869
|
-
waitlistClaim: resolveWaitlistClaim(wizard),
|
|
18870
|
-
spamProtection,
|
|
18871
|
-
terminal: {
|
|
18872
|
-
result: wizard.enrollmentResult,
|
|
18873
|
-
errorMessage: wizard.errorMessage
|
|
18874
|
-
},
|
|
18875
|
-
actions: {
|
|
18876
|
-
selectRun: (runId) => {
|
|
18877
|
-
const run = wizard.scopedRuns.find((candidate) => candidate.eventSeriesId === runId) ?? null;
|
|
18878
|
-
if (run) wizard.handleRunSelect(run);
|
|
18879
|
-
},
|
|
18880
|
-
updateRegistrant,
|
|
18881
|
-
selectPricingOption: wizard.choosePricingOption,
|
|
18882
|
-
setSlidingAmountCents,
|
|
18883
|
-
selectPayment,
|
|
18884
|
-
setDiscountCode: wizard.setDiscountCode,
|
|
18885
|
-
setDiscountOpen: wizard.setDiscountUiOpen,
|
|
18886
|
-
setAltchaSolution: wizard.setAltchaSolution,
|
|
18887
|
-
continue: runCurrentAction,
|
|
18888
|
-
back,
|
|
18889
|
-
submit: runCurrentAction,
|
|
18890
|
-
retry: wizard.handleRetry,
|
|
18891
|
-
logout: () => wizard.handleLogout?.()
|
|
18892
|
-
}
|
|
18893
|
-
};
|
|
18894
|
-
}
|
|
18895
|
-
function toHeadlessActionResult(result) {
|
|
18896
|
-
switch (result.kind) {
|
|
18897
|
-
case "state-updated": return {
|
|
18898
|
-
ok: true,
|
|
18899
|
-
outcome: result
|
|
18900
|
-
};
|
|
18901
|
-
case "checkout-redirect": return {
|
|
18902
|
-
ok: true,
|
|
18903
|
-
outcome: result
|
|
18904
|
-
};
|
|
18905
|
-
case "validation-failed": return {
|
|
18906
|
-
ok: false,
|
|
18907
|
-
reason: "validation-failed",
|
|
18908
|
-
message: "Check the highlighted fields and try again."
|
|
18909
|
-
};
|
|
18910
|
-
case "blocked": return {
|
|
18911
|
-
ok: false,
|
|
18912
|
-
reason: "blocked",
|
|
18913
|
-
message: result.message
|
|
18914
|
-
};
|
|
18915
|
-
case "failed": return {
|
|
18916
|
-
ok: false,
|
|
18917
|
-
reason: "failed",
|
|
18918
|
-
message: result.message
|
|
18919
|
-
};
|
|
18920
|
-
}
|
|
18921
|
-
}
|
|
18922
|
-
function toPublicWholeSeriesOffering(run) {
|
|
18923
|
-
const pricing = toWholeSeriesPricing(run.pricing);
|
|
18924
|
-
return {
|
|
18925
|
-
eventSeriesId: run.registrationTarget.eventSeriesId,
|
|
18926
|
-
eventOfferingId: run.eventOfferingId,
|
|
18927
|
-
title: run.title,
|
|
18928
|
-
slug: run.slug,
|
|
18929
|
-
description: run.description,
|
|
18930
|
-
teamMembers: run.teamMembers ? [...run.teamMembers] : void 0,
|
|
18931
|
-
consent: run.consent,
|
|
18932
|
-
enrollmentOpen: run.registrationOpen,
|
|
18933
|
-
pricing,
|
|
18934
|
-
currency: run.pricing.currency,
|
|
18935
|
-
paymentTerms: run.pricing.paymentTerms,
|
|
18936
|
-
enrollmentCapacity: run.capacity,
|
|
18937
|
-
acceptsMemberships: run.acceptsMemberships,
|
|
18938
|
-
status: run.lifecycleStatus,
|
|
18939
|
-
sessionsCount: run.includedDates.length,
|
|
18940
|
-
enrolledCount: run.registeredCount,
|
|
18941
|
-
availableSpots: run.availableSpots,
|
|
18942
|
-
sessions: run.includedDates.map((date) => ({
|
|
18943
|
-
...date,
|
|
18944
|
-
overrides: date.overrides ? { ...date.overrides } : date.overrides
|
|
18945
|
-
})),
|
|
18946
|
-
venue: run.venue
|
|
18947
|
-
};
|
|
18948
|
-
}
|
|
18949
|
-
function toWholeSeriesPricing(pricing) {
|
|
18950
|
-
const common = {
|
|
18951
|
-
bookingRequirement: pricing.bookingRequirement,
|
|
18952
|
-
pricingStrategy: pricing.pricingStrategy,
|
|
18953
|
-
currency: pricing.currency,
|
|
18954
|
-
paymentTerms: pricing.paymentTerms
|
|
18955
|
-
};
|
|
18956
|
-
switch (pricing.pricingStrategy) {
|
|
18957
|
-
case "free": return {
|
|
18958
|
-
...common,
|
|
18959
|
-
singlePriceAmount: null,
|
|
18960
|
-
options: []
|
|
18961
|
-
};
|
|
18962
|
-
case "single": return {
|
|
18963
|
-
...common,
|
|
18964
|
-
singlePriceAmount: pricing.amountCents,
|
|
18965
|
-
options: []
|
|
18966
|
-
};
|
|
18967
|
-
case "tiered": return {
|
|
18968
|
-
...common,
|
|
18969
|
-
singlePriceAmount: null,
|
|
18970
|
-
options: pricing.options
|
|
18971
|
-
};
|
|
18972
|
-
case "sliding_scale": return {
|
|
18973
|
-
...common,
|
|
18974
|
-
singlePriceAmount: null,
|
|
18975
|
-
slidingMinAmount: pricing.minAmountCents,
|
|
18976
|
-
slidingMaxAmount: pricing.maxAmountCents,
|
|
18977
|
-
slidingSuggestedAmount: pricing.suggestedAmountCents,
|
|
18978
|
-
options: []
|
|
18979
|
-
};
|
|
18980
|
-
}
|
|
18981
|
-
}
|
|
18982
|
-
function toWholeSeriesRegistrationRun(run) {
|
|
18983
|
-
return {
|
|
18984
|
-
id: run.eventSeriesId,
|
|
18985
|
-
title: run.title,
|
|
18986
|
-
slug: run.slug,
|
|
18987
|
-
description: run.description,
|
|
18988
|
-
registrationOpen: run.enrollmentOpen,
|
|
18989
|
-
capacity: run.enrollmentCapacity,
|
|
18990
|
-
registeredCount: run.enrolledCount,
|
|
18991
|
-
availableSpots: run.availableSpots,
|
|
18992
|
-
includedDates: run.sessions.map((session) => ({
|
|
18993
|
-
id: session.id,
|
|
18994
|
-
startsAt: session.startsAt,
|
|
18995
|
-
endsAt: session.endsAt,
|
|
18996
|
-
timeZone: session.timeZone
|
|
18997
|
-
})),
|
|
18998
|
-
venue: run.venue
|
|
18999
|
-
};
|
|
19000
|
-
}
|
|
19001
|
-
function toWholeSeriesRegistrationPricing(pricing) {
|
|
19002
|
-
if (!pricing) return {
|
|
19003
|
-
currency: null,
|
|
19004
|
-
display: null,
|
|
19005
|
-
options: [],
|
|
19006
|
-
slidingScale: null,
|
|
19007
|
-
selectedAmountCents: null,
|
|
19008
|
-
selectedPriceCents: null,
|
|
19009
|
-
requiresPayment: false
|
|
19010
|
-
};
|
|
19011
|
-
return {
|
|
19012
|
-
currency: pricing.currency,
|
|
19013
|
-
display: toWholeSeriesPriceDisplay(pricing.display),
|
|
19014
|
-
options: pricing.selectableOptions.map((option) => ({
|
|
19015
|
-
id: option.id,
|
|
19016
|
-
name: option.name,
|
|
19017
|
-
description: option.description,
|
|
19018
|
-
amountCents: option.priceAmount
|
|
19019
|
-
})),
|
|
19020
|
-
slidingScale: pricing.slidingScale ? {
|
|
19021
|
-
minAmountCents: pricing.slidingScale.minAmount,
|
|
19022
|
-
maxAmountCents: pricing.slidingScale.maxAmount,
|
|
19023
|
-
suggestedAmountCents: pricing.slidingScale.suggestedAmount
|
|
19024
|
-
} : null,
|
|
19025
|
-
selectedAmountCents: pricing.selectedSlidingAmount,
|
|
19026
|
-
selectedPriceCents: pricing.selectedPriceAmount,
|
|
19027
|
-
requiresPayment: pricing.selectedRequiresPayment
|
|
19028
|
-
};
|
|
19029
|
-
}
|
|
19030
|
-
function toWholeSeriesPriceDisplay(display) {
|
|
19031
|
-
switch (display.kind) {
|
|
19032
|
-
case "free": return display;
|
|
19033
|
-
case "exact": return {
|
|
19034
|
-
kind: "exact",
|
|
19035
|
-
amountCents: display.amount,
|
|
19036
|
-
currency: display.currency
|
|
19037
|
-
};
|
|
19038
|
-
case "from": return {
|
|
19039
|
-
kind: "from",
|
|
19040
|
-
amountCents: display.amount,
|
|
19041
|
-
currency: display.currency
|
|
19042
|
-
};
|
|
19043
|
-
case "range": return {
|
|
19044
|
-
kind: "range",
|
|
19045
|
-
minAmountCents: display.minAmount,
|
|
19046
|
-
maxAmountCents: display.maxAmount,
|
|
19047
|
-
currency: display.currency
|
|
19048
|
-
};
|
|
19049
|
-
case "unavailable": return display;
|
|
19050
|
-
}
|
|
19051
|
-
}
|
|
19052
|
-
function resolveWaitlistClaim(wizard) {
|
|
19053
|
-
const waitlistClaim = wizard.waitlistClaim;
|
|
19054
|
-
if (waitlistClaim.isLoading) return { tag: "loading" };
|
|
19055
|
-
if (waitlistClaim.requiresPortalLogin) return {
|
|
19056
|
-
tag: "login-required",
|
|
19057
|
-
message: waitlistClaim.loginMessage ?? "Log in to continue with your waitlist place."
|
|
19058
|
-
};
|
|
19059
|
-
if (waitlistClaim.error) return {
|
|
19060
|
-
tag: "error",
|
|
19061
|
-
message: waitlistClaim.error
|
|
19062
|
-
};
|
|
19063
|
-
if (waitlistClaim.claim) return {
|
|
19064
|
-
tag: "ready",
|
|
19065
|
-
expiresAt: waitlistClaim.claim.expiresAt,
|
|
19066
|
-
prefill: {
|
|
19067
|
-
email: waitlistClaim.claim.prefill.email,
|
|
19068
|
-
name: waitlistClaim.claim.prefill.name,
|
|
19069
|
-
phone: waitlistClaim.claim.prefill.phone,
|
|
19070
|
-
notes: waitlistClaim.claim.prefill.notes
|
|
19071
|
-
}
|
|
19072
|
-
};
|
|
19073
|
-
return { tag: "none" };
|
|
19074
|
-
}
|
|
19075
|
-
function resolveActionBlocker(wizard) {
|
|
19076
|
-
if (!wizard.selectedRun) return null;
|
|
19077
|
-
if (!wizard.selectedRun.enrollmentOpen) return {
|
|
19078
|
-
ok: false,
|
|
19079
|
-
reason: "blocked",
|
|
19080
|
-
message: "Sign-up is closed."
|
|
19081
|
-
};
|
|
19082
|
-
if (wizard.eligibilityLoading || wizard.portalAuthState === "checking") return {
|
|
19083
|
-
ok: false,
|
|
19084
|
-
reason: "blocked",
|
|
19085
|
-
message: "Availability is still being checked."
|
|
19086
|
-
};
|
|
19087
|
-
if (wizard.runEligibility?.isFull && !wizard.runEligibility.canJoinWaitlist) return {
|
|
19088
|
-
ok: false,
|
|
19089
|
-
reason: "blocked",
|
|
19090
|
-
message: wizard.runEligibility.reason ?? "There are no places available."
|
|
19091
|
-
};
|
|
19092
|
-
return null;
|
|
19093
|
-
}
|
|
19094
|
-
//#endregion
|
|
19095
|
-
//#region ../blocks/src/system/runtime/hooks/useBookingFormConfig.state.ts
|
|
19096
|
-
const EMPTY_SNAPSHOT = Object.freeze({
|
|
19097
|
-
formConfig: null,
|
|
19098
|
-
services: []
|
|
19099
|
-
});
|
|
19100
|
-
function createInitialBookingFormConfigState() {
|
|
19101
|
-
return {
|
|
19102
|
-
tag: "loading",
|
|
19103
|
-
previous: EMPTY_SNAPSHOT
|
|
19104
|
-
};
|
|
19105
|
-
}
|
|
19106
|
-
function bookingFormConfigReducer(state, action) {
|
|
19107
|
-
switch (action.type) {
|
|
19108
|
-
case "load-started": return {
|
|
19109
|
-
tag: "loading",
|
|
19110
|
-
previous: toBookingFormConfigSnapshot(state)
|
|
18115
|
+
function bookingFormConfigReducer(state, action) {
|
|
18116
|
+
switch (action.type) {
|
|
18117
|
+
case "load-started": return {
|
|
18118
|
+
tag: "loading",
|
|
18119
|
+
previous: toBookingFormConfigSnapshot(state)
|
|
19111
18120
|
};
|
|
19112
18121
|
case "form-loaded": {
|
|
19113
18122
|
const previous = toBookingFormConfigSnapshot(state);
|
|
@@ -19300,11 +18309,8 @@ const HeadlessBookingProvider = (props) => {
|
|
|
19300
18309
|
const HeadlessEventRegistrationProvider = (props) => {
|
|
19301
18310
|
return React$1.createElement(HeadlessEventRegistrationProvider$1, props);
|
|
19302
18311
|
};
|
|
19303
|
-
const HeadlessWholeSeriesRegistrationProvider = (props) => {
|
|
19304
|
-
return React$1.createElement(HeadlessWholeSeriesRegistrationProvider$1, props);
|
|
19305
|
-
};
|
|
19306
18312
|
const HeadlessBookingPaymentSelectionStep = (props) => {
|
|
19307
18313
|
return React$1.createElement(HeadlessBookingPaymentSelectionStep$1, props);
|
|
19308
18314
|
};
|
|
19309
18315
|
//#endregion
|
|
19310
|
-
export { BOOKING_FORM_DATA_RESERVED_KEY_VALUES, BookingFormClient, AltchaWidget as HeadlessBookingAltchaWidget, AltchaWidget as HeadlessEventRegistrationAltchaWidget,
|
|
18316
|
+
export { BOOKING_FORM_DATA_RESERVED_KEY_VALUES, BookingFormClient, AltchaWidget as HeadlessBookingAltchaWidget, AltchaWidget as HeadlessEventRegistrationAltchaWidget, HeadlessBookingPaymentSelectionStep, HeadlessBookingProvider, HeadlessEventRegistrationProvider, createBookingBlockApiConfig, createEventRegistrationBlockApiConfig, getAppointmentBookingOverrideInput, getEventRegistrationOverrideInput, useBookingFormConfig, useHeadlessBookingFlow, useHeadlessEventRegistrationFlow };
|