@riverbankcms/sdk 0.141.0 → 0.143.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/{PreviewEditorSidebar-Q-fy9GYw.mjs → PreviewEditorSidebar-DROGfMKi.mjs} +24 -15
  2. package/dist/{PreviewEditorUI-LYGzgk85.mjs → PreviewEditorUI-BaRjhFu-.mjs} +3 -3
  3. package/dist/{PreviewQueryProvider-CN0ewic5.mjs → PreviewQueryProvider-BCYICImX.mjs} +1 -1
  4. package/dist/{SdkPreviewModeRuntime-CoPYI5Jq.mjs → SdkPreviewModeRuntime-OIABYLES.mjs} +16 -11
  5. package/dist/{SiteChromeCustomizeContext-D8LePX8x.mjs → SiteChromeCustomizeContext-ohjTvZbc.mjs} +607 -545
  6. package/dist/_dts/api/src/billing.d.ts +6 -1
  7. package/dist/_dts/api/src/bookingConfig.d.ts +1 -1
  8. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +2 -2
  9. package/dist/_dts/api/src/endpoints.d.ts +7 -27
  10. package/dist/_dts/api/src/index.d.ts +1 -1
  11. package/dist/_dts/api/src/publicBookingService.d.ts +1 -0
  12. package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +7 -0
  13. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +48 -41
  14. package/dist/_dts/api/src/sdkConfig/layout.d.ts +13 -0
  15. package/dist/_dts/api/src/sdkContracts.d.ts +3 -8
  16. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +1 -31
  17. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +6 -1
  18. package/dist/_dts/billing/src/site-arrangements.d.ts +9 -5
  19. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +56 -0
  20. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +8 -0
  21. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -1
  22. package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +8 -0
  23. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +95 -35
  24. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.d.ts +10 -0
  25. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/TicketSelectionStep.d.ts +0 -2
  26. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +12 -1
  27. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +2 -2
  28. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationCompletion.d.ts +1 -4
  29. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationDerivations.d.ts +12 -0
  30. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +1 -1
  31. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/sessionStorage.d.ts +1 -0
  32. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.d.ts +4 -5
  33. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +9 -11
  34. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +56 -2
  35. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +10 -4
  36. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.d.ts +23 -0
  37. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/utils.d.ts +1 -1
  38. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +56 -0
  39. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +4 -4
  40. package/dist/_dts/commerce/src/purchase/eventCheckoutRecoveryWindow.d.ts +8 -0
  41. package/dist/_dts/commerce/src/purchase/index.d.ts +2 -1
  42. package/dist/_dts/commerce/src/purchase/stateTransitions.d.ts +1 -13
  43. package/dist/_dts/commerce/src/purchase/stripeCommissionMetadata.d.ts +1 -2
  44. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +58 -45
  45. package/dist/_dts/editor-blocks/src/block-editor/ColourFieldOptionsProvider.d.ts +7 -0
  46. package/dist/_dts/editor-blocks/src/block-editor/colourFieldVisibility.d.ts +7 -0
  47. package/dist/_dts/editor-blocks/src/block-editor/preparedManifest.d.ts +2 -0
  48. package/dist/_dts/editor-blocks/src/index.d.ts +1 -0
  49. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +2 -2
  50. package/dist/_dts/preview-next/src/client/preview/PreviewFooterEditorPanel.d.ts +3 -6
  51. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +2 -2
  52. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +2 -2
  53. package/dist/_dts/preview-next/src/client/preview/footerInspection.d.ts +16 -0
  54. package/dist/_dts/preview-next/src/client/preview/sdkConfig.d.ts +6 -0
  55. package/dist/_dts/sdk/src/config/types.d.ts +2 -18
  56. package/dist/_dts/sdk/src/config/validation.d.ts +6 -0
  57. package/dist/_dts/sdk/src/public-api/contracts.d.ts +3 -0
  58. package/dist/_dts/sdk/src/version.d.ts +1 -1
  59. package/dist/_dts/theme-core/src/footer/mode.d.ts +10 -1
  60. package/dist/_dts/theme-core/src/schema.d.ts +1 -7
  61. package/dist/_dts/theme-core/src/site-styles/effectivePageDesign.d.ts +32 -0
  62. package/dist/_dts/theme-core/src/site-styles/index.d.ts +1 -0
  63. package/dist/client/{BookingConsentAgreement-xJeYNdnb.mjs → BookingConsentAgreement-BoCtvzzu.mjs} +2 -2
  64. package/dist/client/{DiscountCodeDisclosure-DdT6uzl9.mjs → DiscountCodeDisclosure-B5S30nZk.mjs} +1 -1
  65. package/dist/client/{EventCombined.client-Cp28uYuM.mjs → EventCombined.client-CeZ2-zSt.mjs} +5 -5
  66. package/dist/client/{EventListing.client-CD6AJsMr.mjs → EventListing.client-DJN3j8B3.mjs} +2 -2
  67. package/dist/client/{LeafletStaticMap-DBsAi9-e.mjs → LeafletStaticMap-RjtGzDQT.mjs} +1 -1
  68. package/dist/client/{accordion-6dwbOKYR.mjs → accordion-DOmnDoyg.mjs} +1 -1
  69. package/dist/client/{bookingForm-CZE9_qPQ.mjs → bookingForm-C0vk7pgS.mjs} +5 -5
  70. package/dist/client/bookings.mjs +468 -534
  71. package/dist/client/{carousel-7VHGQARz.mjs → carousel-BZJ7pno3.mjs} +1 -1
  72. package/dist/client/{cart-Qg_mvQhh.mjs → cart-CaeVAHJl.mjs} +3 -3
  73. package/dist/client/{checkout-D84rpgdr.mjs → checkout-7wmoNDtG.mjs} +3 -3
  74. package/dist/client/client.mjs +559 -593
  75. package/dist/client/{context-Ctp3T0Wr.mjs → context-BOimxE3U.mjs} +12 -1
  76. package/dist/client/{dates-DJKFcI_N.mjs → dates-BnzVksi4.mjs} +2 -2
  77. package/dist/client/{eventCalendar-CK31z3vs.mjs → eventCalendar-l-fpaslC.mjs} +7 -7
  78. package/dist/client/{eventCombined-DiXd-ewn.mjs → eventCombined-DGGvssK6.mjs} +3 -3
  79. package/dist/client/{eventDetails-CTRgt2DK.mjs → eventDetails-DRiCm_hL.mjs} +4 -4
  80. package/dist/client/{eventListing-Dy9vi_j_.mjs → eventListing-dph8loYX.mjs} +3 -3
  81. package/dist/client/{eventRegistration-CnalYMr2.mjs → eventRegistration-ClBohmbY.mjs} +472 -531
  82. package/dist/client/{form-eUiMveTT.mjs → form-BLVVAnd3.mjs} +2 -2
  83. package/dist/client/{headerSection-Dy9kQpB1.mjs → headerSection-DHy4C8Ix.mjs} +2 -2
  84. package/dist/client/hooks.mjs +39 -13
  85. package/dist/client/{locationMap-DalCmWU0.mjs → locationMap-6HuS28ck.mjs} +2 -2
  86. package/dist/client/{newsletterForm-SDDPvhS0.mjs → newsletterForm-xOdcOhZP.mjs} +2 -2
  87. package/dist/client/{pricing-OcMz4SnX.mjs → pricing-ChinRYFt.mjs} +1 -1
  88. package/dist/client/{productDetail-BQrgHElM.mjs → productDetail-0chA5gbK.mjs} +3 -3
  89. package/dist/client/{productList-OnPn_UJj.mjs → productList-OoINA0h1.mjs} +3 -3
  90. package/dist/client/{propsDecoder-zBdsnS-N.mjs → propsDecoder-CIZ-hbIG.mjs} +33 -9
  91. package/dist/client/rendering/client.mjs +536 -550
  92. package/dist/client/rendering/islands.mjs +17 -17
  93. package/dist/client/rendering.mjs +602 -596
  94. package/dist/client/{scrollToBlock-BNM4Ob2Y.mjs → scrollToBlock-BPZl0gPZ.mjs} +1 -1
  95. package/dist/client/{shop-Bv1fPTwQ.mjs → shop-CLJFqNIq.mjs} +6 -6
  96. package/dist/client/{shop-commerce-D4KNGaW8.mjs → shop-commerce-PpANg5wB.mjs} +5 -5
  97. package/dist/client/{shop-commerce-store-2N5EV0Rc.mjs → shop-commerce-store-TA_Kz2ku.mjs} +1 -1
  98. package/dist/client/{shopShared-DvJGdHTV.mjs → shopShared-DzcFcA5g.mjs} +3 -3
  99. package/dist/client/{useEventFilters-BBBvGDHQ.mjs → useEventFilters-CFU21QZo.mjs} +5 -5
  100. package/dist/preview-next/before-render.mjs +11 -37
  101. package/dist/preview-next/client/runtime.mjs +4 -4
  102. package/dist/preview-next/keepAlive.mjs +11 -37
  103. package/dist/preview-next/middleware.mjs +11 -37
  104. package/dist/{previewAuthStore-Gjb6r6vz.mjs → previewAuthStore-JA6-I_sL.mjs} +11 -37
  105. package/dist/{sdk-runtime-Defnbfzw.mjs → sdk-runtime-CDKl0Fr7.mjs} +2 -2
  106. package/dist/{separator-CZXO3Sb0.mjs → separator-BTp96X32.mjs} +1 -1
  107. package/dist/server/components.mjs +80 -51
  108. package/dist/server/config-validation.mjs +43 -14
  109. package/dist/server/config.mjs +43 -14
  110. package/dist/server/data.mjs +39 -13
  111. package/dist/server/index.mjs +12 -38
  112. package/dist/server/next.mjs +40 -53
  113. package/dist/server/page-converter.mjs +20 -8
  114. package/dist/server/prebuild.mjs +1 -1
  115. package/dist/server/rendering/server.mjs +80 -51
  116. package/dist/server/rendering.mjs +80 -51
  117. package/dist/server/routing.mjs +52 -17
  118. package/dist/server/server.mjs +40 -51
  119. package/dist/server/theme-bridge.mjs +10 -8
  120. package/dist/server/theme.mjs +10 -8
  121. package/package.json +1 -1
  122. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.d.ts +0 -14
  123. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.d.ts +0 -8
@@ -3327,7 +3327,10 @@ var init_contentMediaSnapshotAudit = __esmMin((() => {
3327
3327
  init_contentMediaAudit();
3328
3328
  init_contentMediaAuditFieldAdapter();
3329
3329
  init_identifiers();
3330
- })), init_src$1 = __esmMin((() => {
3330
+ }));
3331
+ //#endregion
3332
+ //#region ../media-core/src/index.ts
3333
+ var init_src$1 = __esmMin((() => {
3331
3334
  init_types$15();
3332
3335
  init_fileDomain();
3333
3336
  init_fileStorage();
@@ -3378,6 +3381,14 @@ var init_contentMediaSnapshotAudit = __esmMin((() => {
3378
3381
  init_contentMediaAudit();
3379
3382
  init_contentMediaAuditFieldAdapter();
3380
3383
  init_contentMediaSnapshotAudit();
3384
+ }));
3385
+ var footerModeSchema, init_mode = __esmMin((() => {
3386
+ footerModeSchema = z.enum([
3387
+ "default",
3388
+ "blocks",
3389
+ "default+blocks",
3390
+ "none"
3391
+ ]);
3381
3392
  })), hotspotSchema, rotationSchema, rectSchema, aspectCropSchema, transformSchema, mediaPosterSchema, mediaBaseSchema, mediaIdentifierSchema, imageMediaSchema, videoMediaSchema, audioMediaSchema, documentMediaSchema, spreadsheetMediaSchema, archiveMediaSchema, mediaSchema, persistableMediaBaseSchema;
3382
3393
  var init_media$2 = __esmMin((() => {
3383
3394
  hotspotSchema = z.object({
@@ -8035,8 +8046,9 @@ var init_boxBackgroundSchema = __esmMin((() => {
8035
8046
  showVideoOnMobile: z.boolean().nullable().optional()
8036
8047
  })
8037
8048
  ]);
8038
- })), axesSchema, typographyStyleSchema, bodyTypographyStyleSchema, headingSizeSchema, headingTypographyOverridesSchema, headingTypographyStyleSchema, proseLinkUnderlineStyleSchema, proseLinkUnderlineThicknessSchema, proseLinkUnderlineOffsetSchema, proseLinkStyleSchema, semanticSpacingSchema, boxRoundedSchema, noHeadingDecorationSchema, visibleHeadingDecorationSchema, headingDecorationSchema, headingDecorationOverrideSchema, accordionIconTreatmentSchema, sectionStylesOverrideSchema, containerStylesOverrideSchema, cardBorderOverrideSchema, cardStylesOverrideSchema, blockStyleOverridesSchema, blockThemeOverrideSchema, typographyScaleSchema, eyebrowTypographyStyleSchema, typographySchema, spaceSchema, corners, shadow, border, motion, inputStyle$1, headerPositioningValues, headerPositioning, headerNavStyle, navFontWeight, headerMaxWidth, headerBorderSchema, logoStyleSchema, headerLogoTextSchema, dropdownStyleSchema, headerCtaGapSchema, headerCtaTreatmentSchema, navContainerSchema, headerBackgroundSchema, headerSchema, footerVariant, footerMaxWidth, footerMode, footerNavLayoutMode, footerNavLayoutAlign, footerSpacing, footerLogoPlacement, footerLogoSize, footerLogoMaxHeight, footerBottomTextLinkStyleSchema, footerBottomBarSchema, footerNavLayoutSchema, footerLogoSchema, footerSchema, containerPaddingPresetSchema, layoutSchema, heroTypographySizeSchema, heroTypographyLineHeightSchema, heroResponsiveTypographySchema, heroTypographySchema, heroSchema, bodyTextIntroTypographySizeSchema, bodyTextSchema, testimonialQuoteTreatmentSchema, themeSchema;
8049
+ })), axesSchema, typographyStyleSchema, bodyTypographyStyleSchema, headingSizeSchema, headingTypographyOverridesSchema, headingTypographyStyleSchema, proseLinkUnderlineStyleSchema, proseLinkUnderlineThicknessSchema, proseLinkUnderlineOffsetSchema, proseLinkStyleSchema, semanticSpacingSchema, boxRoundedSchema, noHeadingDecorationSchema, visibleHeadingDecorationSchema, headingDecorationSchema, headingDecorationOverrideSchema, accordionIconTreatmentSchema, sectionStylesOverrideSchema, containerStylesOverrideSchema, cardBorderOverrideSchema, cardStylesOverrideSchema, blockStyleOverridesSchema, blockThemeOverrideSchema, typographyScaleSchema, eyebrowTypographyStyleSchema, typographySchema, spaceSchema, corners, shadow, border, motion, inputStyle$1, headerPositioningValues, headerPositioning, headerNavStyle, navFontWeight, headerMaxWidth, headerBorderSchema, logoStyleSchema, headerLogoTextSchema, dropdownStyleSchema, headerCtaGapSchema, headerCtaTreatmentSchema, navContainerSchema, headerBackgroundSchema, headerSchema, footerVariant, footerMaxWidth, footerNavLayoutMode, footerNavLayoutAlign, footerSpacing, footerLogoPlacement, footerLogoSize, footerLogoMaxHeight, footerBottomTextLinkStyleSchema, footerBottomBarSchema, footerNavLayoutSchema, footerLogoSchema, footerSchema, containerPaddingPresetSchema, layoutSchema, heroTypographySizeSchema, heroTypographyLineHeightSchema, heroResponsiveTypographySchema, heroTypographySchema, heroSchema, bodyTextIntroTypographySizeSchema, bodyTextSchema, testimonialQuoteTreatmentSchema, themeSchema;
8039
8050
  var init_schema$2 = __esmMin((() => {
8051
+ init_mode();
8040
8052
  init_media$2();
8041
8053
  init_schema$3();
8042
8054
  init_buttons();
@@ -8535,12 +8547,6 @@ var init_schema$2 = __esmMin((() => {
8535
8547
  "split"
8536
8548
  ]);
8537
8549
  footerMaxWidth = z.enum(["container", "full"]);
8538
- footerMode = z.enum([
8539
- "default",
8540
- "blocks",
8541
- "default+blocks",
8542
- "none"
8543
- ]);
8544
8550
  footerNavLayoutMode = z.enum([
8545
8551
  "stack",
8546
8552
  "inline",
@@ -8629,9 +8635,9 @@ var init_schema$2 = __esmMin((() => {
8629
8635
  /**
8630
8636
  * SDK-only footer rendering mode.
8631
8637
  *
8632
- * Backwards compatible: missing/undefined behaves as 'default'.
8638
+ * Historical persisted field; SDK rendering mode now lives in layout.footerMode.
8633
8639
  */
8634
- mode: footerMode.optional(),
8640
+ mode: footerModeSchema.optional(),
8635
8641
  variant: footerVariant,
8636
8642
  maxWidth: footerMaxWidth,
8637
8643
  showLogoText: z.boolean().optional(),
@@ -9199,6 +9205,15 @@ var init_schemas = __esmMin((() => {
9199
9205
  timeZone: z.string(),
9200
9206
  pricing: publicEventPricingSchema,
9201
9207
  paymentTerms: blockBookingPaymentTermsSchema,
9208
+ cancellationPolicy: z.object({ refunds: z.object({
9209
+ mode: z.enum([
9210
+ "never",
9211
+ "always",
9212
+ "cutoff"
9213
+ ]),
9214
+ cutoffHours: z.number(),
9215
+ method: z.enum(["original_payment_method", "site_credit"])
9216
+ }) }),
9202
9217
  consent: blockBookingConsentSchema.nullable(),
9203
9218
  accessRestriction: accessRestrictionSchema,
9204
9219
  allowedCategoryIds: z.array(z.string()),
@@ -9597,6 +9612,10 @@ var init_endpoints = __esmMin((() => {
9597
9612
  method: "POST",
9598
9613
  authScope: "portal"
9599
9614
  },
9615
+ registrationNextStep: {
9616
+ path: "/public/sites/{siteId}/events/registration-next-step",
9617
+ method: "POST"
9618
+ },
9600
9619
  registrationStatus: {
9601
9620
  path: "/public/sites/{siteId}/events/registration-status",
9602
9621
  method: "GET"
@@ -10179,6 +10198,13 @@ function createBlockApi(config) {
10179
10198
  body: data
10180
10199
  });
10181
10200
  },
10201
+ async checkRegistrationNextStep(data) {
10202
+ const path = buildPath(EVENTS.registrationNextStep.path, { siteId: requireSiteId() });
10203
+ return request(EVENTS.registrationNextStep, {
10204
+ path,
10205
+ body: data
10206
+ });
10207
+ },
10182
10208
  async getEventRegistrationStatus(params) {
10183
10209
  const sid = requireSiteId();
10184
10210
  const path = buildPath(EVENTS.registrationStatus.path, { siteId: sid });
@@ -28186,6 +28212,10 @@ var init_headerOpeningForeground = __esmMin((() => {
28186
28212
  init_colorTokenParts();
28187
28213
  init_types$8();
28188
28214
  }));
28215
+ var init_effectivePageDesign = __esmMin((() => {
28216
+ init_pageDesignIntent();
28217
+ init_siteStyleBlockPolicies();
28218
+ }));
28189
28219
  function validateBlockSequence(snapshots, ctx) {
28190
28220
  for (const issue of collectBlockSequenceIssues(snapshots)) ctx.addIssue(issue);
28191
28221
  }
@@ -28462,6 +28492,7 @@ var init_site_styles = __esmMin((() => {
28462
28492
  init_lookResolution();
28463
28493
  init_lookOptionGroups();
28464
28494
  init_logoBranding();
28495
+ init_effectivePageDesign();
28465
28496
  init_pageDesignAuthority();
28466
28497
  init_pageDesignEditorErrors();
28467
28498
  init_pageDesignEditorCapabilities();
@@ -33602,6 +33633,18 @@ var init_wizardSteps$1 = __esmMin((() => {
33602
33633
  }));
33603
33634
  //#endregion
33604
33635
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
33636
+ /** Public requests share subject identity without copying the run's display sessions. */
33637
+ function toRegistrationRequestSubject(subject, attendanceMode) {
33638
+ return subject.kind === "occurrence" ? {
33639
+ kind: "occurrence",
33640
+ occurrenceId: subject.occurrenceId,
33641
+ attendanceMode: attendanceMode ?? void 0
33642
+ } : {
33643
+ kind: "wholeSeries",
33644
+ eventSeriesId: subject.eventSeriesId,
33645
+ attendanceMode: attendanceMode ?? void 0
33646
+ };
33647
+ }
33605
33648
  function eventMatchesOccurrenceId(event, occurrenceId) {
33606
33649
  return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
33607
33650
  }
@@ -33831,6 +33874,7 @@ function shellLabelForRegistrationStep(step, events) {
33831
33874
  case "redirecting":
33832
33875
  case "verifying-payment":
33833
33876
  case "verifying-timeout":
33877
+ case "payment-status":
33834
33878
  case "payment-failed": return "Details";
33835
33879
  }
33836
33880
  }
@@ -46803,7 +46847,7 @@ var init_eventPaymentOptions = __esmMin((() => {
46803
46847
  //#endregion
46804
46848
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationStateMachine.ts
46805
46849
  function hasBlockingExistingRegistration(input) {
46806
- return !input.hasWaitlistClaim && input.isAuthenticated && input.registration.kind !== "none";
46850
+ return !input.hasWaitlistClaim && input.isAuthenticated && input.registration.kind === "waitlisted";
46807
46851
  }
46808
46852
  function createInitialRegistrationFlowState(hasPreSelectedContext) {
46809
46853
  return {
@@ -46855,7 +46899,7 @@ function computeAutoSelection(input) {
46855
46899
  return { method: null };
46856
46900
  }
46857
46901
  function computeDirectPaymentSelection(eligibility) {
46858
- if (!eligibility?.canPayDirectly) return { method: null };
46902
+ if (!eligibility?.requiresPayment) return { method: null };
46859
46903
  const approvedKinds = getApprovedDirectPaymentCollectionOptionKinds(eligibility.paymentOptions);
46860
46904
  const collectionOptionKind = approvedKinds.includes("upfront") ? "upfront" : approvedKinds[0];
46861
46905
  return collectionOptionKind ? {
@@ -46869,7 +46913,7 @@ function isSelectionValid(input) {
46869
46913
  if (!eligibility) return selection.method === "stripe" || selection.method === "pass_bundle" || selection.method === "membership_bundle";
46870
46914
  switch (selection.method) {
46871
46915
  case "free": return eligibility.isFree;
46872
- case "stripe": return Boolean(eligibility.canPayDirectly && eligibility.price);
46916
+ case "stripe": return Boolean(eligibility.requiresPayment && eligibility.price);
46873
46917
  case "pass": return isAuthenticated && ticketsCount === 1 && !!selection.passId && eligibility.eligiblePasses.some((pass) => pass.id === selection.passId);
46874
46918
  case "membership": return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some((membership) => membership.id === selection.membershipId);
46875
46919
  case "pass_bundle": return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some((pass) => pass.id === selection.bundlePassId);
@@ -46888,7 +46932,7 @@ function normalizeRegistrationFlowState(state) {
46888
46932
  ticketsCount: state.ticketsCount,
46889
46933
  passOptOut: nextPassOptOut
46890
46934
  });
46891
- const canKeepManualSelection = state.step === "select-payment" && state.selectionSource === "manual" && isSelectionValid({
46935
+ const canKeepManualSelection = state.step !== "select-tickets" && state.selectionSource === "manual" && isSelectionValid({
46892
46936
  selection: state.paymentSelection,
46893
46937
  isAuthenticated: state.isAuthenticated,
46894
46938
  eligibility: state.eligibility,
@@ -46980,7 +47024,7 @@ function resolveEventRegistrationSubmitPlan(input) {
46980
47024
  const selection = input.paymentSelection.method ? input.paymentSelection : void 0;
46981
47025
  if (input.canJoinWaitlist) return {
46982
47026
  ok: true,
46983
- args: withOptionalSelection({ method: "free" }, selection)
47027
+ args: { method: "free" }
46984
47028
  };
46985
47029
  switch (input.paymentSelection.method) {
46986
47030
  case "pass": return input.paymentSelection.passId ? {
@@ -47049,92 +47093,55 @@ var init_event_registration_headless_state = __esmMin((() => {
47049
47093
  init_event_registration_headless_planning();
47050
47094
  }));
47051
47095
  //#endregion
47052
- //#region ../blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.ts
47053
- /** Recovery may select held places; checkout still owns admission and payment validation. */
47054
- function checkoutRecoveryOptionAvailability(availability) {
47055
- if (availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable") return {
47056
- kind: "available",
47057
- remainingPlaces: null
47058
- };
47059
- return availability;
47096
+ //#region ../blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.ts
47097
+ /** Ticket selection requests a quote; only the server admits a booking. */
47098
+ function canRequestTicketOption(availability) {
47099
+ return availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable";
47060
47100
  }
47061
- /**
47062
- * A form-only projection for the explicit existing-checkout path. It permits
47063
- * collecting the original selection without claiming a new place is available.
47064
- * The public checkout service identifies the customer and remains the admission
47065
- * authority; no reservation/customer data is exposed through this projection.
47066
- */
47067
- function getCheckoutRecoveryFormEligibility(eligibility) {
47068
- if (!eligibility || eligibility.registration.kind !== "none" && eligibility.registration.kind !== "pending_payment" || eligibility.availability.kind === "unavailable" && eligibility.availability.reason !== "full" && eligibility.availability.reason !== "selectionRequired") return eligibility;
47069
- const amountCents = eligibility.price ?? 0;
47070
- if (amountCents <= 0 || !eligibility.currency || eligibility.availability.kind === "unavailable" && eligibility.availability.reason === "selectionRequired") return eligibility.registration.kind === "pending_payment" ? {
47071
- ...eligibility,
47072
- registration: { kind: "none" },
47073
- ticketTypes: eligibility.ticketTypes.map((option) => ({
47074
- ...option,
47075
- availability: checkoutRecoveryOptionAvailability(option.availability)
47076
- }))
47077
- } : eligibility;
47078
- const currency = eligibility.currency;
47079
- const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
47080
- switch (option.kind) {
47081
- case "upfront": return {
47082
- kind: "payInFull",
47083
- amountCents,
47084
- currency
47085
- };
47086
- case "deferred_manual": return {
47087
- kind: "deferredManual",
47088
- amountCents,
47089
- currency
47090
- };
47091
- case "instalment_plan": return {
47092
- kind: "instalmentPlan",
47093
- amountCents,
47094
- currency
47095
- };
47096
- case "flexible_balance": return {
47097
- kind: "flexibleBalance",
47098
- amountCents,
47099
- currency
47100
- };
47101
- }
47102
- });
47103
- return {
47104
- ...eligibility,
47105
- registration: { kind: "none" },
47106
- availability: {
47107
- kind: "available",
47108
- remainingPlaces: null,
47109
- waitlistEnabled: eligibility.waitlistEnabled
47110
- },
47111
- eligible: paymentOptions.length > 0,
47112
- isFull: false,
47113
- canJoinWaitlist: false,
47114
- isFree: false,
47115
- requiresPayment: true,
47116
- canPayDirectly: paymentOptions.length > 0,
47117
- paymentOptions,
47118
- eligiblePasses: [],
47119
- eligibleMemberships: [],
47120
- ticketTypes: eligibility.ticketTypes.map((option) => ({
47121
- ...option,
47122
- availability: checkoutRecoveryOptionAvailability(option.availability)
47123
- }))
47124
- };
47101
+ function normalizeTicketSelectionLines(lines) {
47102
+ const quantitiesByTicketType = /* @__PURE__ */ new Map();
47103
+ for (const line of lines) {
47104
+ const quantity = Math.floor(line.quantity);
47105
+ if (quantity <= 0) continue;
47106
+ const key = line.pricingOptionId ?? null;
47107
+ quantitiesByTicketType.set(key, (quantitiesByTicketType.get(key) ?? 0) + quantity);
47108
+ }
47109
+ return [...quantitiesByTicketType.entries()].map(([pricingOptionId, quantity]) => ({
47110
+ pricingOptionId,
47111
+ quantity
47112
+ }));
47125
47113
  }
47126
- function isSoldOutEventSelectable(event, waitlistAvailable) {
47127
- return waitlistAvailable || canRecoverEventCheckout(event);
47114
+ function getTicketSelectionTotal(lines) {
47115
+ return normalizeTicketSelectionLines(lines).reduce((total, line) => total + line.quantity, 0);
47128
47116
  }
47129
- function canJoinWaitlistOutsideRecovery(event, attendanceMode, checkoutRecovery) {
47130
- return !checkoutRecovery && event !== null && canJoinEventWaitlist(event, { attendanceMode });
47117
+ function getTicketLineQuantity(lines, pricingOptionId) {
47118
+ return normalizeTicketSelectionLines(lines).find((line) => line.pricingOptionId === pricingOptionId)?.quantity ?? 0;
47131
47119
  }
47132
- function canRecoverEventCheckout(event) {
47133
- return event !== null && (event.registrationSubject.kind === "wholeSeries" || event.pricing.kind !== "free" && event.pricing.kind !== "external");
47120
+ function getSingleSelectedPricingOptionId(lines) {
47121
+ const normalized = normalizeTicketSelectionLines(lines);
47122
+ return normalized.length === 1 ? normalized[0]?.pricingOptionId ?? null : null;
47134
47123
  }
47135
- var init_checkoutRecovery = __esmMin((() => {
47136
- init_domain();
47137
- }));
47124
+ function hasValidPricingOptionSelection(input) {
47125
+ if (!input.selectionRequired) return true;
47126
+ if (input.lines.length === 0) return false;
47127
+ const availableOptionIds = new Set(input.visibleOptions.filter((option) => canRequestTicketOption(option.availability)).map((option) => option.pricingOptionId));
47128
+ return input.lines.every((line) => line.pricingOptionId !== null && availableOptionIds.has(line.pricingOptionId));
47129
+ }
47130
+ function setTicketLineQuantity(input) {
47131
+ const nextQuantity = Math.max(0, Math.floor(input.quantity));
47132
+ const normalized = normalizeTicketSelectionLines(input.lines).filter((line) => line.pricingOptionId !== input.pricingOptionId);
47133
+ if (nextQuantity <= 0) return normalized;
47134
+ return [...normalized, {
47135
+ pricingOptionId: input.pricingOptionId,
47136
+ quantity: nextQuantity
47137
+ }];
47138
+ }
47139
+ function getTicketTypeLineMax(input) {
47140
+ const otherSelectedQuantity = input.totalSelectedQuantity - input.currentQuantity;
47141
+ const maxByBlock = input.maxTickets - otherSelectedQuantity;
47142
+ return Math.max(0, maxByBlock);
47143
+ }
47144
+ var init_ticketSelectionLines = __esmMin((() => {}));
47138
47145
  //#endregion
47139
47146
  //#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
47140
47147
  function getPortalSubjectEmail(profile) {
@@ -47198,8 +47205,6 @@ function formatPassCreditUsageLabel(creditsRemaining) {
47198
47205
  return `Uses 1 of ${creditsRemaining} credits`;
47199
47206
  }
47200
47207
  function transformRegistrationOptionsResponse(response) {
47201
- const canJoinWaitlist = response.availability.kind === "waitlist";
47202
- const isFull = response.availability.remainingPlaces === 0 || response.availability.kind === "unavailable" && response.availability.reason === "full";
47203
47208
  const eligiblePasses = response.entitlements.passes.map((pass) => ({
47204
47209
  id: pass.customerPassId,
47205
47210
  passName: pass.passName,
@@ -47212,7 +47217,6 @@ function transformRegistrationOptionsResponse(response) {
47212
47217
  const eventAcceptsPasses = response.entitlements.requiresLoginForPasses || eligiblePasses.length > 0 || response.entitlements.availableForPurchase.passes.length > 0;
47213
47218
  const eventAcceptsMemberships = response.entitlements.requiresLoginForMemberships || eligibleMemberships.length > 0 || response.entitlements.availableForPurchase.memberships.length > 0;
47214
47219
  const monetaryPaymentAvailable = hasMonetaryPaymentOption(response);
47215
- const registrationAvailable = response.availability.kind === "available" || response.availability.kind === "waitlist";
47216
47220
  return {
47217
47221
  availability: response.availability,
47218
47222
  registration: response.registration,
@@ -47227,7 +47231,6 @@ function transformRegistrationOptionsResponse(response) {
47227
47231
  },
47228
47232
  transactions: []
47229
47233
  } : null,
47230
- eligible: response.registration.kind === "none" && registrationAvailable,
47231
47234
  requiresPayment: monetaryPaymentAvailable,
47232
47235
  pricingStrategy: response.pricing.strategy,
47233
47236
  paymentTerms: response.pricing.paymentTerms,
@@ -47242,16 +47245,12 @@ function transformRegistrationOptionsResponse(response) {
47242
47245
  currency: response.pricing.currency
47243
47246
  })),
47244
47247
  ticketTypes: response.pricing.options,
47245
- isFull,
47246
- waitlistEnabled: response.availability.waitlistEnabled,
47247
- canJoinWaitlist,
47248
47248
  price: response.pricing.subtotalCents,
47249
47249
  currency: response.pricing.currency,
47250
47250
  requiresAuthForPasses: response.entitlements.requiresLoginForPasses,
47251
47251
  requiresAuthForMemberships: response.entitlements.requiresLoginForMemberships,
47252
47252
  eligiblePasses,
47253
47253
  eligibleMemberships,
47254
- canPayDirectly: monetaryPaymentAvailable,
47255
47254
  eventAcceptsPasses,
47256
47255
  eventAcceptsMemberships,
47257
47256
  availablePasses: [...response.entitlements.availableForPurchase.passes],
@@ -47281,8 +47280,8 @@ function getVisibleTicketTypes(input) {
47281
47280
  })) : [];
47282
47281
  return (input.eligibility?.ticketTypes ?? eventTicketTypes).filter((ticketType) => ticketType.isActive && (!input.selectedAttendanceMode || (ticketType.attendanceScope ?? "both") === "both" || (ticketType.attendanceScope ?? "both") === input.selectedAttendanceMode));
47283
47282
  }
47284
- function getImplicitSingleAvailableTicketType(ticketTypes) {
47285
- return ticketTypes.length === 1 && ticketTypes[0]?.availability.kind === "available" ? ticketTypes[0] : null;
47283
+ function getImplicitSingleTicketType(ticketTypes) {
47284
+ return ticketTypes.length === 1 && ticketTypes[0] && canRequestTicketOption(ticketTypes[0].availability) ? ticketTypes[0] : null;
47286
47285
  }
47287
47286
  function findSelectedTicketType(input) {
47288
47287
  if (!input.selectedPricingOptionId) return null;
@@ -47295,6 +47294,7 @@ function findSelectedTicketType(input) {
47295
47294
  var ENTITLEMENT_SINGLE_TICKET_TOOLTIP;
47296
47295
  var init_utils = __esmMin((() => {
47297
47296
  init_src$2();
47297
+ init_ticketSelectionLines();
47298
47298
  init_shared();
47299
47299
  ENTITLEMENT_SINGLE_TICKET_TOOLTIP = "Only available for single-ticket bookings";
47300
47300
  }));
@@ -47307,7 +47307,6 @@ function getEventSelectionMode(events) {
47307
47307
  }
47308
47308
  var EventSelectionStep;
47309
47309
  var init_EventSelectionStep = __esmMin((() => {
47310
- init_checkoutRecovery();
47311
47310
  init_utils();
47312
47311
  init_domain();
47313
47312
  EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCapacity }) => {
@@ -47324,25 +47323,19 @@ var init_EventSelectionStep = __esmMin((() => {
47324
47323
  const remaining = getRemainingPlaces(selectMostOpenCapacitySource(event));
47325
47324
  const isSoldOut = isEventFull(event);
47326
47325
  const canJoinWaitlist = canJoinEventWaitlistOnAnyMode(event);
47327
- const isUnavailable = isSoldOut && !isSoldOutEventSelectable(event, canJoinWaitlist);
47328
47326
  const isLowCapacity = remaining.kind === "low";
47329
47327
  const capacityLabel = formatEventRemainingPlaces(event, { full: "Sold out" });
47330
47328
  const timeZone = event.timeZone ?? null;
47331
- const cardClasses = [
47332
- "er-event-card",
47333
- isSelected && "er-event-card--selected",
47334
- isUnavailable && "er-event-card--disabled"
47335
- ].filter(Boolean).join(" ");
47329
+ const cardClasses = ["er-event-card", isSelected && "er-event-card--selected"].filter(Boolean).join(" ");
47336
47330
  const badgeClasses = [
47337
47331
  "er-capacity-badge",
47338
- isUnavailable && "er-capacity-badge--soldout",
47332
+ isSoldOut && "er-capacity-badge--soldout",
47339
47333
  isLowCapacity && "er-capacity-badge--low",
47340
- (canJoinWaitlist || !isUnavailable && !isLowCapacity) && "er-capacity-badge--available"
47334
+ (canJoinWaitlist || !isSoldOut && !isLowCapacity) && "er-capacity-badge--available"
47341
47335
  ].filter(Boolean).join(" ");
47342
47336
  return /* @__PURE__ */ jsx("button", {
47343
47337
  type: "button",
47344
- onClick: () => !isUnavailable && onSelect(event),
47345
- disabled: isUnavailable,
47338
+ onClick: () => onSelect(event),
47346
47339
  className: cardClasses,
47347
47340
  children: /* @__PURE__ */ jsxs("div", {
47348
47341
  className: "er-event-option",
@@ -47370,44 +47363,15 @@ var init_EventSelectionStep = __esmMin((() => {
47370
47363
  };
47371
47364
  }));
47372
47365
  //#endregion
47373
- //#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
47374
- /** Recovery belongs to the selected booking subject; changing events resets its scope. */
47375
- function useCheckoutRecovery(event, setStep) {
47376
- const [recoveryEventId, setRecoveryEventId] = useState(null);
47377
- return {
47378
- checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
47379
- startCheckoutRecovery: useCallback(() => {
47380
- if (!event) return;
47381
- setRecoveryEventId(event.selectionId);
47382
- setStep("select-tickets");
47383
- }, [event, setStep])
47384
- };
47385
- }
47386
- /** Authenticated pending bookings enter the same form-only recovery path as guests. */
47387
- function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
47388
- const registrationKind = eligibility?.registration.kind;
47389
- useEffect(() => {
47390
- if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
47391
- }, [
47392
- registrationKind,
47393
- step,
47394
- checkoutRecovery,
47395
- startCheckoutRecovery
47396
- ]);
47397
- return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
47398
- }
47399
- var init_useCheckoutRecovery = __esmMin((() => {
47400
- init_checkoutRecovery();
47401
- }));
47402
- //#endregion
47403
47366
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
47404
47367
  function resolveRegistrationRecoveryAction(step, action) {
47405
47368
  if (step === "payment-failed") return "payment-options";
47406
- if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "payment-status";
47369
+ if (step === "payment-status") return "none";
47370
+ if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "none";
47407
47371
  return action;
47408
47372
  }
47409
47373
  function canRecoverToWaitlist(eligibility) {
47410
- return Boolean(eligibility?.isFull && eligibility.canJoinWaitlist);
47374
+ return eligibility?.availability.kind === "waitlist" && eligibility.registration.kind !== "pending_payment";
47411
47375
  }
47412
47376
  function shouldRefreshAfterRegistrationError(step, action, enabled) {
47413
47377
  return enabled || step === "error" && action === "places";
@@ -47424,19 +47388,19 @@ function resetRegistrationAfterExpiry(input) {
47424
47388
  input.setErrorMessage("");
47425
47389
  input.setPendingRegistrationReference(null);
47426
47390
  }
47427
- /** Recovery never starts another payment. Unknown payment outcomes go to the portal. */
47391
+ /** Retry the retained submission in place; explicit payment uncertainty stays status-only. */
47428
47392
  function recoverRegistrationError(action, handlers) {
47429
47393
  switch (action) {
47430
47394
  case "none": return;
47431
47395
  case "portal":
47432
- case "payment-status":
47433
47396
  window.location.assign("/portal");
47434
47397
  return;
47435
47398
  case "event":
47436
47399
  window.location.assign(window.location.pathname);
47437
47400
  return;
47438
47401
  case "retry":
47439
- window.location.reload();
47402
+ handlers.clearError();
47403
+ handlers.setStep("select-payment");
47440
47404
  return;
47441
47405
  case "details":
47442
47406
  handlers.clearError();
@@ -47476,54 +47440,6 @@ function validateFormData(formData, requiresConsent = false) {
47476
47440
  }
47477
47441
  var init_validation = __esmMin((() => {}));
47478
47442
  //#endregion
47479
- //#region ../blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.ts
47480
- function normalizeTicketSelectionLines(lines) {
47481
- const quantitiesByTicketType = /* @__PURE__ */ new Map();
47482
- for (const line of lines) {
47483
- const quantity = Math.floor(line.quantity);
47484
- if (quantity <= 0) continue;
47485
- const key = line.pricingOptionId ?? null;
47486
- quantitiesByTicketType.set(key, (quantitiesByTicketType.get(key) ?? 0) + quantity);
47487
- }
47488
- return [...quantitiesByTicketType.entries()].map(([pricingOptionId, quantity]) => ({
47489
- pricingOptionId,
47490
- quantity
47491
- }));
47492
- }
47493
- function getTicketSelectionTotal(lines) {
47494
- return normalizeTicketSelectionLines(lines).reduce((total, line) => total + line.quantity, 0);
47495
- }
47496
- function getTicketLineQuantity(lines, pricingOptionId) {
47497
- return normalizeTicketSelectionLines(lines).find((line) => line.pricingOptionId === pricingOptionId)?.quantity ?? 0;
47498
- }
47499
- function getSingleSelectedPricingOptionId(lines) {
47500
- const normalized = normalizeTicketSelectionLines(lines);
47501
- return normalized.length === 1 ? normalized[0]?.pricingOptionId ?? null : null;
47502
- }
47503
- function hasValidPricingOptionSelection(input) {
47504
- if (!input.selectionRequired) return true;
47505
- if (input.lines.length === 0) return false;
47506
- const availableOptionIds = new Set(input.visibleOptions.filter((option) => option.availability.kind === "available").map((option) => option.pricingOptionId));
47507
- return input.lines.every((line) => line.pricingOptionId !== null && availableOptionIds.has(line.pricingOptionId));
47508
- }
47509
- function setTicketLineQuantity(input) {
47510
- const nextQuantity = Math.max(0, Math.floor(input.quantity));
47511
- const normalized = normalizeTicketSelectionLines(input.lines).filter((line) => line.pricingOptionId !== input.pricingOptionId);
47512
- if (nextQuantity <= 0) return normalized;
47513
- return [...normalized, {
47514
- pricingOptionId: input.pricingOptionId,
47515
- quantity: nextQuantity
47516
- }];
47517
- }
47518
- function getTicketTypeLineMax(input) {
47519
- const otherSelectedQuantity = input.totalSelectedQuantity - input.currentQuantity;
47520
- const maxByBlock = input.maxTickets - otherSelectedQuantity;
47521
- const maxByEvent = input.availableSpots == null ? input.maxTickets : input.availableSpots - otherSelectedQuantity;
47522
- const maxByTicketType = input.ticketTypeRemainingCapacity ?? input.maxTickets;
47523
- return Math.max(0, Math.min(maxByBlock, maxByEvent, maxByTicketType));
47524
- }
47525
- var init_ticketSelectionLines = __esmMin((() => {}));
47526
- //#endregion
47527
47443
  //#region ../blocks/src/system/runtime/nodes/event-registration/hooks.state.ts
47528
47444
  function eligibilityLookupReducer(state, action) {
47529
47445
  switch (action.type) {
@@ -47635,17 +47551,6 @@ function usePortalAuthWithDeps(deps) {
47635
47551
  logout
47636
47552
  };
47637
47553
  }
47638
- function toRegistrationOptionsSubject(subject, attendanceMode) {
47639
- return subject.kind === "occurrence" ? {
47640
- kind: "occurrence",
47641
- occurrenceId: subject.occurrenceId,
47642
- attendanceMode: attendanceMode ?? void 0
47643
- } : {
47644
- kind: "wholeSeries",
47645
- eventSeriesId: subject.eventSeriesId,
47646
- attendanceMode: attendanceMode ?? void 0
47647
- };
47648
- }
47649
47554
  function useEligibility(params) {
47650
47555
  return useEligibilityWithDeps(params, eventRegistrationHooksDeps);
47651
47556
  }
@@ -47686,7 +47591,7 @@ function useEligibilityWithDeps(params, deps) {
47686
47591
  requestIdRef.current = requestId;
47687
47592
  dispatch({ type: "loading-started" });
47688
47593
  try {
47689
- const subject = toRegistrationOptionsSubject(params.subject, params.attendanceMode);
47594
+ const subject = toRegistrationRequestSubject(params.subject, params.attendanceMode);
47690
47595
  const result = await api.getRegistrationOptions({
47691
47596
  subject,
47692
47597
  selections: ticketSelections.map((selection) => ({
@@ -47808,6 +47713,7 @@ var init_hooks = __esmMin((() => {
47808
47713
  init_api();
47809
47714
  init_utils();
47810
47715
  init_ticketSelectionLines();
47716
+ init_registrationDerivations();
47811
47717
  init_hooks_state();
47812
47718
  eventRegistrationHooksDeps = { useBlockApi };
47813
47719
  REGISTRATION_OPTIONS_DEBOUNCE_MS = 150;
@@ -48151,7 +48057,6 @@ var init_stripeCommissionMetadata = __esmMin((() => {
48151
48057
  "no_commission_plan",
48152
48058
  "billing_evidence_invalid",
48153
48059
  "fee_rounds_to_zero",
48154
- "non_commissionable_scope",
48155
48060
  "payment_not_stripe"
48156
48061
  ];
48157
48062
  historicalContext = {
@@ -48275,7 +48180,6 @@ var init_stripeMinimumCharge = __esmMin((() => {
48275
48180
  var init_stripeCheckoutReturnUrl = __esmMin((() => {}));
48276
48181
  var init_stateTransitions = __esmMin((() => {
48277
48182
  init_src$2();
48278
- init_assertNever();
48279
48183
  }));
48280
48184
  //#endregion
48281
48185
  //#region ../commerce/src/purchase/event-registration-errors.ts
@@ -48289,9 +48193,9 @@ var init_event_registration_errors = __esmMin((() => {
48289
48193
  message: "Booking is currently closed for this event. Please contact the organiser if you’d like to find out more.",
48290
48194
  action: "none"
48291
48195
  },
48292
- paymentUncertain: {
48293
- message: "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.",
48294
- action: "payment-status"
48196
+ paymentInvestigationRequired: {
48197
+ message: "We still can’t confirm your payment. Please don’t make another payment. Contact the organiser so they can check your booking.",
48198
+ action: "none"
48295
48199
  },
48296
48200
  paymentProviderUnavailable: {
48297
48201
  message: "We couldn’t reach the payment provider. Please try again in a minute.",
@@ -48343,6 +48247,7 @@ var init_event_registration_errors = __esmMin((() => {
48343
48247
  }
48344
48248
  };
48345
48249
  }));
48250
+ var init_eventCheckoutRecoveryWindow = __esmMin((() => {}));
48346
48251
  //#endregion
48347
48252
  //#region ../commerce/src/purchase/index.ts
48348
48253
  var init_purchase = __esmMin((() => {
@@ -48404,6 +48309,7 @@ var init_purchase = __esmMin((() => {
48404
48309
  init_stripeCheckoutReturnUrl();
48405
48310
  init_stateTransitions();
48406
48311
  init_event_registration_errors();
48312
+ init_eventCheckoutRecoveryWindow();
48407
48313
  init_stripeCommissionMetadata();
48408
48314
  }));
48409
48315
  //#endregion
@@ -48842,7 +48748,30 @@ function checkoutReturnCommand(params) {
48842
48748
  };
48843
48749
  return null;
48844
48750
  }
48845
- async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
48751
+ function handleCheckoutReturnOutcome(options, deps, context, outcome) {
48752
+ const { pending, params } = context;
48753
+ if (outcome.kind === "resolved") {
48754
+ deps.clearReturnParams();
48755
+ options.setPendingRegistrationReference(outcome.reference);
48756
+ options.setStep("verifying-payment");
48757
+ return "settled";
48758
+ }
48759
+ if (outcome.kind === "abandoned") {
48760
+ deps.clearReturnParams();
48761
+ options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
48762
+ options.setStep("select-payment");
48763
+ return "settled";
48764
+ }
48765
+ if (outcome.kind === "notFound" && params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
48766
+ deps.clearReturnParams();
48767
+ options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
48768
+ options.setStep("select-payment");
48769
+ return "settled";
48770
+ }
48771
+ showReturnReconciliation(options, "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.");
48772
+ return outcome.kind === "notFound" ? "settled" : "retryable";
48773
+ }
48774
+ async function handleCheckoutReturn(options, deps, returnContextRef) {
48846
48775
  deps.cleanupStaleRegistrations();
48847
48776
  const params = deps.readReturnParams();
48848
48777
  if (params.registration !== "cancelled" && params.registration !== "success") return "settled";
@@ -48856,34 +48785,15 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
48856
48785
  }
48857
48786
  const { checkoutAttemptId } = command;
48858
48787
  const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
48859
- checkoutAttemptIdRef.current = checkoutAttemptId;
48788
+ returnContextRef.current = { checkoutAttemptId };
48860
48789
  if (pending) restorePendingPresentation(options, pending);
48861
48790
  options.setStep("verifying-payment");
48862
48791
  try {
48863
48792
  const outcome = await options.api.resolveEventCheckoutReturn(command);
48864
- switch (outcome.kind) {
48865
- case "resolved":
48866
- deps.clearReturnParams();
48867
- options.setPendingRegistrationReference(outcome.reference);
48868
- options.setStep("verifying-payment");
48869
- return "settled";
48870
- case "abandoned":
48871
- deps.clearReturnParams();
48872
- options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
48873
- options.setStep("select-payment");
48874
- return "settled";
48875
- case "notFound":
48876
- if (params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
48877
- deps.clearReturnParams();
48878
- options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
48879
- options.setStep("select-payment");
48880
- return "settled";
48881
- }
48882
- showReturnReconciliation(options, "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.");
48883
- return "settled";
48884
- case "reconciliationRequired": break;
48885
- }
48886
- showReturnReconciliation(options, "We’re checking your booking and payment. Please don’t try to book again yet. If you’ve already paid, you don’t need to pay again.");
48793
+ return handleCheckoutReturnOutcome(options, deps, {
48794
+ pending,
48795
+ params
48796
+ }, outcome);
48887
48797
  } catch {
48888
48798
  showReturnReconciliation(options, "We couldn’t check your payment just now. Please check again in a moment. Don’t make another booking while we’re checking.");
48889
48799
  }
@@ -48892,9 +48802,16 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
48892
48802
  function useEventRegistrationStripeReturn(options) {
48893
48803
  return useEventRegistrationStripeReturnWithDeps(options, eventRegistrationStripeReturnDeps);
48894
48804
  }
48805
+ function completeVerifiedRegistration(options, deps, returnContext) {
48806
+ const siteId = options.api.config.siteId;
48807
+ const checkoutAttemptId = returnContext?.checkoutAttemptId;
48808
+ if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
48809
+ options.setRegistrationResult({ status: "confirmed" });
48810
+ options.setStep("success");
48811
+ }
48895
48812
  function useEventRegistrationStripeReturnWithDeps(options, deps) {
48896
48813
  const { api, pendingRegistrationReference, setErrorMessage, setRegistrationResult, setStep, step } = options;
48897
- const checkoutAttemptIdRef = useRef(null);
48814
+ const returnContextRef = useRef(null);
48898
48815
  const lookupInFlightRef = useRef(false);
48899
48816
  const [lookupState, setLookupState] = useState("settled");
48900
48817
  const resolveReturn = useCallback(async () => {
@@ -48902,7 +48819,7 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
48902
48819
  lookupInFlightRef.current = true;
48903
48820
  setLookupState("loading");
48904
48821
  try {
48905
- setLookupState(await handleCheckoutReturn(options, deps, checkoutAttemptIdRef));
48822
+ setLookupState(await handleCheckoutReturn(options, deps, returnContextRef));
48906
48823
  } finally {
48907
48824
  lookupInFlightRef.current = false;
48908
48825
  }
@@ -48925,13 +48842,8 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
48925
48842
  resolveReturn();
48926
48843
  }, []);
48927
48844
  useEffect(() => {
48928
- if (verification.status === "completed") {
48929
- const siteId = api.config.siteId;
48930
- const checkoutAttemptId = checkoutAttemptIdRef.current;
48931
- if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
48932
- setRegistrationResult({ status: "confirmed" });
48933
- setStep("success");
48934
- } else if (verification.status === "failed") {
48845
+ if (verification.status === "completed") completeVerifiedRegistration(options, deps, returnContextRef.current);
48846
+ else if (verification.status === "failed") {
48935
48847
  setErrorMessage("Please try again or choose another payment option. If this keeps happening, contact the organiser for help.");
48936
48848
  setStep("payment-failed");
48937
48849
  } else if (verification.status === "timeout") setStep("verifying-timeout");
@@ -48990,7 +48902,10 @@ function registrationErrorPresentation(error) {
48990
48902
  const reason = error instanceof BlockApiError ? parseEventRegistrationErrorReason(error.tag) : null;
48991
48903
  if (reason) return eventRegistrationErrors[reason];
48992
48904
  if (error instanceof BlockApiError && error.status < 500) return eventRegistrationErrors.invalidCommitInput;
48993
- return eventRegistrationErrors.paymentUncertain;
48905
+ return {
48906
+ message: "Something went wrong. Please try again.",
48907
+ action: "retry"
48908
+ };
48994
48909
  }
48995
48910
  var init_registrationErrorPresentation = __esmMin((() => {
48996
48911
  init_purchase();
@@ -49019,26 +48934,6 @@ function useEventRegistrationSubmit(options) {
49019
48934
  * and the balance left, which the block's copy cannot. Every other method keeps
49020
48935
  * whatever success message the site configured.
49021
48936
  */
49022
- function toRegistrationResult(result) {
49023
- if (result.alreadyRegistered) {
49024
- const waitlisted = result.status === "waitlist";
49025
- return {
49026
- status: result.status,
49027
- variant: "info",
49028
- title: waitlisted ? "Already waitlisted" : "Already registered",
49029
- message: result.message ?? (waitlisted ? "You are already on the waitlist for this event." : "You are already registered for this event.")
49030
- };
49031
- }
49032
- if (result.status === "waitlist") return {
49033
- status: "waitlist",
49034
- title: "Added to waitlist",
49035
- message: result.message ?? (typeof result.waitlistPosition === "number" ? `You've been added to the waitlist (position ${result.waitlistPosition}).` : "You've been added to the waitlist.")
49036
- };
49037
- return {
49038
- status: result.status,
49039
- message: result.paymentMethod === "pass" ? result.message : void 0
49040
- };
49041
- }
49042
48937
  function useEventRegistrationSubmitWithDeps(options, deps) {
49043
48938
  /**
49044
48939
  * The command identity for the submission currently in progress.
@@ -49052,7 +48947,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
49052
48947
  * Identical retries retain the command after a lost response. Changed form
49053
48948
  * details get a new command so the server applies the new booking intent.
49054
48949
  */
49055
- const commandRef = useRef(null);
48950
+ const { commandRef } = options;
49056
48951
  const inFlightRef = useRef(null);
49057
48952
  const submit = async (method, passId, membershipId, selection, submitOptions) => {
49058
48953
  const target = options.registrationTarget;
@@ -49065,19 +48960,15 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
49065
48960
  const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
49066
48961
  try {
49067
48962
  let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
49068
- if (prepared.subject.kind === "wholeSeries" && method === "stripe") {
49069
- commandRef.current = null;
49070
- return await submitWholeSeriesCheckout(options, deps, {
48963
+ let request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
48964
+ const intentKey = registrationRequestIntentKey(request);
48965
+ if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) {
48966
+ prepared = {
49071
48967
  ...prepared,
49072
- subject: prepared.subject
49073
- }, submitOptions);
48968
+ registrationCommandId: deps.createClientCommandId()
48969
+ };
48970
+ request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
49074
48971
  }
49075
- const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
49076
- const intentKey = registrationRequestIntentKey(request);
49077
- if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
49078
- ...prepared,
49079
- registrationCommandId: deps.createClientCommandId()
49080
- };
49081
48972
  commandRef.current = {
49082
48973
  id: prepared.registrationCommandId,
49083
48974
  intentKey
@@ -49086,8 +48977,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
49086
48977
  ...request,
49087
48978
  registrationCommandId: prepared.registrationCommandId
49088
48979
  });
49089
- commandRef.current = null;
49090
- return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
48980
+ return await completeRegistrationSubmission(options, deps, prepared, result, submitOptions);
49091
48981
  } catch (error) {
49092
48982
  if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
49093
48983
  const { message, action } = registrationErrorPresentation(error);
@@ -49111,9 +49001,40 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
49111
49001
  return pending;
49112
49002
  };
49113
49003
  }
49114
- async function completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions) {
49115
- if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
49116
- options.setRegistrationResult(toRegistrationResult(result));
49004
+ async function completeRegistrationSubmission(options, deps, prepared, result, submitOptions) {
49005
+ switch (result.kind) {
49006
+ case "paymentStatusRequired":
49007
+ options.setPaymentStatusRecovery({
49008
+ kind: "ready",
49009
+ subject: result.subject
49010
+ });
49011
+ options.setStep("payment-status");
49012
+ return {
49013
+ ok: true,
49014
+ outcome: { kind: "payment_status" }
49015
+ };
49016
+ case "checkoutRequired":
49017
+ options.setPendingRegistrationReference(result.reference);
49018
+ savePendingCheckout(options, deps, prepared, result.submissionId, result.reference);
49019
+ options.setStep("redirecting");
49020
+ return redirectToCheckout(result.checkoutUrl, submitOptions);
49021
+ case "waitlisted":
49022
+ options.setRegistrationResult({
49023
+ status: "waitlist",
49024
+ title: "Added to waitlist",
49025
+ message: result.waitlist.message
49026
+ });
49027
+ break;
49028
+ case "bookingComplete":
49029
+ case "paymentDeferred":
49030
+ options.setPendingRegistrationReference(result.reference);
49031
+ options.setRegistrationResult({
49032
+ status: "confirmed",
49033
+ message: result.summary.paymentMethod === "pass" ? result.summary.message : void 0
49034
+ });
49035
+ break;
49036
+ }
49037
+ options.commandRef.current = null;
49117
49038
  options.setStep("success");
49118
49039
  return {
49119
49040
  ok: true,
@@ -49144,15 +49065,7 @@ function prepareSubmitContext(options, registrationCommandId, target, method, pa
49144
49065
  email: guest.email?.trim().toLowerCase() || void 0,
49145
49066
  phone: guest.phone?.trim() || void 0
49146
49067
  })) : void 0,
49147
- subject: target.subject.kind === "occurrence" ? {
49148
- kind: "occurrence",
49149
- occurrenceId: target.subject.occurrenceId,
49150
- attendanceMode: options.selectedAttendanceMode ?? void 0
49151
- } : {
49152
- kind: "wholeSeries",
49153
- eventSeriesId: target.subject.eventSeriesId,
49154
- attendanceMode: options.selectedAttendanceMode ?? void 0
49155
- }
49068
+ subject: toRegistrationRequestSubject(target.subject, options.selectedAttendanceMode)
49156
49069
  };
49157
49070
  }
49158
49071
  function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId, selection) {
@@ -49176,85 +49089,6 @@ function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId,
49176
49089
  if (method === "free") return { method };
49177
49090
  throw new Error("Choose an available payment option.");
49178
49091
  }
49179
- async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions) {
49180
- options.setStep("redirecting");
49181
- if (prepared.selectionSnapshot.method !== "stripe") throw new Error("Choose an available payment option.");
49182
- const checkoutAttemptId = deps.createClientCommandId();
49183
- const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
49184
- const result = await options.api.createEventCheckout({
49185
- subject: prepared.subject,
49186
- ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
49187
- selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
49188
- email: options.formData.email.trim().toLowerCase(),
49189
- name: options.formData.name.trim(),
49190
- phone: options.formData.phone.trim() || void 0,
49191
- formData: options.formData,
49192
- consentAccepted: options.formData.consentAccepted,
49193
- altchaSolution: options.altchaSolution,
49194
- guests: prepared.guestsPayload,
49195
- claimToken: options.claimToken ?? void 0,
49196
- waitlistEntryId: options.waitlistEntryId ?? void 0,
49197
- discountCode: options.discountCode.trim() || void 0,
49198
- collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
49199
- checkoutAttemptId,
49200
- ...urls
49201
- });
49202
- if (result.scope !== "wholeSeries") throw new Error("Unexpected registration scope for event checkout.");
49203
- if ("waitlistEntryId" in result) {
49204
- options.setRegistrationResult({
49205
- status: "waitlist",
49206
- variant: result.alreadyRegistered ? "info" : void 0,
49207
- title: result.alreadyRegistered ? "Already waitlisted" : "Added to waitlist",
49208
- message: result.alreadyRegistered ? "You are already on the waitlist for this event." : "You've been added to the waitlist."
49209
- });
49210
- options.setStep("success");
49211
- return {
49212
- ok: true,
49213
- outcome: { kind: "completed" }
49214
- };
49215
- }
49216
- if (result.bypassed) return completeBypassedCheckout(options);
49217
- if (!result.checkoutUrl) throw new Error("Checkout URL missing");
49218
- savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
49219
- scope: "wholeSeries",
49220
- registrationId: result.registrationId
49221
- });
49222
- return redirectToCheckout(result.checkoutUrl, submitOptions);
49223
- }
49224
- function needsOccurrenceCheckout(result, method) {
49225
- return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
49226
- "stripe",
49227
- "pass_bundle",
49228
- "membership_bundle"
49229
- ].includes(method);
49230
- }
49231
- async function submitOccurrenceCheckout(options, deps, prepared, registration, method, submitOptions) {
49232
- const reference = {
49233
- scope: "occurrence",
49234
- attendeeId: registration.attendeeId
49235
- };
49236
- options.setPendingRegistrationReference(reference);
49237
- options.setStep("redirecting");
49238
- const checkoutAttemptId = deps.createClientCommandId();
49239
- const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
49240
- const result = await options.api.createEventCheckout({
49241
- subject: {
49242
- kind: "occurrence",
49243
- attendeeId: registration.attendeeId
49244
- },
49245
- registrationCommandId: prepared.registrationCommandId,
49246
- checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
49247
- productId: prepared.bundleProductId,
49248
- discountCode: options.discountCode.trim() || void 0,
49249
- collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0,
49250
- ...urls
49251
- });
49252
- if (result.scope !== "occurrence") throw new Error("Unexpected registration scope for event checkout.");
49253
- if (result.bypassed) return completeBypassedCheckout(options);
49254
- if (!result.checkoutUrl) throw new Error("Checkout URL missing");
49255
- if (prepared.subject.kind === "occurrence") savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference);
49256
- return redirectToCheckout(result.checkoutUrl, submitOptions);
49257
- }
49258
49092
  function savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference) {
49259
49093
  const siteId = options.api.config.siteId;
49260
49094
  if (!siteId) return;
@@ -49267,14 +49101,6 @@ function savePendingCheckout(options, deps, prepared, checkoutAttemptId, referen
49267
49101
  paymentSelection: prepared.selectionSnapshot
49268
49102
  });
49269
49103
  }
49270
- function completeBypassedCheckout(options) {
49271
- options.setRegistrationResult({ status: "confirmed" });
49272
- options.setStep("success");
49273
- return {
49274
- ok: true,
49275
- outcome: { kind: "completed" }
49276
- };
49277
- }
49278
49104
  function redirectToCheckout(checkoutUrl, submitOptions) {
49279
49105
  if (submitOptions?.redirect !== "manual") window.location.href = checkoutUrl;
49280
49106
  return {
@@ -49286,12 +49112,23 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
49286
49112
  };
49287
49113
  }
49288
49114
  function registrationRequestIntentKey(request) {
49289
- const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
49290
- return JSON.stringify(intent);
49115
+ const { registrationCommandId: _command, altchaSolution: _proof, checkout, ...intent } = request;
49116
+ return JSON.stringify({
49117
+ ...intent,
49118
+ checkout: checkout ? {
49119
+ discountCode: checkout.discountCode,
49120
+ collectionOptionKind: checkout.collectionOptionKind
49121
+ } : void 0
49122
+ });
49291
49123
  }
49292
- function buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId) {
49124
+ function buildRegistrationRequest(options, prepared, method, passId, membershipId) {
49293
49125
  return {
49294
49126
  registrationCommandId: prepared.registrationCommandId,
49127
+ checkout: {
49128
+ ...buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: prepared.registrationCommandId }),
49129
+ discountCode: options.discountCode.trim() || void 0,
49130
+ collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0
49131
+ },
49295
49132
  subject: prepared.subject,
49296
49133
  ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
49297
49134
  selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
@@ -49316,6 +49153,7 @@ var init_useEventRegistrationSubmit = __esmMin((() => {
49316
49153
  init_shared();
49317
49154
  init_registrationErrorPresentation();
49318
49155
  init_constants();
49156
+ init_registrationDerivations();
49319
49157
  init_sessionStorage();
49320
49158
  init_ticketSelectionLines();
49321
49159
  eventRegistrationSubmitDeps = {
@@ -49533,23 +49371,128 @@ var init_useWaitlistClaimRestoration = __esmMin((() => {
49533
49371
  }));
49534
49372
  //#endregion
49535
49373
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationCompletion.ts
49374
+ function isSelectionSoldOut(availability) {
49375
+ return availability?.kind === "unavailable" && availability.reason === "full";
49376
+ }
49536
49377
  function resolveRegistrationAvailabilityBlocker(input) {
49537
49378
  if (input.hasWaitlistClaim) return null;
49538
49379
  if (input.eligibilityError) return input.eligibilityError;
49539
49380
  if (!input.eligibility) return "Registration is not available for this event.";
49381
+ if (input.eligibility.registration.kind === "pending_payment") return null;
49382
+ if (isSelectionSoldOut(input.eligibility.availability)) return null;
49540
49383
  if (input.eligibility.availability.kind === "unavailable" && input.eligibility.availability.reason === "paymentUnavailable") return "Payment options are not available for this event.";
49541
- if (input.eligibility.availability.kind === "unavailable" || !input.eligibility.eligible) return "Registration is not available for this event.";
49384
+ if (input.eligibility.availability.kind === "unavailable" || input.eligibility.registration.kind === "waitlisted") return "Registration is not available for this event.";
49542
49385
  return null;
49543
49386
  }
49544
49387
  function resolvePricingSelectionBlocker(input) {
49545
49388
  if (input.selectionRequired && !input.hasValidSelection) return "Choose at least one available ticket to continue.";
49546
49389
  return input.slidingScaleSelectionMessage;
49547
49390
  }
49548
- function isSoldOutWithoutWaitlist(input) {
49549
- return Boolean(!input.hasWaitlistClaim && input.eligibility?.isFull && !input.eligibility.canJoinWaitlist);
49550
- }
49551
49391
  var init_registrationCompletion = __esmMin((() => {}));
49552
49392
  //#endregion
49393
+ //#region ../blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.ts
49394
+ function isCheckableRecovery(state) {
49395
+ return state.kind === "ready" || state.kind === "processing" || state.kind === "temporarilyUnavailable";
49396
+ }
49397
+ function assistanceRequired(recovery) {
49398
+ return {
49399
+ kind: "assistanceRequired",
49400
+ subject: recovery.subject
49401
+ };
49402
+ }
49403
+ function applyStatusOutcome(outcome, recovery, setters, setRecovery) {
49404
+ if (outcome.kind === "resolved") {
49405
+ setters.setPendingRegistrationReference(outcome.reference);
49406
+ setters.setRegistrationResult({ status: "confirmed" });
49407
+ setRecovery(null);
49408
+ setters.setStep("success");
49409
+ return;
49410
+ }
49411
+ switch (outcome.kind) {
49412
+ case "paymentProcessing":
49413
+ setRecovery({
49414
+ ...recovery,
49415
+ kind: "processing"
49416
+ });
49417
+ return;
49418
+ case "paymentAvailable":
49419
+ setRecovery({
49420
+ ...recovery,
49421
+ kind: "paymentAvailable",
49422
+ checkoutUrl: outcome.checkoutUrl
49423
+ });
49424
+ return;
49425
+ case "paymentCheckUnavailable":
49426
+ setRecovery({
49427
+ ...recovery,
49428
+ kind: "temporarilyUnavailable"
49429
+ });
49430
+ return;
49431
+ case "paymentRetryAvailable":
49432
+ setRecovery({
49433
+ ...recovery,
49434
+ kind: "retryAvailable"
49435
+ });
49436
+ return;
49437
+ case "abandoned":
49438
+ case "notFound":
49439
+ case "reconciliationRequired":
49440
+ case "paymentAssistanceRequired":
49441
+ setRecovery(assistanceRequired(recovery));
49442
+ return;
49443
+ }
49444
+ }
49445
+ function usePaymentStatusRecovery(options) {
49446
+ const [recovery, setRecovery] = useState(null);
49447
+ const checkRef = useRef(null);
49448
+ return {
49449
+ recovery,
49450
+ showRecovery: useCallback((next) => setRecovery(next), []),
49451
+ check: useCallback(() => {
49452
+ if (!recovery || !isCheckableRecovery(recovery) || checkRef.current) return;
49453
+ const pending = (async () => {
49454
+ setRecovery({
49455
+ ...recovery,
49456
+ kind: "checking"
49457
+ });
49458
+ try {
49459
+ applyStatusOutcome(await options.api.resolveEventCheckoutReturn({
49460
+ kind: "checkStatus",
49461
+ subject: recovery.subject
49462
+ }), recovery, options, setRecovery);
49463
+ } catch {
49464
+ setRecovery({
49465
+ ...recovery,
49466
+ kind: "temporarilyUnavailable"
49467
+ });
49468
+ }
49469
+ })();
49470
+ checkRef.current = pending;
49471
+ pending.finally(() => {
49472
+ if (checkRef.current === pending) checkRef.current = null;
49473
+ });
49474
+ }, [options, recovery]),
49475
+ continuePayment: useCallback(() => {
49476
+ if (recovery?.kind === "paymentAvailable") window.location.assign(recovery.checkoutUrl);
49477
+ }, [recovery]),
49478
+ returnToPayment: useCallback(() => {
49479
+ if (recovery?.kind !== "retryAvailable") return;
49480
+ options.beginNewSubmission();
49481
+ setRecovery(null);
49482
+ options.setOptionsRefreshKey((value) => value + 1);
49483
+ options.setStep("select-payment");
49484
+ }, [options, recovery]),
49485
+ returnToBooking: useCallback(() => {
49486
+ if (recovery?.kind !== "assistanceRequired") return;
49487
+ options.beginNewSubmission();
49488
+ setRecovery(null);
49489
+ options.setOptionsRefreshKey((value) => value + 1);
49490
+ options.setStep("select-tickets");
49491
+ }, [options, recovery])
49492
+ };
49493
+ }
49494
+ var init_usePaymentStatusRecovery = __esmMin((() => {}));
49495
+ //#endregion
49553
49496
  //#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
49554
49497
  function usesTieredPricing(event) {
49555
49498
  return event !== null && event !== void 0 ? publicEventPricingStrategy(event.pricing) === "tiered" : false;
@@ -49596,6 +49539,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49596
49539
  const [errorAction, setErrorAction] = useState("retry");
49597
49540
  const [optionsRefreshKey, setOptionsRefreshKey] = useState(0);
49598
49541
  const [altchaSolution, setAltchaSolution] = useState(null);
49542
+ const [checkingNextStep, setCheckingNextStep] = useState(false);
49599
49543
  const { authState: portalAuthState, profile: portalProfile } = deps.usePortalAuth();
49600
49544
  const waitlistClaim = deps.useWaitlistClaim();
49601
49545
  const [showMagicLinkModal, setShowMagicLinkModal] = useState(false);
@@ -49622,28 +49566,29 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49622
49566
  }), [options.occurrenceContext, selectedEvent]);
49623
49567
  const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
49624
49568
  const currentEvent = selectedEvent ?? preSelectedEvent;
49569
+ const commandRef = useRef(null);
49625
49570
  const setStep = useCallback((nextStep) => {
49626
49571
  dispatchFlow({
49627
49572
  type: "set-step",
49628
49573
  step: nextStep
49629
49574
  });
49630
49575
  }, []);
49631
- const { checkoutRecovery, startCheckoutRecovery } = useCheckoutRecovery(currentEvent, setStep);
49632
- const currentEventUsesTicketTypes = usesTieredPricing(currentEvent);
49633
- const currentCanJoinWaitlist = canJoinWaitlistOutsideRecovery(currentEvent, selectedAttendanceMode, checkoutRecovery);
49634
- const usesTicketTypeSelections = currentEventUsesTicketTypes && !currentCanJoinWaitlist;
49576
+ const { recovery: paymentStatusRecovery, showRecovery: setPaymentStatusRecovery, check: handleCheckPaymentStatus, continuePayment: handleContinueExistingPayment, returnToPayment: handleReturnToPayment, returnToBooking: handleReturnToBooking } = usePaymentStatusRecovery({
49577
+ api,
49578
+ beginNewSubmission: () => {
49579
+ commandRef.current = null;
49580
+ },
49581
+ setPendingRegistrationReference,
49582
+ setRegistrationResult,
49583
+ setOptionsRefreshKey,
49584
+ setStep
49585
+ });
49586
+ const usesTicketTypeSelections = usesTieredPricing(currentEvent);
49635
49587
  const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
49636
49588
  event: currentEvent,
49637
49589
  eligibility: null,
49638
49590
  selectedAttendanceMode
49639
- }).map((option) => checkoutRecovery ? {
49640
- ...option,
49641
- availability: checkoutRecoveryOptionAvailability(option.availability)
49642
- } : option), [
49643
- currentEvent,
49644
- selectedAttendanceMode,
49645
- checkoutRecovery
49646
- ]);
49591
+ }), [currentEvent, selectedAttendanceMode]);
49647
49592
  const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
49648
49593
  const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
49649
49594
  const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
@@ -49681,7 +49626,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49681
49626
  isAuthenticated: portalAuthState === "authenticated",
49682
49627
  occurrenceId: registrationOccurrenceId
49683
49628
  });
49684
- const eligibility = useCheckoutRecoveryEligibility(eligibilityResult.eligibility, step, checkoutRecovery, startCheckoutRecovery);
49629
+ const eligibility = eligibilityResult.eligibility;
49685
49630
  const eligibilityLoading = eligibilityResult.isLoading;
49686
49631
  const eligibilityError = eligibilityResult.error;
49687
49632
  const portalCreditState = eligibilityResult.creditState;
@@ -49793,14 +49738,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49793
49738
  event: currentEvent,
49794
49739
  eligibility,
49795
49740
  selectedAttendanceMode
49796
- }).map((option) => checkoutRecovery ? {
49797
- ...option,
49798
- availability: checkoutRecoveryOptionAvailability(option.availability)
49799
- } : option), [
49741
+ }), [
49800
49742
  currentEvent,
49801
49743
  selectedAttendanceMode,
49802
- eligibility,
49803
- checkoutRecovery
49744
+ eligibility
49804
49745
  ]);
49805
49746
  const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
49806
49747
  const selectedTicketType = useMemo(() => findSelectedTicketType({
@@ -49824,12 +49765,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49824
49765
  const event = currentEvent;
49825
49766
  if (!usesTieredPricing(event)) return false;
49826
49767
  if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
49827
- return checkoutRecovery || !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
49828
- }, [
49829
- currentEvent,
49830
- selectedAttendanceMode,
49831
- checkoutRecovery
49832
- ]);
49768
+ return true;
49769
+ }, [currentEvent, selectedAttendanceMode]);
49833
49770
  const hasValidTicketSelection = hasValidPricingOptionSelection({
49834
49771
  selectionRequired: ticketTypeSelectionRequired,
49835
49772
  lines: normalizedSelectedTicketLines,
@@ -49840,8 +49777,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49840
49777
  if (selectedTicketLines.length > 0) setSelectedTicketLines([]);
49841
49778
  return;
49842
49779
  }
49843
- const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => ticketType.availability.kind === "available");
49844
- const implicitTicketType = getImplicitSingleAvailableTicketType(eventTicketTypesForSelection);
49780
+ const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => canRequestTicketOption(ticketType.availability));
49781
+ const implicitTicketType = getImplicitSingleTicketType(eventTicketTypesForSelection);
49845
49782
  if (implicitTicketType && normalizedSelectedTicketLines.length === 0) {
49846
49783
  setSelectedTicketLines([{
49847
49784
  pricingOptionId: implicitTicketType.pricingOptionId,
@@ -49908,6 +49845,26 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49908
49845
  selectedEventSlidingScale,
49909
49846
  selectedSlidingAmount
49910
49847
  ]);
49848
+ const checkDetailsNextStep = async () => {
49849
+ if (portalAuthState === "authenticated" || waitlistClaim.claim || eligibility?.availability.kind === "available" || !registrationTarget) return { kind: canRecoverToWaitlist(eligibility) ? "waitlist" : "continue" };
49850
+ setCheckingNextStep(true);
49851
+ try {
49852
+ return await api.checkRegistrationNextStep({
49853
+ subject: toRegistrationRequestSubject(registrationTarget.subject, selectedAttendanceMode),
49854
+ selections: ticketSelections,
49855
+ selectedSlidingAmount: selectedSlidingAmount ?? void 0,
49856
+ email: formData.email,
49857
+ altchaSolution
49858
+ });
49859
+ } catch {
49860
+ return {
49861
+ kind: "unavailable",
49862
+ message: "We could not check availability. Please try again."
49863
+ };
49864
+ } finally {
49865
+ setCheckingNextStep(false);
49866
+ }
49867
+ };
49911
49868
  const handleDetailsComplete = async () => {
49912
49869
  const blockDetailsCompletion = (message) => {
49913
49870
  setErrorAction("places");
@@ -49939,11 +49896,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49939
49896
  message: "Check the highlighted fields and try again."
49940
49897
  };
49941
49898
  }
49942
- if (isSoldOutWithoutWaitlist({
49943
- hasWaitlistClaim: waitlistClaim.claim !== null,
49944
- eligibility
49945
- })) return blockDetailsCompletion("Sorry, there aren’t enough places left for your selection. Please check the available places and choose again.");
49946
- if (!eligibility?.canJoinWaitlist && requiresPaymentStep({
49899
+ const next = await checkDetailsNextStep();
49900
+ if (next.kind === "unavailable") return blockDetailsCompletion(next.message);
49901
+ const canJoinWaitlist = next.kind === "waitlist";
49902
+ if (!canJoinWaitlist && requiresPaymentStep({
49947
49903
  eventRequiresPayment,
49948
49904
  paymentSelection
49949
49905
  })) {
@@ -49956,7 +49912,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49956
49912
  const submitPlan = resolveEventRegistrationSubmitPlan({
49957
49913
  paymentSelection,
49958
49914
  eventRequiresPayment,
49959
- canJoinWaitlist: eligibility?.canJoinWaitlist
49915
+ canJoinWaitlist
49960
49916
  });
49961
49917
  if (!submitPlan.ok) return blockDetailsCompletion(submitPlan.message);
49962
49918
  const submitResult = await handleSubmit(submitPlan.args.method, submitPlan.args.passId, submitPlan.args.membershipId, submitPlan.args.selection);
@@ -49974,7 +49930,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
49974
49930
  const submitPlan = resolveEventRegistrationSubmitPlan({
49975
49931
  paymentSelection,
49976
49932
  eventRequiresPayment,
49977
- canJoinWaitlist: eligibility?.canJoinWaitlist
49933
+ canJoinWaitlist: false
49978
49934
  });
49979
49935
  if (!submitPlan.ok) {
49980
49936
  setErrorMessage(submitPlan.message);
@@ -50006,6 +49962,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
50006
49962
  const selectionMethod = paymentSelection.method;
50007
49963
  const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
50008
49964
  const handleSubmit = deps.useEventRegistrationSubmit({
49965
+ commandRef,
50009
49966
  setErrorAction,
50010
49967
  api,
50011
49968
  registrationTarget,
@@ -50022,7 +49979,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
50022
49979
  setPendingRegistrationReference,
50023
49980
  setStep,
50024
49981
  setRegistrationResult: (result) => setRegistrationResult(result),
50025
- setErrorMessage
49982
+ setErrorMessage,
49983
+ setPaymentStatusRecovery
50026
49984
  });
50027
49985
  const handleEventSelect = (event) => {
50028
49986
  setSelectedEvent(event);
@@ -50081,8 +50039,6 @@ function useEventRegistrationWizardWithDeps(options, deps) {
50081
50039
  scopedEvents,
50082
50040
  preSelectedEvent,
50083
50041
  hasPreSelectedContext,
50084
- checkoutRecovery,
50085
- startCheckoutRecovery,
50086
50042
  step,
50087
50043
  setStep,
50088
50044
  selectedEvent,
@@ -50136,7 +50092,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
50136
50092
  waitlistClaim,
50137
50093
  eligibility,
50138
50094
  registrationOptionsState: eligibilityResult.state,
50139
- eligibilityLoading,
50095
+ eligibilityLoading: eligibilityLoading || checkingNextStep,
50140
50096
  eligibilityError,
50141
50097
  existingRegistration: existingRegistrationResult.registration,
50142
50098
  existingRegistrationLoading: existingRegistrationResult.isLoading || portalAuthState === "authenticated" && eligibilityLoading,
@@ -50156,6 +50112,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
50156
50112
  discountContext,
50157
50113
  shouldShowDiscountToggle,
50158
50114
  verification,
50115
+ paymentStatusRecovery,
50116
+ handleCheckPaymentStatus,
50117
+ handleContinueExistingPayment,
50118
+ handleReturnToPayment,
50119
+ handleReturnToBooking,
50159
50120
  handleDetailsComplete,
50160
50121
  handlePaymentSelect,
50161
50122
  handleUseCardInsteadOfPass,
@@ -50167,12 +50128,9 @@ function useEventRegistrationWizardWithDeps(options, deps) {
50167
50128
  }
50168
50129
  var eventRegistrationWizardDeps;
50169
50130
  var init_useEventRegistrationWizard = __esmMin((() => {
50170
- init_checkoutRecovery();
50171
- init_useCheckoutRecovery();
50172
50131
  init_src$2();
50173
50132
  init_registrationErrorRecovery();
50174
50133
  init_api();
50175
- init_domain();
50176
50134
  init_validation();
50177
50135
  init_hooks();
50178
50136
  init_portalLogout();
@@ -50192,6 +50150,7 @@ var init_useEventRegistrationWizard = __esmMin((() => {
50192
50150
  init_waitlistClaimRestoration();
50193
50151
  init_useWaitlistClaimRestoration();
50194
50152
  init_registrationCompletion();
50153
+ init_usePaymentStatusRecovery();
50195
50154
  eventRegistrationWizardDeps = {
50196
50155
  usePortalAuth,
50197
50156
  useEligibility,
@@ -50375,7 +50334,6 @@ var init_ErrorStep = __esmMin((() => {
50375
50334
  start: "Start again",
50376
50335
  details: "Check my details",
50377
50336
  "payment-options": "View payment options",
50378
- "payment-status": "Check payment status",
50379
50337
  portal: "View my bookings",
50380
50338
  event: "View event"
50381
50339
  };
@@ -50394,7 +50352,7 @@ var init_ErrorStep = __esmMin((() => {
50394
50352
  className: "er-text--muted er-message",
50395
50353
  children: offerWaitlist ? "Sorry, this event is now full. You can join the waiting list, and we’ll email you if a place becomes available." : message
50396
50354
  }),
50397
- actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
50355
+ actions: action === "none" ? void 0 : action === "portal" ? /* @__PURE__ */ jsx("a", {
50398
50356
  href: "/portal",
50399
50357
  className: "er-retry-btn",
50400
50358
  children: labels[action]
@@ -50655,8 +50613,11 @@ var init_EventRegistrationSummaryBar = __esmMin((() => {
50655
50613
  */
50656
50614
  function resolveDetailsButtonText(input) {
50657
50615
  const { wizard } = input;
50658
- if (wizard.eligibility?.canJoinWaitlist) return "Join waitlist";
50659
- if (!input.hasWaitlistClaim && wizard.eligibility?.isFull) return "Sold out";
50616
+ const availability = wizard.eligibility?.availability;
50617
+ const full = availability?.kind === "waitlist" || isSelectionSoldOut(availability);
50618
+ if (wizard.portalAuthState !== "authenticated" && full) return "Continue";
50619
+ if (canRecoverToWaitlist(wizard.eligibility)) return "Join waitlist";
50620
+ if (!input.hasWaitlistClaim && full && wizard.eligibility?.registration.kind !== "pending_payment") return "Sold out";
50660
50621
  if (wizard.paymentSelection.method === "pass") return "Book using class pass";
50661
50622
  if (wizard.paymentSelection.method === "membership") return input.fallbackText;
50662
50623
  return wizard.eventRequiresPayment ? "Continue to payment" : input.fallbackText;
@@ -50671,44 +50632,28 @@ function isExistingRegistrationBlocking$1(wizard) {
50671
50632
  hasWaitlistClaim: wizard.waitlistClaim.claim !== null
50672
50633
  });
50673
50634
  }
50674
- /**
50675
- * Full for the visitor's selected attendance mode (or the whole event when no
50676
- * mode is chosen) with no waitlist to fall back on. Reads the same capacity
50677
- * source as the steps above the action bar so the button never disagrees
50678
- * with them on a hybrid event.
50679
- */
50680
- function isFullWithNoWaitlist(event, attendanceMode) {
50681
- if (!event) return false;
50682
- const source = selectEventCapacitySource(event, attendanceMode);
50683
- return getEventAvailability(source).isFull && !source.waitlistEnabled;
50684
- }
50685
50635
  function resolveTicketSelectionContinueLabel(input) {
50686
50636
  if (input.isCheckingExistingRegistration) return "Checking registration...";
50687
50637
  if (input.registrationOptionsPending) return "Checking availability...";
50688
50638
  if (input.registrationOptionsFailed) return "Availability unavailable";
50689
50639
  if (input.hasExistingRegistration) return resolveExistingRegistrationLabel(input.wizard);
50690
- if (input.isSoldOutWithoutWaitlist) return "Sold out";
50691
50640
  if (input.ticketTypeSelectionBlocked) return "Choose a ticket";
50692
50641
  return "Continue";
50693
50642
  }
50694
50643
  function SelectTicketsActions(props) {
50695
50644
  const { wizard } = props;
50696
- const hasWaitlistClaim = wizard.waitlistClaim.claim !== null;
50697
- const currentEvent = wizard.selectedEvent ?? wizard.preSelectedEvent;
50698
50645
  const registrationOptionsPending = wizard.registrationOptionsState.tag === "idle" || wizard.registrationOptionsState.tag === "loading";
50699
50646
  const registrationOptionsFailed = wizard.registrationOptionsState.tag === "failed";
50700
- const isSoldOutWithoutWaitlist = !wizard.checkoutRecovery && !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
50701
50647
  const isCheckingExistingRegistration = wizard.portalAuthState === "authenticated" && wizard.existingRegistrationLoading;
50702
50648
  const hasExistingRegistration = isExistingRegistrationBlocking$1(wizard);
50703
50649
  const ticketTypeSelectionBlocked = wizard.ticketTypeSelectionRequired && !wizard.hasValidTicketSelection;
50704
- const isContinueDisabled = registrationOptionsPending || registrationOptionsFailed || isCheckingExistingRegistration || hasExistingRegistration || isSoldOutWithoutWaitlist || ticketTypeSelectionBlocked;
50650
+ const isContinueDisabled = registrationOptionsPending || registrationOptionsFailed || isCheckingExistingRegistration || hasExistingRegistration || ticketTypeSelectionBlocked;
50705
50651
  const continueLabel = resolveTicketSelectionContinueLabel({
50706
50652
  wizard,
50707
50653
  registrationOptionsPending,
50708
50654
  registrationOptionsFailed,
50709
50655
  isCheckingExistingRegistration,
50710
50656
  hasExistingRegistration,
50711
- isSoldOutWithoutWaitlist,
50712
50657
  ticketTypeSelectionBlocked
50713
50658
  });
50714
50659
  return /* @__PURE__ */ jsxs("div", {
@@ -50739,8 +50684,12 @@ function EnterDetailsActions(props) {
50739
50684
  const { wizard } = props;
50740
50685
  const hasWaitlistClaim = wizard.waitlistClaim.claim !== null;
50741
50686
  const isCheckingEligibility = wizard.eligibilityLoading;
50742
- const eligibilityUnavailable = !hasWaitlistClaim && (Boolean(wizard.eligibilityError) || !wizard.eligibility || wizard.eligibility.availability.kind === "unavailable" || !wizard.eligibility.eligible);
50743
- const isSoldOut = !hasWaitlistClaim && wizard.eligibility?.isFull === true && wizard.eligibility.canJoinWaitlist !== true;
50687
+ const eligibilityUnavailable = Boolean(resolveRegistrationAvailabilityBlocker({
50688
+ hasWaitlistClaim,
50689
+ eligibility: wizard.eligibility,
50690
+ eligibilityError: wizard.eligibilityError
50691
+ }));
50692
+ const isSoldOut = !hasWaitlistClaim && wizard.portalAuthState === "authenticated" && wizard.eligibility?.registration.kind !== "pending_payment" && isSelectionSoldOut(wizard.eligibility?.availability);
50744
50693
  const isContinueDisabled = isCheckingEligibility || eligibilityUnavailable || isSoldOut;
50745
50694
  const continueLabel = isCheckingEligibility ? "Checking availability..." : wizard.eligibilityError ? "Availability unavailable" : eligibilityUnavailable ? "Registration unavailable" : resolveDetailsButtonText({
50746
50695
  wizard,
@@ -50791,6 +50740,7 @@ function EventRegistrationWizardActions(props) {
50791
50740
  case "redirecting":
50792
50741
  case "verifying-payment":
50793
50742
  case "verifying-timeout":
50743
+ case "payment-status":
50794
50744
  case "payment-failed": return null;
50795
50745
  case "select-event": return null;
50796
50746
  case "select-tickets": return /* @__PURE__ */ jsx(SelectTicketsActions, { ...props });
@@ -50802,7 +50752,8 @@ function EventRegistrationWizardActions(props) {
50802
50752
  var init_EventRegistrationWizardActions = __esmMin((() => {
50803
50753
  init_registrationStateMachine();
50804
50754
  init_spinner$1();
50805
- init_domain();
50755
+ init_registrationCompletion();
50756
+ init_registrationErrorRecovery();
50806
50757
  }));
50807
50758
  //#endregion
50808
50759
  //#region ../blocks/src/system/runtime/nodes/event-registration/siteCreditPreview.ts
@@ -50883,7 +50834,7 @@ var init_siteCreditPreview = __esmMin((() => {
50883
50834
  function resolvePaymentStepStatus(input) {
50884
50835
  if (input.loading) return "loading";
50885
50836
  if (input.error || !input.eligibility) return "error";
50886
- if (input.eligibility.registration.kind !== "none" || !input.eligibility.eligible && !input.eligibility.isFree) return "not-eligible";
50837
+ if (input.eligibility.registration.kind === "waitlisted" || input.eligibility.paymentOptions.length === 0) return "not-eligible";
50887
50838
  return "ready";
50888
50839
  }
50889
50840
  function shouldPromptForLogin(status, isAuthenticated, eligibility) {
@@ -50918,7 +50869,7 @@ function UnavailableEntitlementMessage(props) {
50918
50869
  ] });
50919
50870
  }
50920
50871
  function IneligiblePaymentPanel(props) {
50921
- if (props.eligibility.isFull && !props.eligibility.canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
50872
+ if (isSelectionSoldOut(props.eligibility.availability)) return /* @__PURE__ */ jsxs("div", {
50922
50873
  className: "rb-reg-stack er-stack",
50923
50874
  children: [/* @__PURE__ */ jsx("h3", {
50924
50875
  className: "er-title",
@@ -50987,26 +50938,23 @@ function PaymentBlockingPanel(props) {
50987
50938
  })
50988
50939
  });
50989
50940
  if (!props.eligibility) return /* @__PURE__ */ jsx(MissingEligibilityPanel, {});
50990
- if (props.eligibility.registration.kind !== "none") {
50991
- const isBooked = props.eligibility.registration.kind === "booked";
50992
- return /* @__PURE__ */ jsxs("div", {
50993
- className: "rb-reg-stack er-stack",
50994
- children: [/* @__PURE__ */ jsx("h3", {
50995
- className: "er-title",
50996
- children: isBooked ? "Already booked" : "Already on the waitlist"
50997
- }), /* @__PURE__ */ jsxs("div", {
50998
- className: "er-center",
50999
- children: [/* @__PURE__ */ jsx("p", {
51000
- className: "er-text er-text--muted",
51001
- children: isBooked ? "You already have a booking for this event. Please check your bookings to see its status. If you need help, contact the organiser." : "You're already on the waitlist for this event."
51002
- }), /* @__PURE__ */ jsx("a", {
51003
- href: "/portal",
51004
- className: "er-retry-btn",
51005
- children: "View my bookings"
51006
- })]
50941
+ if (props.eligibility.registration.kind === "waitlisted") return /* @__PURE__ */ jsxs("div", {
50942
+ className: "rb-reg-stack er-stack",
50943
+ children: [/* @__PURE__ */ jsx("h3", {
50944
+ className: "er-title",
50945
+ children: "Already on the waitlist"
50946
+ }), /* @__PURE__ */ jsxs("div", {
50947
+ className: "er-center",
50948
+ children: [/* @__PURE__ */ jsx("p", {
50949
+ className: "er-text er-text--muted",
50950
+ children: "You're already on the waitlist for this event."
50951
+ }), /* @__PURE__ */ jsx("a", {
50952
+ href: "/portal",
50953
+ className: "er-retry-btn",
50954
+ children: "View my bookings"
51007
50955
  })]
51008
- });
51009
- }
50956
+ })]
50957
+ });
51010
50958
  if (props.eligibility.isFree) return /* @__PURE__ */ jsxs("div", {
51011
50959
  className: "rb-reg-stack er-stack",
51012
50960
  children: [/* @__PURE__ */ jsx("h3", {
@@ -51027,7 +50975,7 @@ function PaymentBlockingPanel(props) {
51027
50975
  })]
51028
50976
  })]
51029
50977
  });
51030
- return props.eligibility.eligible ? null : /* @__PURE__ */ jsx(IneligiblePaymentPanel, {
50978
+ return props.eligibility.paymentOptions.length > 0 ? null : /* @__PURE__ */ jsx(IneligiblePaymentPanel, {
51031
50979
  eligibility: props.eligibility,
51032
50980
  email: props.email,
51033
50981
  isAuthenticated: props.isAuthenticated,
@@ -51037,6 +50985,7 @@ function PaymentBlockingPanel(props) {
51037
50985
  var init_PaymentBlockingPanel = __esmMin((() => {
51038
50986
  init_buttons();
51039
50987
  init_spinner$1();
50988
+ init_registrationCompletion();
51040
50989
  }));
51041
50990
  //#endregion
51042
50991
  //#region ../blocks/src/system/runtime/nodes/event-registration/types.ts
@@ -51166,7 +51115,7 @@ function SlidingScaleAmountField(props) {
51166
51115
  }
51167
51116
  function TicketTypeQuantityRows(props) {
51168
51117
  const totalSelectedQuantity = getTicketSelectionTotal(props.ticketSelections);
51169
- const effectiveMaxTickets = props.availableSpots == null ? props.maxTickets : Math.min(props.maxTickets, props.availableSpots);
51118
+ const effectiveMaxTickets = props.maxTickets;
51170
51119
  return /* @__PURE__ */ jsxs("div", {
51171
51120
  className: "er-ticket-lines",
51172
51121
  children: [
@@ -51176,16 +51125,14 @@ function TicketTypeQuantityRows(props) {
51176
51125
  "aria-label": props.bookingUnit === "place" ? "Places" : "Tickets",
51177
51126
  children: props.ticketTypes.map((ticketType) => {
51178
51127
  const quantity = getTicketLineQuantity(props.ticketSelections, ticketType.pricingOptionId);
51179
- const disabled = ticketType.availability.kind === "unavailable";
51128
+ const disabled = !canRequestTicketOption(ticketType.availability);
51180
51129
  const availabilityLabel = getTicketTypeAvailabilityLabel(ticketType);
51181
51130
  const ticketTypeRemainingLabel = formatTicketTypeRemaining(ticketType.availability.remainingPlaces);
51182
51131
  const priceLabel = ticketType.priceAmount > 0 ? formatPrice(ticketType.priceAmount, props.currency) : "Free";
51183
51132
  const maxAllowed = disabled ? 0 : getTicketTypeLineMax({
51184
51133
  currentQuantity: quantity,
51185
51134
  totalSelectedQuantity,
51186
- maxTickets: props.maxTickets,
51187
- availableSpots: props.availableSpots,
51188
- ticketTypeRemainingCapacity: ticketType.availability.remainingPlaces
51135
+ maxTickets: props.maxTickets
51189
51136
  });
51190
51137
  return /* @__PURE__ */ jsxs("div", {
51191
51138
  className: `er-ticket-line${disabled ? " er-ticket-line--disabled" : ""}`,
@@ -51290,33 +51237,13 @@ function AttendanceModeTiles(props) {
51290
51237
  })
51291
51238
  });
51292
51239
  }
51293
- function getMaxAllowedTicketCount(input) {
51294
- if (input.canJoinWaitlist) return input.maxTickets;
51295
- if (!input.usesTicketTypes) return Math.min(input.maxTickets, input.availableSpots ?? input.maxTickets);
51296
- if (!input.hasSelectedTicketType) return 1;
51297
- return Math.max(1, Math.min(input.maxTickets, input.selectedTicketTypeRemainingCapacity ?? input.maxTickets, input.availableSpots ?? input.maxTickets));
51298
- }
51299
51240
  function resolveTicketSelectionPricing(event) {
51300
51241
  return {
51301
51242
  mode: event ? publicEventPricingStrategy(event.pricing) : void 0,
51302
51243
  currency: event ? publicEventPricingCurrency(event.pricing) : null
51303
51244
  };
51304
51245
  }
51305
- function CheckoutRecoveryEntry(props) {
51306
- return props.onContinue ? /* @__PURE__ */ jsx("button", {
51307
- type: "button",
51308
- className: "er-back-btn",
51309
- onClick: props.onContinue,
51310
- children: "Continue an existing booking"
51311
- }) : null;
51312
- }
51313
- function getTicketSelectionCapacity(event, attendanceMode, checkoutRecovery) {
51314
- if (checkoutRecovery) return {
51315
- availableSpots: null,
51316
- isSoldOut: false,
51317
- canJoinWaitlist: false,
51318
- eventAvailabilityLabel: null
51319
- };
51246
+ function getTicketSelectionCapacity(event, attendanceMode) {
51320
51247
  const source = event ? selectEventCapacitySource(event, attendanceMode) : null;
51321
51248
  const availability = source ? getEventAvailability(source) : null;
51322
51249
  const canJoinWaitlist = source ? canJoinEventWaitlist(source) : false;
@@ -51333,29 +51260,21 @@ var init_TicketSelectionStep = __esmMin((() => {
51333
51260
  init_domain();
51334
51261
  init_utils();
51335
51262
  init_ticketSelectionLines();
51336
- TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" }, checkoutRecovery = false, onCheckoutRecovery }) => {
51263
+ TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" } }) => {
51337
51264
  const unit = bookingUnit.kind;
51338
51265
  const deliveryMode = event?.deliveryMode ?? "in_person";
51339
51266
  const attendanceModes = event?.attendanceModes ?? [];
51340
- const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode, checkoutRecovery);
51267
+ const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode);
51341
51268
  const { mode: eventPricingMode, currency: eventPricingCurrency } = resolveTicketSelectionPricing(event);
51342
- const usesTicketTypes = eventPricingMode === "tiered" && !canJoinWaitlist;
51269
+ const usesTicketTypes = eventPricingMode === "tiered";
51343
51270
  const visibleTicketTypes = usesTicketTypes ? visibleTicketTypesOverride ?? getVisibleTicketTypes({
51344
51271
  event,
51345
51272
  eligibility: null,
51346
51273
  selectedAttendanceMode
51347
51274
  }) : [];
51348
- const implicitTicketType = usesTicketTypes ? getImplicitSingleAvailableTicketType(visibleTicketTypes) : null;
51349
51275
  const noVisibleTicketTypes = usesTicketTypes && visibleTicketTypes.length === 0;
51350
- const hasAvailableTicketTypes = usesTicketTypes && visibleTicketTypes.some((ticketType) => ticketType.availability.kind === "available");
51351
- const maxAllowed = getMaxAllowedTicketCount({
51352
- canJoinWaitlist,
51353
- usesTicketTypes,
51354
- maxTickets,
51355
- availableSpots,
51356
- selectedTicketTypeRemainingCapacity: implicitTicketType?.availability.remainingPlaces ?? null,
51357
- hasSelectedTicketType: implicitTicketType !== null
51358
- });
51276
+ const hasAvailableTicketTypes = usesTicketTypes && visibleTicketTypes.some((ticketType) => canRequestTicketOption(ticketType.availability));
51277
+ const maxAllowed = maxTickets;
51359
51278
  if (deliveryMode === "hybrid" && !selectedAttendanceMode) return /* @__PURE__ */ jsxs("div", {
51360
51279
  className: "rb-reg-stack er-stack",
51361
51280
  children: [
@@ -51374,20 +51293,6 @@ var init_TicketSelectionStep = __esmMin((() => {
51374
51293
  })
51375
51294
  ]
51376
51295
  });
51377
- if (isSoldOut && !canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
51378
- className: "rb-reg-stack er-stack",
51379
- children: [
51380
- /* @__PURE__ */ jsx("h3", {
51381
- className: "er-title",
51382
- children: "Sold out"
51383
- }),
51384
- /* @__PURE__ */ jsx("p", {
51385
- className: "er-text er-text--muted",
51386
- children: "Sorry you missed out! This event is fully booked."
51387
- }),
51388
- /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })
51389
- ]
51390
- });
51391
51296
  if (!eventPricingCurrency) return /* @__PURE__ */ jsx("div", {
51392
51297
  className: "rb-reg-stack er-stack",
51393
51298
  children: /* @__PURE__ */ jsx("p", {
@@ -51454,14 +51359,14 @@ var init_TicketSelectionStep = __esmMin((() => {
51454
51359
  })]
51455
51360
  })
51456
51361
  ] }),
51457
- canJoinWaitlist && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
51362
+ isSoldOut && !canJoinWaitlist && /* @__PURE__ */ jsx("p", {
51458
51363
  className: "er-text er-text--muted",
51459
- children: "This event is currently full. Continue to join the waitlist if a place opens up."
51460
- }), /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })] }),
51461
- checkoutRecovery && /* @__PURE__ */ jsx("p", {
51364
+ children: "This event is fully booked."
51365
+ }),
51366
+ canJoinWaitlist && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("p", {
51462
51367
  className: "er-text er-text--muted",
51463
- children: "Enter the details from your earlier booking. We’ll check your checkout before continuing to payment."
51464
- })
51368
+ children: "This event is currently full. Continue to join the waitlist if a place opens up."
51369
+ }) })
51465
51370
  ]
51466
51371
  });
51467
51372
  };
@@ -106406,7 +106311,7 @@ var init_PaymentSelectionStep = __esmMin((() => {
106406
106311
  const occurrenceId = occurrenceContext?.id ?? (event?.registrationSubject.kind === "occurrence" ? event.registrationSubject.occurrenceId : "");
106407
106312
  const selectedMethod = selectedSelection.method;
106408
106313
  const totalPrice = directPaymentTotalCents;
106409
- const canShowDirectPaymentOptions = Boolean(eligibility?.eligible && eligibility.canPayDirectly && eligibility.price);
106314
+ const canShowDirectPaymentOptions = Boolean(eligibility?.requiresPayment && eligibility.price);
106410
106315
  const directPaymentOptions = eligibility && canShowDirectPaymentOptions ? buildEventRegistrationPaymentOptionsViewModel({
106411
106316
  eventTitle: event?.title ?? "Event",
106412
106317
  approvedPaymentOptions: eligibility.paymentOptions,
@@ -106469,7 +106374,7 @@ var init_PaymentSelectionStep = __esmMin((() => {
106469
106374
  onRequestLogin
106470
106375
  });
106471
106376
  if (eligibilityLoading || eligibilityError || !eligibility) return blockingPanel;
106472
- if (eligibility.isFree || !eligibility.eligible) return blockingPanel;
106377
+ if (eligibility.isFree || paymentStepStatus !== "ready") return blockingPanel;
106473
106378
  const isMultiTicket = areEntitlementsDisabledForTicketCount(ticketsCount);
106474
106379
  return /* @__PURE__ */ jsxs("div", {
106475
106380
  className: "rb-reg-stack er-stack",
@@ -106688,7 +106593,7 @@ var init_VerifyingTimeoutStep = __esmMin((() => {
106688
106593
  title,
106689
106594
  body: /* @__PURE__ */ jsx("p", {
106690
106595
  className: "er-text--muted er-message",
106691
- children: message
106596
+ children: onCheckAgain ? message : "We still can’t confirm your payment. Please don’t make another payment. Contact the organiser so they can check your booking."
106692
106597
  }),
106693
106598
  actionsClassName: "er-button-group",
106694
106599
  actions: onCheckAgain ? /* @__PURE__ */ jsx("button", {
@@ -106696,11 +106601,7 @@ var init_VerifyingTimeoutStep = __esmMin((() => {
106696
106601
  onClick: onCheckAgain,
106697
106602
  className: "er-btn er-btn--primary",
106698
106603
  children: "Check payment status"
106699
- }) : /* @__PURE__ */ jsx("a", {
106700
- href: "/portal",
106701
- className: "er-btn er-btn--primary",
106702
- children: "Check payment status"
106703
- }),
106604
+ }) : void 0,
106704
106605
  secondaryBody: supportEmail ? /* @__PURE__ */ jsxs("p", {
106705
106606
  className: "er-text--sm er-text--muted er-message",
106706
106607
  children: [
@@ -106890,6 +106791,7 @@ function EventRegistrationWizardContent(props) {
106890
106791
  case "redirecting":
106891
106792
  case "verifying-payment":
106892
106793
  case "verifying-timeout":
106794
+ case "payment-status":
106893
106795
  case "payment-failed": return null;
106894
106796
  case "select-event": return /* @__PURE__ */ jsx(EventSelectionStep, {
106895
106797
  events: wizard.scopedEvents,
@@ -106905,8 +106807,6 @@ function EventRegistrationWizardContent(props) {
106905
106807
  onBookForSomeoneElse: wizard.handleBookForSomeoneElse
106906
106808
  }), /* @__PURE__ */ jsx(TicketSelectionStep, {
106907
106809
  event: wizard.selectedEvent,
106908
- checkoutRecovery: wizard.checkoutRecovery,
106909
- onCheckoutRecovery: canRecoverEventCheckout(wizard.selectedEvent) ? wizard.startCheckoutRecovery : void 0,
106910
106810
  occurrenceContext: wizard.occurrenceContext,
106911
106811
  selectedAttendanceMode: wizard.selectedAttendanceMode,
106912
106812
  onAttendanceModeChange: wizard.setSelectedAttendanceMode,
@@ -106934,13 +106834,90 @@ var init_EventRegistrationWizardContent = __esmMin((() => {
106934
106834
  init_client();
106935
106835
  init_src();
106936
106836
  init_shared();
106937
- init_checkoutRecovery();
106938
106837
  init_registrationStateMachine();
106939
106838
  init_siteCreditPreview();
106940
106839
  init_PaymentBlockingPanel();
106941
106840
  init_event_registration();
106942
106841
  }));
106943
106842
  //#endregion
106843
+ //#region ../blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.tsx
106844
+ function presentation(state) {
106845
+ switch (state.kind) {
106846
+ case "ready": return {
106847
+ title: "We haven’t confirmed your payment yet",
106848
+ message: "We’ve saved your booking details, but we haven’t been able to confirm that your payment was successful. Please don’t make another payment. Select Check payment status to get the latest update.",
106849
+ action: { label: "Check payment status" }
106850
+ };
106851
+ case "checking": return {
106852
+ title: "We haven’t confirmed your payment yet",
106853
+ message: "We’ve saved your booking details, but we haven’t been able to confirm that your payment was successful. Please don’t make another payment.",
106854
+ action: {
106855
+ label: "Checking payment…",
106856
+ disabled: true
106857
+ }
106858
+ };
106859
+ case "processing": return {
106860
+ title: "Your payment is still being processed",
106861
+ message: "Please don’t make another payment. You can check its status again in a moment.",
106862
+ action: { label: "Check payment status" }
106863
+ };
106864
+ case "paymentAvailable": return {
106865
+ title: "Your payment hasn’t been completed",
106866
+ message: "Your booking details are still saved. Continue to payment to finish your booking.",
106867
+ action: { label: "Continue to payment" }
106868
+ };
106869
+ case "retryAvailable": return {
106870
+ title: "Continue your booking",
106871
+ message: "You can return to payment. We’ll check your booking, any existing payment and availability before starting another checkout.",
106872
+ action: { label: "Return to payment" }
106873
+ };
106874
+ case "temporarilyUnavailable": return {
106875
+ title: "We couldn’t check your payment",
106876
+ message: "Please don’t make another payment yet. Try checking again in a moment.",
106877
+ action: { label: "Check payment status" }
106878
+ };
106879
+ case "assistanceRequired": return {
106880
+ title: "We still can’t confirm your payment",
106881
+ message: "Please don’t make another payment. Contact the organiser so they can check your booking.",
106882
+ action: { label: "Return to booking" }
106883
+ };
106884
+ }
106885
+ }
106886
+ function PaymentStatusStep(props) {
106887
+ const view = presentation(props.state);
106888
+ const onClick = props.state.kind === "paymentAvailable" ? props.onContinuePayment : props.state.kind === "retryAvailable" ? props.onReturnToPayment : props.state.kind === "assistanceRequired" ? props.onReturnToBooking : props.onCheck;
106889
+ return /* @__PURE__ */ jsx(TerminalPanel, {
106890
+ tone: "warning",
106891
+ className: "er-center",
106892
+ titleClassName: "er-title--lg er-message",
106893
+ icon: /* @__PURE__ */ jsx(StateIcon, {
106894
+ variant: "warning",
106895
+ children: /* @__PURE__ */ jsx(ClockIcon, {})
106896
+ }),
106897
+ title: view.title,
106898
+ body: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
106899
+ className: "er-text--muted er-message",
106900
+ children: view.message
106901
+ }), /* @__PURE__ */ jsx("span", {
106902
+ className: "rb-sr-only",
106903
+ "aria-live": "polite",
106904
+ "aria-atomic": "true",
106905
+ children: props.state.kind === "checking" ? "Checking payment…" : view.title
106906
+ })] }),
106907
+ actionsClassName: "er-button-group",
106908
+ actions: view.action ? /* @__PURE__ */ jsx("button", {
106909
+ type: "button",
106910
+ onClick,
106911
+ disabled: view.action.disabled,
106912
+ className: "er-btn er-btn--primary",
106913
+ children: /* @__PURE__ */ jsx("span", { children: view.action.label })
106914
+ }) : void 0
106915
+ });
106916
+ }
106917
+ var init_PaymentStatusStep = __esmMin((() => {
106918
+ init_shared();
106919
+ }));
106920
+ //#endregion
106944
106921
  //#region ../blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.tsx
106945
106922
  function EventPortalAuthPrompt(props) {
106946
106923
  return /* @__PURE__ */ jsxs("div", {
@@ -107025,6 +107002,13 @@ function EventRegistrationTerminalState(props) {
107025
107002
  message: wizard.verification.status === "timeout" ? void 0 : wizard.errorMessage,
107026
107003
  supportEmail: props.supportEmail
107027
107004
  });
107005
+ case "payment-status": return wizard.paymentStatusRecovery ? /* @__PURE__ */ jsx(PaymentStatusStep, {
107006
+ state: wizard.paymentStatusRecovery,
107007
+ onCheck: wizard.handleCheckPaymentStatus,
107008
+ onContinuePayment: wizard.handleContinueExistingPayment,
107009
+ onReturnToPayment: wizard.handleReturnToPayment,
107010
+ onReturnToBooking: wizard.handleReturnToBooking
107011
+ }) : null;
107028
107012
  case "success": return wizard.registrationResult ? /* @__PURE__ */ jsx(SuccessStep, {
107029
107013
  title: wizard.registrationResult.title,
107030
107014
  variant: wizard.registrationResult.variant,
@@ -107033,7 +107017,7 @@ function EventRegistrationTerminalState(props) {
107033
107017
  case "error": return /* @__PURE__ */ jsx(ErrorStep, {
107034
107018
  message: wizard.errorMessage,
107035
107019
  action: wizard.errorAction,
107036
- canJoinWaitlist: wizard.eligibility?.isFull && wizard.eligibility.canJoinWaitlist,
107020
+ canJoinWaitlist: wizard.eligibility?.availability.kind === "waitlist" && wizard.eligibility.registration.kind !== "pending_payment",
107037
107021
  onRetry: wizard.handleRetry
107038
107022
  });
107039
107023
  case "select-event":
@@ -107095,6 +107079,7 @@ var init_EventRegistrationSurface = __esmMin((() => {
107095
107079
  init_EventRegistrationWizardActions();
107096
107080
  init_EventRegistrationWizardContent();
107097
107081
  init_PaymentFailedStep();
107082
+ init_PaymentStatusStep();
107098
107083
  init_StepIndicator();
107099
107084
  init_SuccessStep();
107100
107085
  init_VerifyingPaymentStep();
@@ -107232,6 +107217,7 @@ function getWizardStepLabel(input) {
107232
107217
  case "redirecting":
107233
107218
  case "verifying-payment":
107234
107219
  case "verifying-timeout":
107220
+ case "payment-status":
107235
107221
  case "payment-failed": return "";
107236
107222
  }
107237
107223
  }