@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
@@ -3503,7 +3503,10 @@ var init_contentMediaSnapshotAudit = __esmMin((() => {
3503
3503
  init_contentMediaAudit();
3504
3504
  init_contentMediaAuditFieldAdapter();
3505
3505
  init_identifiers();
3506
- })), init_src$1 = __esmMin((() => {
3506
+ }));
3507
+ //#endregion
3508
+ //#region ../media-core/src/index.ts
3509
+ var init_src$1 = __esmMin((() => {
3507
3510
  init_types$15();
3508
3511
  init_fileDomain();
3509
3512
  init_fileStorage();
@@ -3554,6 +3557,14 @@ var init_contentMediaSnapshotAudit = __esmMin((() => {
3554
3557
  init_contentMediaAudit();
3555
3558
  init_contentMediaAuditFieldAdapter();
3556
3559
  init_contentMediaSnapshotAudit();
3560
+ }));
3561
+ var footerModeSchema, init_mode = __esmMin((() => {
3562
+ footerModeSchema = z$1.enum([
3563
+ "default",
3564
+ "blocks",
3565
+ "default+blocks",
3566
+ "none"
3567
+ ]);
3557
3568
  })), hotspotSchema, rotationSchema, rectSchema, aspectCropSchema, transformSchema, mediaPosterSchema, mediaBaseSchema, mediaIdentifierSchema, imageMediaSchema, videoMediaSchema, audioMediaSchema, documentMediaSchema, spreadsheetMediaSchema, archiveMediaSchema, mediaSchema, persistableMediaBaseSchema;
3558
3569
  var init_media$2 = __esmMin((() => {
3559
3570
  hotspotSchema = z$1.object({
@@ -12419,8 +12430,9 @@ var init_boxBackgroundSchema = __esmMin((() => {
12419
12430
  showVideoOnMobile: z$1.boolean().nullable().optional()
12420
12431
  })
12421
12432
  ]);
12422
- })), 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, 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;
12433
+ })), 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, 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;
12423
12434
  var init_schema$2 = __esmMin((() => {
12435
+ init_mode();
12424
12436
  init_media$2();
12425
12437
  init_schema$3();
12426
12438
  init_buttons();
@@ -12919,12 +12931,6 @@ var init_schema$2 = __esmMin((() => {
12919
12931
  "split"
12920
12932
  ]);
12921
12933
  footerMaxWidth = z$1.enum(["container", "full"]);
12922
- footerMode = z$1.enum([
12923
- "default",
12924
- "blocks",
12925
- "default+blocks",
12926
- "none"
12927
- ]);
12928
12934
  footerNavLayoutMode = z$1.enum([
12929
12935
  "stack",
12930
12936
  "inline",
@@ -13013,9 +13019,9 @@ var init_schema$2 = __esmMin((() => {
13013
13019
  /**
13014
13020
  * SDK-only footer rendering mode.
13015
13021
  *
13016
- * Backwards compatible: missing/undefined behaves as 'default'.
13022
+ * Historical persisted field; SDK rendering mode now lives in layout.footerMode.
13017
13023
  */
13018
- mode: footerMode.optional(),
13024
+ mode: footerModeSchema.optional(),
13019
13025
  variant: footerVariant,
13020
13026
  maxWidth: footerMaxWidth,
13021
13027
  showLogoText: z$1.boolean().optional(),
@@ -13605,6 +13611,15 @@ var init_schemas = __esmMin((() => {
13605
13611
  timeZone: z$1.string(),
13606
13612
  pricing: publicEventPricingSchema,
13607
13613
  paymentTerms: blockBookingPaymentTermsSchema,
13614
+ cancellationPolicy: z$1.object({ refunds: z$1.object({
13615
+ mode: z$1.enum([
13616
+ "never",
13617
+ "always",
13618
+ "cutoff"
13619
+ ]),
13620
+ cutoffHours: z$1.number(),
13621
+ method: z$1.enum(["original_payment_method", "site_credit"])
13622
+ }) }),
13608
13623
  consent: blockBookingConsentSchema.nullable(),
13609
13624
  accessRestriction: accessRestrictionSchema,
13610
13625
  allowedCategoryIds: z$1.array(z$1.string()),
@@ -21389,6 +21404,10 @@ var init_headerOpeningForeground = __esmMin((() => {
21389
21404
  init_colorTokenParts();
21390
21405
  init_types$8();
21391
21406
  }));
21407
+ var init_effectivePageDesign = __esmMin((() => {
21408
+ init_pageDesignIntent();
21409
+ init_siteStyleBlockPolicies();
21410
+ }));
21392
21411
  function validateBlockSequence(snapshots, ctx) {
21393
21412
  for (const issue of collectBlockSequenceIssues(snapshots)) ctx.addIssue(issue);
21394
21413
  }
@@ -21665,6 +21684,7 @@ var init_site_styles = __esmMin((() => {
21665
21684
  init_lookResolution();
21666
21685
  init_lookOptionGroups();
21667
21686
  init_logoBranding();
21687
+ init_effectivePageDesign();
21668
21688
  init_pageDesignAuthority();
21669
21689
  init_pageDesignEditorErrors();
21670
21690
  init_pageDesignEditorCapabilities();
@@ -32571,6 +32591,18 @@ var init_wizardSteps$1 = __esmMin((() => {
32571
32591
  }));
32572
32592
  //#endregion
32573
32593
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationDerivations.ts
32594
+ /** Public requests share subject identity without copying the run's display sessions. */
32595
+ function toRegistrationRequestSubject(subject, attendanceMode) {
32596
+ return subject.kind === "occurrence" ? {
32597
+ kind: "occurrence",
32598
+ occurrenceId: subject.occurrenceId,
32599
+ attendanceMode: attendanceMode ?? void 0
32600
+ } : {
32601
+ kind: "wholeSeries",
32602
+ eventSeriesId: subject.eventSeriesId,
32603
+ attendanceMode: attendanceMode ?? void 0
32604
+ };
32605
+ }
32574
32606
  function eventMatchesOccurrenceId(event, occurrenceId) {
32575
32607
  return event.registrationSubject.kind === "occurrence" && (event.registrationSubject.occurrenceId === occurrenceId || event.selectionId === occurrenceId);
32576
32608
  }
@@ -32800,6 +32832,7 @@ function shellLabelForRegistrationStep(step, events) {
32800
32832
  case "redirecting":
32801
32833
  case "verifying-payment":
32802
32834
  case "verifying-timeout":
32835
+ case "payment-status":
32803
32836
  case "payment-failed": return "Details";
32804
32837
  }
32805
32838
  }
@@ -35927,6 +35960,17 @@ const NEWSLETTER_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
35927
35960
  //#region ../api/src/publicEventEndpointDefinitions.ts
35928
35961
  init_src$2();
35929
35962
  const PUBLIC_EVENT_ENDPOINT_DEFINITIONS = defineEndpointDefinitions({
35963
+ checkPublicEventRegistrationNextStep: {
35964
+ path: "/public/sites/{siteId}/events/registration-next-step",
35965
+ method: "POST",
35966
+ auth: "public",
35967
+ responseKind: "json",
35968
+ errors: [
35969
+ "validation:invalid_input",
35970
+ "auth:forbidden",
35971
+ "server:internal_error"
35972
+ ]
35973
+ },
35930
35974
  listPublicEventCalendarWindow: {
35931
35975
  path: "/public/sites/{siteId}/events/calendar-window",
35932
35976
  method: "GET",
@@ -41384,13 +41428,6 @@ const API_ENDPOINTS$1 = {
41384
41428
  auth: "service",
41385
41429
  responseKind: "json"
41386
41430
  },
41387
- sdkCatalogTheme: {
41388
- path: "/sdk/{siteId}/catalog/theme",
41389
- method: "GET",
41390
- errors: ["server:internal_error"],
41391
- auth: "service",
41392
- responseKind: "json"
41393
- },
41394
41431
  sdkCatalogBlocks: {
41395
41432
  path: "/sdk/{siteId}/catalog/blocks",
41396
41433
  method: "GET",
@@ -41451,12 +41488,6 @@ const API_ENDPOINTS$1 = {
41451
41488
  auth: "service",
41452
41489
  responseKind: "json"
41453
41490
  },
41454
- sdkPullTheme: {
41455
- path: "/sdk/{siteId}/pull/theme",
41456
- method: "GET",
41457
- auth: "service",
41458
- responseKind: "json"
41459
- },
41460
41491
  sdkPullFooter: {
41461
41492
  path: "/sdk/{siteId}/pull/footer",
41462
41493
  method: "GET",
@@ -41563,30 +41594,6 @@ const API_ENDPOINTS$1 = {
41563
41594
  auth: "service",
41564
41595
  responseKind: "json"
41565
41596
  },
41566
- sdkUpsertTheme: {
41567
- path: "/sdk/{siteId}/theme",
41568
- method: "POST",
41569
- auth: "service",
41570
- responseKind: "json",
41571
- errors: [
41572
- "validation:invalid_input",
41573
- "resource:not_found",
41574
- "resource:conflict",
41575
- "server:internal_error"
41576
- ]
41577
- },
41578
- sdkApplySiteStyleSelection: {
41579
- path: "/sdk/{siteId}/theme/style-selection/apply",
41580
- method: "POST",
41581
- auth: "service",
41582
- responseKind: "json",
41583
- errors: [
41584
- "validation:invalid_input",
41585
- "resource:not_found",
41586
- "resource:conflict",
41587
- "server:internal_error"
41588
- ]
41589
- },
41590
41597
  sdkUpsertFooter: {
41591
41598
  path: "/sdk/{siteId}/footer",
41592
41599
  method: "POST",
@@ -85448,6 +85455,7 @@ init_buttons();
85448
85455
  init_cards();
85449
85456
  init_tokens();
85450
85457
  init_gradients();
85458
+ init_mode();
85451
85459
  init_richTextSchema();
85452
85460
  init_media();
85453
85461
  init_media$1();
@@ -85460,6 +85468,7 @@ init_events$2();
85460
85468
  init_colorStyles();
85461
85469
  //#endregion
85462
85470
  //#region ../api/src/sdkConfig/contracts.ts
85471
+ init_mode();
85463
85472
  init_src$2();
85464
85473
  /**
85465
85474
  * Canonical SDK config Zod contracts.
@@ -85632,11 +85641,14 @@ const sdkSiteStyleConfigSchema = z$1.object({
85632
85641
  sectionOptions: sdkSectionOptionsConfigSchema.optional(),
85633
85642
  containerOptions: sdkContainerOptionsConfigSchema.optional()
85634
85643
  });
85635
- const sdkSiteLayoutConfigSchema = z$1.object({ footerBlocks: z$1.array(z$1.object({
85636
- id: z$1.string().min(1).optional(),
85637
- kind: z$1.string().min(1),
85638
- content: z$1.record(z$1.string(), z$1.unknown()).optional()
85639
- })).optional() });
85644
+ const sdkSiteLayoutConfigSchema = z$1.object({
85645
+ footerMode: footerModeSchema.optional(),
85646
+ footerBlocks: z$1.array(z$1.object({
85647
+ id: z$1.string().min(1).optional(),
85648
+ kind: z$1.string().min(1),
85649
+ content: z$1.record(z$1.string(), z$1.unknown()).optional()
85650
+ })).optional()
85651
+ });
85640
85652
  const sdkFieldSelectOptionSchema = z$1.object({
85641
85653
  value: z$1.string(),
85642
85654
  label: z$1.string()
@@ -87426,6 +87438,7 @@ init_src$2();
87426
87438
  //#endregion
87427
87439
  //#region ../blocks/src/rendering/server.ts
87428
87440
  init_schema();
87441
+ init_mode();
87429
87442
  //#endregion
87430
87443
  //#region src/rendering/helpers/siteCustomBlocks.ts
87431
87444
  /**
@@ -145577,6 +145590,10 @@ var init_endpoints = __esmMin((() => {
145577
145590
  method: "POST",
145578
145591
  authScope: "portal"
145579
145592
  },
145593
+ registrationNextStep: {
145594
+ path: "/public/sites/{siteId}/events/registration-next-step",
145595
+ method: "POST"
145596
+ },
145580
145597
  registrationStatus: {
145581
145598
  path: "/public/sites/{siteId}/events/registration-status",
145582
145599
  method: "GET"
@@ -146159,6 +146176,13 @@ function createBlockApi(config) {
146159
146176
  body: data
146160
146177
  });
146161
146178
  },
146179
+ async checkRegistrationNextStep(data) {
146180
+ const path = buildPath(EVENTS.registrationNextStep.path, { siteId: requireSiteId() });
146181
+ return request(EVENTS.registrationNextStep, {
146182
+ path,
146183
+ body: data
146184
+ });
146185
+ },
146162
146186
  async getEventRegistrationStatus(params) {
146163
146187
  const sid = requireSiteId();
146164
146188
  const path = buildPath(EVENTS.registrationStatus.path, { siteId: sid });
@@ -154067,7 +154091,7 @@ var init_eventPaymentOptions = __esmMin((() => {
154067
154091
  //#endregion
154068
154092
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationStateMachine.ts
154069
154093
  function hasBlockingExistingRegistration(input) {
154070
- return !input.hasWaitlistClaim && input.isAuthenticated && input.registration.kind !== "none";
154094
+ return !input.hasWaitlistClaim && input.isAuthenticated && input.registration.kind === "waitlisted";
154071
154095
  }
154072
154096
  function createInitialRegistrationFlowState(hasPreSelectedContext) {
154073
154097
  return {
@@ -154119,7 +154143,7 @@ function computeAutoSelection(input) {
154119
154143
  return { method: null };
154120
154144
  }
154121
154145
  function computeDirectPaymentSelection(eligibility) {
154122
- if (!eligibility?.canPayDirectly) return { method: null };
154146
+ if (!eligibility?.requiresPayment) return { method: null };
154123
154147
  const approvedKinds = getApprovedDirectPaymentCollectionOptionKinds(eligibility.paymentOptions);
154124
154148
  const collectionOptionKind = approvedKinds.includes("upfront") ? "upfront" : approvedKinds[0];
154125
154149
  return collectionOptionKind ? {
@@ -154133,7 +154157,7 @@ function isSelectionValid(input) {
154133
154157
  if (!eligibility) return selection.method === "stripe" || selection.method === "pass_bundle" || selection.method === "membership_bundle";
154134
154158
  switch (selection.method) {
154135
154159
  case "free": return eligibility.isFree;
154136
- case "stripe": return Boolean(eligibility.canPayDirectly && eligibility.price);
154160
+ case "stripe": return Boolean(eligibility.requiresPayment && eligibility.price);
154137
154161
  case "pass": return isAuthenticated && ticketsCount === 1 && !!selection.passId && eligibility.eligiblePasses.some((pass) => pass.id === selection.passId);
154138
154162
  case "membership": return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some((membership) => membership.id === selection.membershipId);
154139
154163
  case "pass_bundle": return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some((pass) => pass.id === selection.bundlePassId);
@@ -154152,7 +154176,7 @@ function normalizeRegistrationFlowState(state) {
154152
154176
  ticketsCount: state.ticketsCount,
154153
154177
  passOptOut: nextPassOptOut
154154
154178
  });
154155
- const canKeepManualSelection = state.step === "select-payment" && state.selectionSource === "manual" && isSelectionValid({
154179
+ const canKeepManualSelection = state.step !== "select-tickets" && state.selectionSource === "manual" && isSelectionValid({
154156
154180
  selection: state.paymentSelection,
154157
154181
  isAuthenticated: state.isAuthenticated,
154158
154182
  eligibility: state.eligibility,
@@ -154244,7 +154268,7 @@ function resolveEventRegistrationSubmitPlan(input) {
154244
154268
  const selection = input.paymentSelection.method ? input.paymentSelection : void 0;
154245
154269
  if (input.canJoinWaitlist) return {
154246
154270
  ok: true,
154247
- args: withOptionalSelection({ method: "free" }, selection)
154271
+ args: { method: "free" }
154248
154272
  };
154249
154273
  switch (input.paymentSelection.method) {
154250
154274
  case "pass": return input.paymentSelection.passId ? {
@@ -154313,92 +154337,55 @@ var init_event_registration_headless_state = __esmMin((() => {
154313
154337
  init_event_registration_headless_planning();
154314
154338
  }));
154315
154339
  //#endregion
154316
- //#region ../blocks/src/system/runtime/nodes/event-registration/checkoutRecovery.ts
154317
- /** Recovery may select held places; checkout still owns admission and payment validation. */
154318
- function checkoutRecoveryOptionAvailability(availability) {
154319
- if (availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable") return {
154320
- kind: "available",
154321
- remainingPlaces: null
154322
- };
154323
- return availability;
154340
+ //#region ../blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.ts
154341
+ /** Ticket selection requests a quote; only the server admits a booking. */
154342
+ function canRequestTicketOption(availability) {
154343
+ return availability.kind === "available" || availability.reason === "sold_out" || availability.reason === "overallCapacityUnavailable";
154324
154344
  }
154325
- /**
154326
- * A form-only projection for the explicit existing-checkout path. It permits
154327
- * collecting the original selection without claiming a new place is available.
154328
- * The public checkout service identifies the customer and remains the admission
154329
- * authority; no reservation/customer data is exposed through this projection.
154330
- */
154331
- function getCheckoutRecoveryFormEligibility(eligibility) {
154332
- 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;
154333
- const amountCents = eligibility.price ?? 0;
154334
- if (amountCents <= 0 || !eligibility.currency || eligibility.availability.kind === "unavailable" && eligibility.availability.reason === "selectionRequired") return eligibility.registration.kind === "pending_payment" ? {
154335
- ...eligibility,
154336
- registration: { kind: "none" },
154337
- ticketTypes: eligibility.ticketTypes.map((option) => ({
154338
- ...option,
154339
- availability: checkoutRecoveryOptionAvailability(option.availability)
154340
- }))
154341
- } : eligibility;
154342
- const currency = eligibility.currency;
154343
- const paymentOptions = eligibility.paymentTerms.allowedOptions.map((option) => {
154344
- switch (option.kind) {
154345
- case "upfront": return {
154346
- kind: "payInFull",
154347
- amountCents,
154348
- currency
154349
- };
154350
- case "deferred_manual": return {
154351
- kind: "deferredManual",
154352
- amountCents,
154353
- currency
154354
- };
154355
- case "instalment_plan": return {
154356
- kind: "instalmentPlan",
154357
- amountCents,
154358
- currency
154359
- };
154360
- case "flexible_balance": return {
154361
- kind: "flexibleBalance",
154362
- amountCents,
154363
- currency
154364
- };
154365
- }
154366
- });
154367
- return {
154368
- ...eligibility,
154369
- registration: { kind: "none" },
154370
- availability: {
154371
- kind: "available",
154372
- remainingPlaces: null,
154373
- waitlistEnabled: eligibility.waitlistEnabled
154374
- },
154375
- eligible: paymentOptions.length > 0,
154376
- isFull: false,
154377
- canJoinWaitlist: false,
154378
- isFree: false,
154379
- requiresPayment: true,
154380
- canPayDirectly: paymentOptions.length > 0,
154381
- paymentOptions,
154382
- eligiblePasses: [],
154383
- eligibleMemberships: [],
154384
- ticketTypes: eligibility.ticketTypes.map((option) => ({
154385
- ...option,
154386
- availability: checkoutRecoveryOptionAvailability(option.availability)
154387
- }))
154388
- };
154345
+ function normalizeTicketSelectionLines(lines) {
154346
+ const quantitiesByTicketType = /* @__PURE__ */ new Map();
154347
+ for (const line of lines) {
154348
+ const quantity = Math.floor(line.quantity);
154349
+ if (quantity <= 0) continue;
154350
+ const key = line.pricingOptionId ?? null;
154351
+ quantitiesByTicketType.set(key, (quantitiesByTicketType.get(key) ?? 0) + quantity);
154352
+ }
154353
+ return [...quantitiesByTicketType.entries()].map(([pricingOptionId, quantity]) => ({
154354
+ pricingOptionId,
154355
+ quantity
154356
+ }));
154389
154357
  }
154390
- function isSoldOutEventSelectable(event, waitlistAvailable) {
154391
- return waitlistAvailable || canRecoverEventCheckout(event);
154358
+ function getTicketSelectionTotal(lines) {
154359
+ return normalizeTicketSelectionLines(lines).reduce((total, line) => total + line.quantity, 0);
154392
154360
  }
154393
- function canJoinWaitlistOutsideRecovery(event, attendanceMode, checkoutRecovery) {
154394
- return !checkoutRecovery && event !== null && canJoinEventWaitlist(event, { attendanceMode });
154361
+ function getTicketLineQuantity(lines, pricingOptionId) {
154362
+ return normalizeTicketSelectionLines(lines).find((line) => line.pricingOptionId === pricingOptionId)?.quantity ?? 0;
154395
154363
  }
154396
- function canRecoverEventCheckout(event) {
154397
- return event !== null && (event.registrationSubject.kind === "wholeSeries" || event.pricing.kind !== "free" && event.pricing.kind !== "external");
154364
+ function getSingleSelectedPricingOptionId(lines) {
154365
+ const normalized = normalizeTicketSelectionLines(lines);
154366
+ return normalized.length === 1 ? normalized[0]?.pricingOptionId ?? null : null;
154398
154367
  }
154399
- var init_checkoutRecovery = __esmMin((() => {
154400
- init_domain();
154401
- }));
154368
+ function hasValidPricingOptionSelection(input) {
154369
+ if (!input.selectionRequired) return true;
154370
+ if (input.lines.length === 0) return false;
154371
+ const availableOptionIds = new Set(input.visibleOptions.filter((option) => canRequestTicketOption(option.availability)).map((option) => option.pricingOptionId));
154372
+ return input.lines.every((line) => line.pricingOptionId !== null && availableOptionIds.has(line.pricingOptionId));
154373
+ }
154374
+ function setTicketLineQuantity(input) {
154375
+ const nextQuantity = Math.max(0, Math.floor(input.quantity));
154376
+ const normalized = normalizeTicketSelectionLines(input.lines).filter((line) => line.pricingOptionId !== input.pricingOptionId);
154377
+ if (nextQuantity <= 0) return normalized;
154378
+ return [...normalized, {
154379
+ pricingOptionId: input.pricingOptionId,
154380
+ quantity: nextQuantity
154381
+ }];
154382
+ }
154383
+ function getTicketTypeLineMax(input) {
154384
+ const otherSelectedQuantity = input.totalSelectedQuantity - input.currentQuantity;
154385
+ const maxByBlock = input.maxTickets - otherSelectedQuantity;
154386
+ return Math.max(0, maxByBlock);
154387
+ }
154388
+ var init_ticketSelectionLines = __esmMin((() => {}));
154402
154389
  //#endregion
154403
154390
  //#region ../blocks/src/system/runtime/nodes/event-registration/utils.ts
154404
154391
  function getPortalSubjectEmail(profile) {
@@ -154462,8 +154449,6 @@ function formatPassCreditUsageLabel(creditsRemaining) {
154462
154449
  return `Uses 1 of ${creditsRemaining} credits`;
154463
154450
  }
154464
154451
  function transformRegistrationOptionsResponse(response) {
154465
- const canJoinWaitlist = response.availability.kind === "waitlist";
154466
- const isFull = response.availability.remainingPlaces === 0 || response.availability.kind === "unavailable" && response.availability.reason === "full";
154467
154452
  const eligiblePasses = response.entitlements.passes.map((pass) => ({
154468
154453
  id: pass.customerPassId,
154469
154454
  passName: pass.passName,
@@ -154476,7 +154461,6 @@ function transformRegistrationOptionsResponse(response) {
154476
154461
  const eventAcceptsPasses = response.entitlements.requiresLoginForPasses || eligiblePasses.length > 0 || response.entitlements.availableForPurchase.passes.length > 0;
154477
154462
  const eventAcceptsMemberships = response.entitlements.requiresLoginForMemberships || eligibleMemberships.length > 0 || response.entitlements.availableForPurchase.memberships.length > 0;
154478
154463
  const monetaryPaymentAvailable = hasMonetaryPaymentOption(response);
154479
- const registrationAvailable = response.availability.kind === "available" || response.availability.kind === "waitlist";
154480
154464
  return {
154481
154465
  availability: response.availability,
154482
154466
  registration: response.registration,
@@ -154491,7 +154475,6 @@ function transformRegistrationOptionsResponse(response) {
154491
154475
  },
154492
154476
  transactions: []
154493
154477
  } : null,
154494
- eligible: response.registration.kind === "none" && registrationAvailable,
154495
154478
  requiresPayment: monetaryPaymentAvailable,
154496
154479
  pricingStrategy: response.pricing.strategy,
154497
154480
  paymentTerms: response.pricing.paymentTerms,
@@ -154506,16 +154489,12 @@ function transformRegistrationOptionsResponse(response) {
154506
154489
  currency: response.pricing.currency
154507
154490
  })),
154508
154491
  ticketTypes: response.pricing.options,
154509
- isFull,
154510
- waitlistEnabled: response.availability.waitlistEnabled,
154511
- canJoinWaitlist,
154512
154492
  price: response.pricing.subtotalCents,
154513
154493
  currency: response.pricing.currency,
154514
154494
  requiresAuthForPasses: response.entitlements.requiresLoginForPasses,
154515
154495
  requiresAuthForMemberships: response.entitlements.requiresLoginForMemberships,
154516
154496
  eligiblePasses,
154517
154497
  eligibleMemberships,
154518
- canPayDirectly: monetaryPaymentAvailable,
154519
154498
  eventAcceptsPasses,
154520
154499
  eventAcceptsMemberships,
154521
154500
  availablePasses: [...response.entitlements.availableForPurchase.passes],
@@ -154545,8 +154524,8 @@ function getVisibleTicketTypes(input) {
154545
154524
  })) : [];
154546
154525
  return (input.eligibility?.ticketTypes ?? eventTicketTypes).filter((ticketType) => ticketType.isActive && (!input.selectedAttendanceMode || (ticketType.attendanceScope ?? "both") === "both" || (ticketType.attendanceScope ?? "both") === input.selectedAttendanceMode));
154547
154526
  }
154548
- function getImplicitSingleAvailableTicketType(ticketTypes) {
154549
- return ticketTypes.length === 1 && ticketTypes[0]?.availability.kind === "available" ? ticketTypes[0] : null;
154527
+ function getImplicitSingleTicketType(ticketTypes) {
154528
+ return ticketTypes.length === 1 && ticketTypes[0] && canRequestTicketOption(ticketTypes[0].availability) ? ticketTypes[0] : null;
154550
154529
  }
154551
154530
  function findSelectedTicketType(input) {
154552
154531
  if (!input.selectedPricingOptionId) return null;
@@ -154559,6 +154538,7 @@ function findSelectedTicketType(input) {
154559
154538
  var ENTITLEMENT_SINGLE_TICKET_TOOLTIP;
154560
154539
  var init_utils = __esmMin((() => {
154561
154540
  init_src$2();
154541
+ init_ticketSelectionLines();
154562
154542
  init_shared();
154563
154543
  ENTITLEMENT_SINGLE_TICKET_TOOLTIP = "Only available for single-ticket bookings";
154564
154544
  }));
@@ -154571,7 +154551,6 @@ function getEventSelectionMode(events) {
154571
154551
  }
154572
154552
  var EventSelectionStep;
154573
154553
  var init_EventSelectionStep = __esmMin((() => {
154574
- init_checkoutRecovery();
154575
154554
  init_utils();
154576
154555
  init_domain();
154577
154556
  EventSelectionStep = ({ events, selectedEvent, onSelect, showVenue, showCapacity }) => {
@@ -154588,25 +154567,19 @@ var init_EventSelectionStep = __esmMin((() => {
154588
154567
  const remaining = getRemainingPlaces(selectMostOpenCapacitySource(event));
154589
154568
  const isSoldOut = isEventFull(event);
154590
154569
  const canJoinWaitlist = canJoinEventWaitlistOnAnyMode(event);
154591
- const isUnavailable = isSoldOut && !isSoldOutEventSelectable(event, canJoinWaitlist);
154592
154570
  const isLowCapacity = remaining.kind === "low";
154593
154571
  const capacityLabel = formatEventRemainingPlaces(event, { full: "Sold out" });
154594
154572
  const timeZone = event.timeZone ?? null;
154595
- const cardClasses = [
154596
- "er-event-card",
154597
- isSelected && "er-event-card--selected",
154598
- isUnavailable && "er-event-card--disabled"
154599
- ].filter(Boolean).join(" ");
154573
+ const cardClasses = ["er-event-card", isSelected && "er-event-card--selected"].filter(Boolean).join(" ");
154600
154574
  const badgeClasses = [
154601
154575
  "er-capacity-badge",
154602
- isUnavailable && "er-capacity-badge--soldout",
154576
+ isSoldOut && "er-capacity-badge--soldout",
154603
154577
  isLowCapacity && "er-capacity-badge--low",
154604
- (canJoinWaitlist || !isUnavailable && !isLowCapacity) && "er-capacity-badge--available"
154578
+ (canJoinWaitlist || !isSoldOut && !isLowCapacity) && "er-capacity-badge--available"
154605
154579
  ].filter(Boolean).join(" ");
154606
154580
  return /* @__PURE__ */ jsx("button", {
154607
154581
  type: "button",
154608
- onClick: () => !isUnavailable && onSelect(event),
154609
- disabled: isUnavailable,
154582
+ onClick: () => onSelect(event),
154610
154583
  className: cardClasses,
154611
154584
  children: /* @__PURE__ */ jsxs("div", {
154612
154585
  className: "er-event-option",
@@ -154634,44 +154607,15 @@ var init_EventSelectionStep = __esmMin((() => {
154634
154607
  };
154635
154608
  }));
154636
154609
  //#endregion
154637
- //#region ../blocks/src/system/runtime/nodes/event-registration/useCheckoutRecovery.ts
154638
- /** Recovery belongs to the selected booking subject; changing events resets its scope. */
154639
- function useCheckoutRecovery(event, setStep) {
154640
- const [recoveryEventId, setRecoveryEventId] = useState(null);
154641
- return {
154642
- checkoutRecovery: event !== null && recoveryEventId === event.selectionId,
154643
- startCheckoutRecovery: useCallback(() => {
154644
- if (!event) return;
154645
- setRecoveryEventId(event.selectionId);
154646
- setStep("select-tickets");
154647
- }, [event, setStep])
154648
- };
154649
- }
154650
- /** Authenticated pending bookings enter the same form-only recovery path as guests. */
154651
- function useCheckoutRecoveryEligibility(eligibility, step, checkoutRecovery, startCheckoutRecovery) {
154652
- const registrationKind = eligibility?.registration.kind;
154653
- useEffect(() => {
154654
- if ((step === "select-event" || step === "select-tickets" || step === "enter-details" || step === "select-payment") && registrationKind === "pending_payment" && !checkoutRecovery) startCheckoutRecovery();
154655
- }, [
154656
- registrationKind,
154657
- step,
154658
- checkoutRecovery,
154659
- startCheckoutRecovery
154660
- ]);
154661
- return useMemo(() => checkoutRecovery ? getCheckoutRecoveryFormEligibility(eligibility) : eligibility, [checkoutRecovery, eligibility]);
154662
- }
154663
- var init_useCheckoutRecovery = __esmMin((() => {
154664
- init_checkoutRecovery();
154665
- }));
154666
- //#endregion
154667
154610
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
154668
154611
  function resolveRegistrationRecoveryAction(step, action) {
154669
154612
  if (step === "payment-failed") return "payment-options";
154670
- if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "payment-status";
154613
+ if (step === "payment-status") return "none";
154614
+ if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "none";
154671
154615
  return action;
154672
154616
  }
154673
154617
  function canRecoverToWaitlist(eligibility) {
154674
- return Boolean(eligibility?.isFull && eligibility.canJoinWaitlist);
154618
+ return eligibility?.availability.kind === "waitlist" && eligibility.registration.kind !== "pending_payment";
154675
154619
  }
154676
154620
  function shouldRefreshAfterRegistrationError(step, action, enabled) {
154677
154621
  return enabled || step === "error" && action === "places";
@@ -154688,19 +154632,19 @@ function resetRegistrationAfterExpiry(input) {
154688
154632
  input.setErrorMessage("");
154689
154633
  input.setPendingRegistrationReference(null);
154690
154634
  }
154691
- /** Recovery never starts another payment. Unknown payment outcomes go to the portal. */
154635
+ /** Retry the retained submission in place; explicit payment uncertainty stays status-only. */
154692
154636
  function recoverRegistrationError(action, handlers) {
154693
154637
  switch (action) {
154694
154638
  case "none": return;
154695
154639
  case "portal":
154696
- case "payment-status":
154697
154640
  window.location.assign("/portal");
154698
154641
  return;
154699
154642
  case "event":
154700
154643
  window.location.assign(window.location.pathname);
154701
154644
  return;
154702
154645
  case "retry":
154703
- window.location.reload();
154646
+ handlers.clearError();
154647
+ handlers.setStep("select-payment");
154704
154648
  return;
154705
154649
  case "details":
154706
154650
  handlers.clearError();
@@ -154740,54 +154684,6 @@ function validateFormData(formData, requiresConsent = false) {
154740
154684
  }
154741
154685
  var init_validation = __esmMin((() => {}));
154742
154686
  //#endregion
154743
- //#region ../blocks/src/system/runtime/nodes/event-registration/ticketSelectionLines.ts
154744
- function normalizeTicketSelectionLines(lines) {
154745
- const quantitiesByTicketType = /* @__PURE__ */ new Map();
154746
- for (const line of lines) {
154747
- const quantity = Math.floor(line.quantity);
154748
- if (quantity <= 0) continue;
154749
- const key = line.pricingOptionId ?? null;
154750
- quantitiesByTicketType.set(key, (quantitiesByTicketType.get(key) ?? 0) + quantity);
154751
- }
154752
- return [...quantitiesByTicketType.entries()].map(([pricingOptionId, quantity]) => ({
154753
- pricingOptionId,
154754
- quantity
154755
- }));
154756
- }
154757
- function getTicketSelectionTotal(lines) {
154758
- return normalizeTicketSelectionLines(lines).reduce((total, line) => total + line.quantity, 0);
154759
- }
154760
- function getTicketLineQuantity(lines, pricingOptionId) {
154761
- return normalizeTicketSelectionLines(lines).find((line) => line.pricingOptionId === pricingOptionId)?.quantity ?? 0;
154762
- }
154763
- function getSingleSelectedPricingOptionId(lines) {
154764
- const normalized = normalizeTicketSelectionLines(lines);
154765
- return normalized.length === 1 ? normalized[0]?.pricingOptionId ?? null : null;
154766
- }
154767
- function hasValidPricingOptionSelection(input) {
154768
- if (!input.selectionRequired) return true;
154769
- if (input.lines.length === 0) return false;
154770
- const availableOptionIds = new Set(input.visibleOptions.filter((option) => option.availability.kind === "available").map((option) => option.pricingOptionId));
154771
- return input.lines.every((line) => line.pricingOptionId !== null && availableOptionIds.has(line.pricingOptionId));
154772
- }
154773
- function setTicketLineQuantity(input) {
154774
- const nextQuantity = Math.max(0, Math.floor(input.quantity));
154775
- const normalized = normalizeTicketSelectionLines(input.lines).filter((line) => line.pricingOptionId !== input.pricingOptionId);
154776
- if (nextQuantity <= 0) return normalized;
154777
- return [...normalized, {
154778
- pricingOptionId: input.pricingOptionId,
154779
- quantity: nextQuantity
154780
- }];
154781
- }
154782
- function getTicketTypeLineMax(input) {
154783
- const otherSelectedQuantity = input.totalSelectedQuantity - input.currentQuantity;
154784
- const maxByBlock = input.maxTickets - otherSelectedQuantity;
154785
- const maxByEvent = input.availableSpots == null ? input.maxTickets : input.availableSpots - otherSelectedQuantity;
154786
- const maxByTicketType = input.ticketTypeRemainingCapacity ?? input.maxTickets;
154787
- return Math.max(0, Math.min(maxByBlock, maxByEvent, maxByTicketType));
154788
- }
154789
- var init_ticketSelectionLines = __esmMin((() => {}));
154790
- //#endregion
154791
154687
  //#region ../blocks/src/system/runtime/nodes/event-registration/hooks.state.ts
154792
154688
  function eligibilityLookupReducer(state, action) {
154793
154689
  switch (action.type) {
@@ -154899,17 +154795,6 @@ function usePortalAuthWithDeps(deps) {
154899
154795
  logout
154900
154796
  };
154901
154797
  }
154902
- function toRegistrationOptionsSubject(subject, attendanceMode) {
154903
- return subject.kind === "occurrence" ? {
154904
- kind: "occurrence",
154905
- occurrenceId: subject.occurrenceId,
154906
- attendanceMode: attendanceMode ?? void 0
154907
- } : {
154908
- kind: "wholeSeries",
154909
- eventSeriesId: subject.eventSeriesId,
154910
- attendanceMode: attendanceMode ?? void 0
154911
- };
154912
- }
154913
154798
  function useEligibility(params) {
154914
154799
  return useEligibilityWithDeps(params, eventRegistrationHooksDeps);
154915
154800
  }
@@ -154950,7 +154835,7 @@ function useEligibilityWithDeps(params, deps) {
154950
154835
  requestIdRef.current = requestId;
154951
154836
  dispatch({ type: "loading-started" });
154952
154837
  try {
154953
- const subject = toRegistrationOptionsSubject(params.subject, params.attendanceMode);
154838
+ const subject = toRegistrationRequestSubject(params.subject, params.attendanceMode);
154954
154839
  const result = await api.getRegistrationOptions({
154955
154840
  subject,
154956
154841
  selections: ticketSelections.map((selection) => ({
@@ -155072,6 +154957,7 @@ var init_hooks = __esmMin((() => {
155072
154957
  init_api();
155073
154958
  init_utils();
155074
154959
  init_ticketSelectionLines();
154960
+ init_registrationDerivations();
155075
154961
  init_hooks_state();
155076
154962
  eventRegistrationHooksDeps = { useBlockApi };
155077
154963
  REGISTRATION_OPTIONS_DEBOUNCE_MS = 150;
@@ -155415,7 +155301,6 @@ var init_stripeCommissionMetadata = __esmMin((() => {
155415
155301
  "no_commission_plan",
155416
155302
  "billing_evidence_invalid",
155417
155303
  "fee_rounds_to_zero",
155418
- "non_commissionable_scope",
155419
155304
  "payment_not_stripe"
155420
155305
  ];
155421
155306
  historicalContext = {
@@ -155539,7 +155424,6 @@ var init_stripeMinimumCharge = __esmMin((() => {
155539
155424
  var init_stripeCheckoutReturnUrl = __esmMin((() => {}));
155540
155425
  var init_stateTransitions = __esmMin((() => {
155541
155426
  init_src$2();
155542
- init_assertNever();
155543
155427
  }));
155544
155428
  //#endregion
155545
155429
  //#region ../commerce/src/purchase/event-registration-errors.ts
@@ -155553,9 +155437,9 @@ var init_event_registration_errors = __esmMin((() => {
155553
155437
  message: "Booking is currently closed for this event. Please contact the organiser if you’d like to find out more.",
155554
155438
  action: "none"
155555
155439
  },
155556
- paymentUncertain: {
155557
- 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.",
155558
- action: "payment-status"
155440
+ paymentInvestigationRequired: {
155441
+ message: "We still can’t confirm your payment. Please don’t make another payment. Contact the organiser so they can check your booking.",
155442
+ action: "none"
155559
155443
  },
155560
155444
  paymentProviderUnavailable: {
155561
155445
  message: "We couldn’t reach the payment provider. Please try again in a minute.",
@@ -155607,6 +155491,7 @@ var init_event_registration_errors = __esmMin((() => {
155607
155491
  }
155608
155492
  };
155609
155493
  }));
155494
+ var init_eventCheckoutRecoveryWindow = __esmMin((() => {}));
155610
155495
  //#endregion
155611
155496
  //#region ../commerce/src/purchase/index.ts
155612
155497
  var init_purchase = __esmMin((() => {
@@ -155668,6 +155553,7 @@ var init_purchase = __esmMin((() => {
155668
155553
  init_stripeCheckoutReturnUrl();
155669
155554
  init_stateTransitions();
155670
155555
  init_event_registration_errors();
155556
+ init_eventCheckoutRecoveryWindow();
155671
155557
  init_stripeCommissionMetadata();
155672
155558
  }));
155673
155559
  //#endregion
@@ -156106,7 +155992,30 @@ function checkoutReturnCommand(params) {
156106
155992
  };
156107
155993
  return null;
156108
155994
  }
156109
- async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
155995
+ function handleCheckoutReturnOutcome(options, deps, context, outcome) {
155996
+ const { pending, params } = context;
155997
+ if (outcome.kind === "resolved") {
155998
+ deps.clearReturnParams();
155999
+ options.setPendingRegistrationReference(outcome.reference);
156000
+ options.setStep("verifying-payment");
156001
+ return "settled";
156002
+ }
156003
+ if (outcome.kind === "abandoned") {
156004
+ deps.clearReturnParams();
156005
+ options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
156006
+ options.setStep("select-payment");
156007
+ return "settled";
156008
+ }
156009
+ if (outcome.kind === "notFound" && params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
156010
+ deps.clearReturnParams();
156011
+ options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
156012
+ options.setStep("select-payment");
156013
+ return "settled";
156014
+ }
156015
+ 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.");
156016
+ return outcome.kind === "notFound" ? "settled" : "retryable";
156017
+ }
156018
+ async function handleCheckoutReturn(options, deps, returnContextRef) {
156110
156019
  deps.cleanupStaleRegistrations();
156111
156020
  const params = deps.readReturnParams();
156112
156021
  if (params.registration !== "cancelled" && params.registration !== "success") return "settled";
@@ -156120,34 +156029,15 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
156120
156029
  }
156121
156030
  const { checkoutAttemptId } = command;
156122
156031
  const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
156123
- checkoutAttemptIdRef.current = checkoutAttemptId;
156032
+ returnContextRef.current = { checkoutAttemptId };
156124
156033
  if (pending) restorePendingPresentation(options, pending);
156125
156034
  options.setStep("verifying-payment");
156126
156035
  try {
156127
156036
  const outcome = await options.api.resolveEventCheckoutReturn(command);
156128
- switch (outcome.kind) {
156129
- case "resolved":
156130
- deps.clearReturnParams();
156131
- options.setPendingRegistrationReference(outcome.reference);
156132
- options.setStep("verifying-payment");
156133
- return "settled";
156134
- case "abandoned":
156135
- deps.clearReturnParams();
156136
- options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
156137
- options.setStep("select-payment");
156138
- return "settled";
156139
- case "notFound":
156140
- if (params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
156141
- deps.clearReturnParams();
156142
- options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
156143
- options.setStep("select-payment");
156144
- return "settled";
156145
- }
156146
- 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.");
156147
- return "settled";
156148
- case "reconciliationRequired": break;
156149
- }
156150
- 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.");
156037
+ return handleCheckoutReturnOutcome(options, deps, {
156038
+ pending,
156039
+ params
156040
+ }, outcome);
156151
156041
  } catch {
156152
156042
  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.");
156153
156043
  }
@@ -156156,9 +156046,16 @@ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
156156
156046
  function useEventRegistrationStripeReturn(options) {
156157
156047
  return useEventRegistrationStripeReturnWithDeps(options, eventRegistrationStripeReturnDeps);
156158
156048
  }
156049
+ function completeVerifiedRegistration(options, deps, returnContext) {
156050
+ const siteId = options.api.config.siteId;
156051
+ const checkoutAttemptId = returnContext?.checkoutAttemptId;
156052
+ if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
156053
+ options.setRegistrationResult({ status: "confirmed" });
156054
+ options.setStep("success");
156055
+ }
156159
156056
  function useEventRegistrationStripeReturnWithDeps(options, deps) {
156160
156057
  const { api, pendingRegistrationReference, setErrorMessage, setRegistrationResult, setStep, step } = options;
156161
- const checkoutAttemptIdRef = useRef(null);
156058
+ const returnContextRef = useRef(null);
156162
156059
  const lookupInFlightRef = useRef(false);
156163
156060
  const [lookupState, setLookupState] = useState("settled");
156164
156061
  const resolveReturn = useCallback(async () => {
@@ -156166,7 +156063,7 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
156166
156063
  lookupInFlightRef.current = true;
156167
156064
  setLookupState("loading");
156168
156065
  try {
156169
- setLookupState(await handleCheckoutReturn(options, deps, checkoutAttemptIdRef));
156066
+ setLookupState(await handleCheckoutReturn(options, deps, returnContextRef));
156170
156067
  } finally {
156171
156068
  lookupInFlightRef.current = false;
156172
156069
  }
@@ -156189,13 +156086,8 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
156189
156086
  resolveReturn();
156190
156087
  }, []);
156191
156088
  useEffect(() => {
156192
- if (verification.status === "completed") {
156193
- const siteId = api.config.siteId;
156194
- const checkoutAttemptId = checkoutAttemptIdRef.current;
156195
- if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
156196
- setRegistrationResult({ status: "confirmed" });
156197
- setStep("success");
156198
- } else if (verification.status === "failed") {
156089
+ if (verification.status === "completed") completeVerifiedRegistration(options, deps, returnContextRef.current);
156090
+ else if (verification.status === "failed") {
156199
156091
  setErrorMessage("Please try again or choose another payment option. If this keeps happening, contact the organiser for help.");
156200
156092
  setStep("payment-failed");
156201
156093
  } else if (verification.status === "timeout") setStep("verifying-timeout");
@@ -156254,7 +156146,10 @@ function registrationErrorPresentation(error) {
156254
156146
  const reason = error instanceof BlockApiError ? parseEventRegistrationErrorReason(error.tag) : null;
156255
156147
  if (reason) return eventRegistrationErrors[reason];
156256
156148
  if (error instanceof BlockApiError && error.status < 500) return eventRegistrationErrors.invalidCommitInput;
156257
- return eventRegistrationErrors.paymentUncertain;
156149
+ return {
156150
+ message: "Something went wrong. Please try again.",
156151
+ action: "retry"
156152
+ };
156258
156153
  }
156259
156154
  var init_registrationErrorPresentation = __esmMin((() => {
156260
156155
  init_purchase();
@@ -156283,26 +156178,6 @@ function useEventRegistrationSubmit(options) {
156283
156178
  * and the balance left, which the block's copy cannot. Every other method keeps
156284
156179
  * whatever success message the site configured.
156285
156180
  */
156286
- function toRegistrationResult(result) {
156287
- if (result.alreadyRegistered) {
156288
- const waitlisted = result.status === "waitlist";
156289
- return {
156290
- status: result.status,
156291
- variant: "info",
156292
- title: waitlisted ? "Already waitlisted" : "Already registered",
156293
- message: result.message ?? (waitlisted ? "You are already on the waitlist for this event." : "You are already registered for this event.")
156294
- };
156295
- }
156296
- if (result.status === "waitlist") return {
156297
- status: "waitlist",
156298
- title: "Added to waitlist",
156299
- message: result.message ?? (typeof result.waitlistPosition === "number" ? `You've been added to the waitlist (position ${result.waitlistPosition}).` : "You've been added to the waitlist.")
156300
- };
156301
- return {
156302
- status: result.status,
156303
- message: result.paymentMethod === "pass" ? result.message : void 0
156304
- };
156305
- }
156306
156181
  function useEventRegistrationSubmitWithDeps(options, deps) {
156307
156182
  /**
156308
156183
  * The command identity for the submission currently in progress.
@@ -156316,7 +156191,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
156316
156191
  * Identical retries retain the command after a lost response. Changed form
156317
156192
  * details get a new command so the server applies the new booking intent.
156318
156193
  */
156319
- const commandRef = useRef(null);
156194
+ const { commandRef } = options;
156320
156195
  const inFlightRef = useRef(null);
156321
156196
  const submit = async (method, passId, membershipId, selection, submitOptions) => {
156322
156197
  const target = options.registrationTarget;
@@ -156329,19 +156204,15 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
156329
156204
  const registrationCommandId = commandRef.current?.id ?? deps.createClientCommandId();
156330
156205
  try {
156331
156206
  let prepared = prepareSubmitContext(options, registrationCommandId, target, method, passId, membershipId, selection);
156332
- if (prepared.subject.kind === "wholeSeries" && method === "stripe") {
156333
- commandRef.current = null;
156334
- return await submitWholeSeriesCheckout(options, deps, {
156207
+ let request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
156208
+ const intentKey = registrationRequestIntentKey(request);
156209
+ if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) {
156210
+ prepared = {
156335
156211
  ...prepared,
156336
- subject: prepared.subject
156337
- }, submitOptions);
156212
+ registrationCommandId: deps.createClientCommandId()
156213
+ };
156214
+ request = buildRegistrationRequest(options, prepared, method, passId, membershipId);
156338
156215
  }
156339
- const request = buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId);
156340
- const intentKey = registrationRequestIntentKey(request);
156341
- if (commandRef.current !== null && commandRef.current.intentKey !== intentKey) prepared = {
156342
- ...prepared,
156343
- registrationCommandId: deps.createClientCommandId()
156344
- };
156345
156216
  commandRef.current = {
156346
156217
  id: prepared.registrationCommandId,
156347
156218
  intentKey
@@ -156350,8 +156221,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
156350
156221
  ...request,
156351
156222
  registrationCommandId: prepared.registrationCommandId
156352
156223
  });
156353
- commandRef.current = null;
156354
- return await completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions);
156224
+ return await completeRegistrationSubmission(options, deps, prepared, result, submitOptions);
156355
156225
  } catch (error) {
156356
156226
  if (error instanceof BlockApiError && error.tag === "registrationPreparationChanged") commandRef.current = null;
156357
156227
  const { message, action } = registrationErrorPresentation(error);
@@ -156375,9 +156245,40 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
156375
156245
  return pending;
156376
156246
  };
156377
156247
  }
156378
- async function completeRegistrationSubmission(options, deps, prepared, result, method, submitOptions) {
156379
- if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
156380
- options.setRegistrationResult(toRegistrationResult(result));
156248
+ async function completeRegistrationSubmission(options, deps, prepared, result, submitOptions) {
156249
+ switch (result.kind) {
156250
+ case "paymentStatusRequired":
156251
+ options.setPaymentStatusRecovery({
156252
+ kind: "ready",
156253
+ subject: result.subject
156254
+ });
156255
+ options.setStep("payment-status");
156256
+ return {
156257
+ ok: true,
156258
+ outcome: { kind: "payment_status" }
156259
+ };
156260
+ case "checkoutRequired":
156261
+ options.setPendingRegistrationReference(result.reference);
156262
+ savePendingCheckout(options, deps, prepared, result.submissionId, result.reference);
156263
+ options.setStep("redirecting");
156264
+ return redirectToCheckout(result.checkoutUrl, submitOptions);
156265
+ case "waitlisted":
156266
+ options.setRegistrationResult({
156267
+ status: "waitlist",
156268
+ title: "Added to waitlist",
156269
+ message: result.waitlist.message
156270
+ });
156271
+ break;
156272
+ case "bookingComplete":
156273
+ case "paymentDeferred":
156274
+ options.setPendingRegistrationReference(result.reference);
156275
+ options.setRegistrationResult({
156276
+ status: "confirmed",
156277
+ message: result.summary.paymentMethod === "pass" ? result.summary.message : void 0
156278
+ });
156279
+ break;
156280
+ }
156281
+ options.commandRef.current = null;
156381
156282
  options.setStep("success");
156382
156283
  return {
156383
156284
  ok: true,
@@ -156408,15 +156309,7 @@ function prepareSubmitContext(options, registrationCommandId, target, method, pa
156408
156309
  email: guest.email?.trim().toLowerCase() || void 0,
156409
156310
  phone: guest.phone?.trim() || void 0
156410
156311
  })) : void 0,
156411
- subject: target.subject.kind === "occurrence" ? {
156412
- kind: "occurrence",
156413
- occurrenceId: target.subject.occurrenceId,
156414
- attendanceMode: options.selectedAttendanceMode ?? void 0
156415
- } : {
156416
- kind: "wholeSeries",
156417
- eventSeriesId: target.subject.eventSeriesId,
156418
- attendanceMode: options.selectedAttendanceMode ?? void 0
156419
- }
156312
+ subject: toRegistrationRequestSubject(target.subject, options.selectedAttendanceMode)
156420
156313
  };
156421
156314
  }
156422
156315
  function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId, selection) {
@@ -156440,85 +156333,6 @@ function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId,
156440
156333
  if (method === "free") return { method };
156441
156334
  throw new Error("Choose an available payment option.");
156442
156335
  }
156443
- async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions) {
156444
- options.setStep("redirecting");
156445
- if (prepared.selectionSnapshot.method !== "stripe") throw new Error("Choose an available payment option.");
156446
- const checkoutAttemptId = deps.createClientCommandId();
156447
- const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
156448
- const result = await options.api.createEventCheckout({
156449
- subject: prepared.subject,
156450
- ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
156451
- selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
156452
- email: options.formData.email.trim().toLowerCase(),
156453
- name: options.formData.name.trim(),
156454
- phone: options.formData.phone.trim() || void 0,
156455
- formData: options.formData,
156456
- consentAccepted: options.formData.consentAccepted,
156457
- altchaSolution: options.altchaSolution,
156458
- guests: prepared.guestsPayload,
156459
- claimToken: options.claimToken ?? void 0,
156460
- waitlistEntryId: options.waitlistEntryId ?? void 0,
156461
- discountCode: options.discountCode.trim() || void 0,
156462
- collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
156463
- checkoutAttemptId,
156464
- ...urls
156465
- });
156466
- if (result.scope !== "wholeSeries") throw new Error("Unexpected registration scope for event checkout.");
156467
- if ("waitlistEntryId" in result) {
156468
- options.setRegistrationResult({
156469
- status: "waitlist",
156470
- variant: result.alreadyRegistered ? "info" : void 0,
156471
- title: result.alreadyRegistered ? "Already waitlisted" : "Added to waitlist",
156472
- message: result.alreadyRegistered ? "You are already on the waitlist for this event." : "You've been added to the waitlist."
156473
- });
156474
- options.setStep("success");
156475
- return {
156476
- ok: true,
156477
- outcome: { kind: "completed" }
156478
- };
156479
- }
156480
- if (result.bypassed) return completeBypassedCheckout(options);
156481
- if (!result.checkoutUrl) throw new Error("Checkout URL missing");
156482
- savePendingCheckout(options, deps, prepared, result.checkoutAttemptId, {
156483
- scope: "wholeSeries",
156484
- registrationId: result.registrationId
156485
- });
156486
- return redirectToCheckout(result.checkoutUrl, submitOptions);
156487
- }
156488
- function needsOccurrenceCheckout(result, method) {
156489
- return result.scope === "occurrence" && result.status === "confirmed" && result.pendingPayment && [
156490
- "stripe",
156491
- "pass_bundle",
156492
- "membership_bundle"
156493
- ].includes(method);
156494
- }
156495
- async function submitOccurrenceCheckout(options, deps, prepared, registration, method, submitOptions) {
156496
- const reference = {
156497
- scope: "occurrence",
156498
- attendeeId: registration.attendeeId
156499
- };
156500
- options.setPendingRegistrationReference(reference);
156501
- options.setStep("redirecting");
156502
- const checkoutAttemptId = deps.createClientCommandId();
156503
- const urls = buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: checkoutAttemptId });
156504
- const result = await options.api.createEventCheckout({
156505
- subject: {
156506
- kind: "occurrence",
156507
- attendeeId: registration.attendeeId
156508
- },
156509
- registrationCommandId: prepared.registrationCommandId,
156510
- checkoutType: method === "pass_bundle" ? "pass_bundle" : method === "membership_bundle" ? "membership_bundle" : "event",
156511
- productId: prepared.bundleProductId,
156512
- discountCode: options.discountCode.trim() || void 0,
156513
- collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0,
156514
- ...urls
156515
- });
156516
- if (result.scope !== "occurrence") throw new Error("Unexpected registration scope for event checkout.");
156517
- if (result.bypassed) return completeBypassedCheckout(options);
156518
- if (!result.checkoutUrl) throw new Error("Checkout URL missing");
156519
- if (prepared.subject.kind === "occurrence") savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference);
156520
- return redirectToCheckout(result.checkoutUrl, submitOptions);
156521
- }
156522
156336
  function savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference) {
156523
156337
  const siteId = options.api.config.siteId;
156524
156338
  if (!siteId) return;
@@ -156531,14 +156345,6 @@ function savePendingCheckout(options, deps, prepared, checkoutAttemptId, referen
156531
156345
  paymentSelection: prepared.selectionSnapshot
156532
156346
  });
156533
156347
  }
156534
- function completeBypassedCheckout(options) {
156535
- options.setRegistrationResult({ status: "confirmed" });
156536
- options.setStep("success");
156537
- return {
156538
- ok: true,
156539
- outcome: { kind: "completed" }
156540
- };
156541
- }
156542
156348
  function redirectToCheckout(checkoutUrl, submitOptions) {
156543
156349
  if (submitOptions?.redirect !== "manual") window.location.href = checkoutUrl;
156544
156350
  return {
@@ -156550,12 +156356,23 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
156550
156356
  };
156551
156357
  }
156552
156358
  function registrationRequestIntentKey(request) {
156553
- const { registrationCommandId: _command, altchaSolution: _proof, ...intent } = request;
156554
- return JSON.stringify(intent);
156359
+ const { registrationCommandId: _command, altchaSolution: _proof, checkout, ...intent } = request;
156360
+ return JSON.stringify({
156361
+ ...intent,
156362
+ checkout: checkout ? {
156363
+ discountCode: checkout.discountCode,
156364
+ collectionOptionKind: checkout.collectionOptionKind
156365
+ } : void 0
156366
+ });
156555
156367
  }
156556
- function buildOccurrenceRegistrationRequest(options, prepared, method, passId, membershipId) {
156368
+ function buildRegistrationRequest(options, prepared, method, passId, membershipId) {
156557
156369
  return {
156558
156370
  registrationCommandId: prepared.registrationCommandId,
156371
+ checkout: {
156372
+ ...buildCheckoutReturnUrls("registration", EVENT_REGISTRATION_ANCHOR_ID, { [EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]: prepared.registrationCommandId }),
156373
+ discountCode: options.discountCode.trim() || void 0,
156374
+ collectionOptionKind: prepared.selectionSnapshot.method === "stripe" ? prepared.selectionSnapshot.collectionOptionKind : void 0
156375
+ },
156559
156376
  subject: prepared.subject,
156560
156377
  ticketSelections: toTicketSelectionRequests(prepared.ticketSelections),
156561
156378
  selectedSlidingAmount: options.selectedSlidingAmount ?? void 0,
@@ -156580,6 +156397,7 @@ var init_useEventRegistrationSubmit = __esmMin((() => {
156580
156397
  init_shared();
156581
156398
  init_registrationErrorPresentation();
156582
156399
  init_constants();
156400
+ init_registrationDerivations();
156583
156401
  init_sessionStorage();
156584
156402
  init_ticketSelectionLines();
156585
156403
  eventRegistrationSubmitDeps = {
@@ -156797,23 +156615,128 @@ var init_useWaitlistClaimRestoration = __esmMin((() => {
156797
156615
  }));
156798
156616
  //#endregion
156799
156617
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationCompletion.ts
156618
+ function isSelectionSoldOut(availability) {
156619
+ return availability?.kind === "unavailable" && availability.reason === "full";
156620
+ }
156800
156621
  function resolveRegistrationAvailabilityBlocker(input) {
156801
156622
  if (input.hasWaitlistClaim) return null;
156802
156623
  if (input.eligibilityError) return input.eligibilityError;
156803
156624
  if (!input.eligibility) return "Registration is not available for this event.";
156625
+ if (input.eligibility.registration.kind === "pending_payment") return null;
156626
+ if (isSelectionSoldOut(input.eligibility.availability)) return null;
156804
156627
  if (input.eligibility.availability.kind === "unavailable" && input.eligibility.availability.reason === "paymentUnavailable") return "Payment options are not available for this event.";
156805
- if (input.eligibility.availability.kind === "unavailable" || !input.eligibility.eligible) return "Registration is not available for this event.";
156628
+ if (input.eligibility.availability.kind === "unavailable" || input.eligibility.registration.kind === "waitlisted") return "Registration is not available for this event.";
156806
156629
  return null;
156807
156630
  }
156808
156631
  function resolvePricingSelectionBlocker(input) {
156809
156632
  if (input.selectionRequired && !input.hasValidSelection) return "Choose at least one available ticket to continue.";
156810
156633
  return input.slidingScaleSelectionMessage;
156811
156634
  }
156812
- function isSoldOutWithoutWaitlist(input) {
156813
- return Boolean(!input.hasWaitlistClaim && input.eligibility?.isFull && !input.eligibility.canJoinWaitlist);
156814
- }
156815
156635
  var init_registrationCompletion = __esmMin((() => {}));
156816
156636
  //#endregion
156637
+ //#region ../blocks/src/system/runtime/nodes/event-registration/usePaymentStatusRecovery.ts
156638
+ function isCheckableRecovery(state) {
156639
+ return state.kind === "ready" || state.kind === "processing" || state.kind === "temporarilyUnavailable";
156640
+ }
156641
+ function assistanceRequired(recovery) {
156642
+ return {
156643
+ kind: "assistanceRequired",
156644
+ subject: recovery.subject
156645
+ };
156646
+ }
156647
+ function applyStatusOutcome(outcome, recovery, setters, setRecovery) {
156648
+ if (outcome.kind === "resolved") {
156649
+ setters.setPendingRegistrationReference(outcome.reference);
156650
+ setters.setRegistrationResult({ status: "confirmed" });
156651
+ setRecovery(null);
156652
+ setters.setStep("success");
156653
+ return;
156654
+ }
156655
+ switch (outcome.kind) {
156656
+ case "paymentProcessing":
156657
+ setRecovery({
156658
+ ...recovery,
156659
+ kind: "processing"
156660
+ });
156661
+ return;
156662
+ case "paymentAvailable":
156663
+ setRecovery({
156664
+ ...recovery,
156665
+ kind: "paymentAvailable",
156666
+ checkoutUrl: outcome.checkoutUrl
156667
+ });
156668
+ return;
156669
+ case "paymentCheckUnavailable":
156670
+ setRecovery({
156671
+ ...recovery,
156672
+ kind: "temporarilyUnavailable"
156673
+ });
156674
+ return;
156675
+ case "paymentRetryAvailable":
156676
+ setRecovery({
156677
+ ...recovery,
156678
+ kind: "retryAvailable"
156679
+ });
156680
+ return;
156681
+ case "abandoned":
156682
+ case "notFound":
156683
+ case "reconciliationRequired":
156684
+ case "paymentAssistanceRequired":
156685
+ setRecovery(assistanceRequired(recovery));
156686
+ return;
156687
+ }
156688
+ }
156689
+ function usePaymentStatusRecovery(options) {
156690
+ const [recovery, setRecovery] = useState(null);
156691
+ const checkRef = useRef(null);
156692
+ return {
156693
+ recovery,
156694
+ showRecovery: useCallback((next) => setRecovery(next), []),
156695
+ check: useCallback(() => {
156696
+ if (!recovery || !isCheckableRecovery(recovery) || checkRef.current) return;
156697
+ const pending = (async () => {
156698
+ setRecovery({
156699
+ ...recovery,
156700
+ kind: "checking"
156701
+ });
156702
+ try {
156703
+ applyStatusOutcome(await options.api.resolveEventCheckoutReturn({
156704
+ kind: "checkStatus",
156705
+ subject: recovery.subject
156706
+ }), recovery, options, setRecovery);
156707
+ } catch {
156708
+ setRecovery({
156709
+ ...recovery,
156710
+ kind: "temporarilyUnavailable"
156711
+ });
156712
+ }
156713
+ })();
156714
+ checkRef.current = pending;
156715
+ pending.finally(() => {
156716
+ if (checkRef.current === pending) checkRef.current = null;
156717
+ });
156718
+ }, [options, recovery]),
156719
+ continuePayment: useCallback(() => {
156720
+ if (recovery?.kind === "paymentAvailable") window.location.assign(recovery.checkoutUrl);
156721
+ }, [recovery]),
156722
+ returnToPayment: useCallback(() => {
156723
+ if (recovery?.kind !== "retryAvailable") return;
156724
+ options.beginNewSubmission();
156725
+ setRecovery(null);
156726
+ options.setOptionsRefreshKey((value) => value + 1);
156727
+ options.setStep("select-payment");
156728
+ }, [options, recovery]),
156729
+ returnToBooking: useCallback(() => {
156730
+ if (recovery?.kind !== "assistanceRequired") return;
156731
+ options.beginNewSubmission();
156732
+ setRecovery(null);
156733
+ options.setOptionsRefreshKey((value) => value + 1);
156734
+ options.setStep("select-tickets");
156735
+ }, [options, recovery])
156736
+ };
156737
+ }
156738
+ var init_usePaymentStatusRecovery = __esmMin((() => {}));
156739
+ //#endregion
156817
156740
  //#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
156818
156741
  function usesTieredPricing(event) {
156819
156742
  return event !== null && event !== void 0 ? publicEventPricingStrategy(event.pricing) === "tiered" : false;
@@ -156860,6 +156783,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
156860
156783
  const [errorAction, setErrorAction] = useState("retry");
156861
156784
  const [optionsRefreshKey, setOptionsRefreshKey] = useState(0);
156862
156785
  const [altchaSolution, setAltchaSolution] = useState(null);
156786
+ const [checkingNextStep, setCheckingNextStep] = useState(false);
156863
156787
  const { authState: portalAuthState, profile: portalProfile } = deps.usePortalAuth();
156864
156788
  const waitlistClaim = deps.useWaitlistClaim();
156865
156789
  const [showMagicLinkModal, setShowMagicLinkModal] = useState(false);
@@ -156886,28 +156810,29 @@ function useEventRegistrationWizardWithDeps(options, deps) {
156886
156810
  }), [options.occurrenceContext, selectedEvent]);
156887
156811
  const registrationOccurrenceId = getRegistrationOccurrenceId(registrationTarget);
156888
156812
  const currentEvent = selectedEvent ?? preSelectedEvent;
156813
+ const commandRef = useRef(null);
156889
156814
  const setStep = useCallback((nextStep) => {
156890
156815
  dispatchFlow({
156891
156816
  type: "set-step",
156892
156817
  step: nextStep
156893
156818
  });
156894
156819
  }, []);
156895
- const { checkoutRecovery, startCheckoutRecovery } = useCheckoutRecovery(currentEvent, setStep);
156896
- const currentEventUsesTicketTypes = usesTieredPricing(currentEvent);
156897
- const currentCanJoinWaitlist = canJoinWaitlistOutsideRecovery(currentEvent, selectedAttendanceMode, checkoutRecovery);
156898
- const usesTicketTypeSelections = currentEventUsesTicketTypes && !currentCanJoinWaitlist;
156820
+ const { recovery: paymentStatusRecovery, showRecovery: setPaymentStatusRecovery, check: handleCheckPaymentStatus, continuePayment: handleContinueExistingPayment, returnToPayment: handleReturnToPayment, returnToBooking: handleReturnToBooking } = usePaymentStatusRecovery({
156821
+ api,
156822
+ beginNewSubmission: () => {
156823
+ commandRef.current = null;
156824
+ },
156825
+ setPendingRegistrationReference,
156826
+ setRegistrationResult,
156827
+ setOptionsRefreshKey,
156828
+ setStep
156829
+ });
156830
+ const usesTicketTypeSelections = usesTieredPricing(currentEvent);
156899
156831
  const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
156900
156832
  event: currentEvent,
156901
156833
  eligibility: null,
156902
156834
  selectedAttendanceMode
156903
- }).map((option) => checkoutRecovery ? {
156904
- ...option,
156905
- availability: checkoutRecoveryOptionAvailability(option.availability)
156906
- } : option), [
156907
- currentEvent,
156908
- selectedAttendanceMode,
156909
- checkoutRecovery
156910
- ]);
156835
+ }), [currentEvent, selectedAttendanceMode]);
156911
156836
  const normalizedSelectedTicketLines = useMemo(() => normalizeTicketSelectionLines(selectedTicketLines), [selectedTicketLines]);
156912
156837
  const ticketTypeSelectionTotal = useMemo(() => getTicketSelectionTotal(normalizedSelectedTicketLines), [normalizedSelectedTicketLines]);
156913
156838
  const ticketsCount = usesTicketTypeSelections ? ticketTypeSelectionTotal : flowState.ticketsCount;
@@ -156945,7 +156870,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
156945
156870
  isAuthenticated: portalAuthState === "authenticated",
156946
156871
  occurrenceId: registrationOccurrenceId
156947
156872
  });
156948
- const eligibility = useCheckoutRecoveryEligibility(eligibilityResult.eligibility, step, checkoutRecovery, startCheckoutRecovery);
156873
+ const eligibility = eligibilityResult.eligibility;
156949
156874
  const eligibilityLoading = eligibilityResult.isLoading;
156950
156875
  const eligibilityError = eligibilityResult.error;
156951
156876
  const portalCreditState = eligibilityResult.creditState;
@@ -157057,14 +156982,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157057
156982
  event: currentEvent,
157058
156983
  eligibility,
157059
156984
  selectedAttendanceMode
157060
- }).map((option) => checkoutRecovery ? {
157061
- ...option,
157062
- availability: checkoutRecoveryOptionAvailability(option.availability)
157063
- } : option), [
156985
+ }), [
157064
156986
  currentEvent,
157065
156987
  selectedAttendanceMode,
157066
- eligibility,
157067
- checkoutRecovery
156988
+ eligibility
157068
156989
  ]);
157069
156990
  const singleSelectedPricingOptionId = getSingleSelectedPricingOptionId(normalizedSelectedTicketLines);
157070
156991
  const selectedTicketType = useMemo(() => findSelectedTicketType({
@@ -157088,12 +157009,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157088
157009
  const event = currentEvent;
157089
157010
  if (!usesTieredPricing(event)) return false;
157090
157011
  if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
157091
- return checkoutRecovery || !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
157092
- }, [
157093
- currentEvent,
157094
- selectedAttendanceMode,
157095
- checkoutRecovery
157096
- ]);
157012
+ return true;
157013
+ }, [currentEvent, selectedAttendanceMode]);
157097
157014
  const hasValidTicketSelection = hasValidPricingOptionSelection({
157098
157015
  selectionRequired: ticketTypeSelectionRequired,
157099
157016
  lines: normalizedSelectedTicketLines,
@@ -157104,8 +157021,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157104
157021
  if (selectedTicketLines.length > 0) setSelectedTicketLines([]);
157105
157022
  return;
157106
157023
  }
157107
- const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => ticketType.availability.kind === "available");
157108
- const implicitTicketType = getImplicitSingleAvailableTicketType(eventTicketTypesForSelection);
157024
+ const availableTicketTypes = eventTicketTypesForSelection.filter((ticketType) => canRequestTicketOption(ticketType.availability));
157025
+ const implicitTicketType = getImplicitSingleTicketType(eventTicketTypesForSelection);
157109
157026
  if (implicitTicketType && normalizedSelectedTicketLines.length === 0) {
157110
157027
  setSelectedTicketLines([{
157111
157028
  pricingOptionId: implicitTicketType.pricingOptionId,
@@ -157172,6 +157089,26 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157172
157089
  selectedEventSlidingScale,
157173
157090
  selectedSlidingAmount
157174
157091
  ]);
157092
+ const checkDetailsNextStep = async () => {
157093
+ if (portalAuthState === "authenticated" || waitlistClaim.claim || eligibility?.availability.kind === "available" || !registrationTarget) return { kind: canRecoverToWaitlist(eligibility) ? "waitlist" : "continue" };
157094
+ setCheckingNextStep(true);
157095
+ try {
157096
+ return await api.checkRegistrationNextStep({
157097
+ subject: toRegistrationRequestSubject(registrationTarget.subject, selectedAttendanceMode),
157098
+ selections: ticketSelections,
157099
+ selectedSlidingAmount: selectedSlidingAmount ?? void 0,
157100
+ email: formData.email,
157101
+ altchaSolution
157102
+ });
157103
+ } catch {
157104
+ return {
157105
+ kind: "unavailable",
157106
+ message: "We could not check availability. Please try again."
157107
+ };
157108
+ } finally {
157109
+ setCheckingNextStep(false);
157110
+ }
157111
+ };
157175
157112
  const handleDetailsComplete = async () => {
157176
157113
  const blockDetailsCompletion = (message) => {
157177
157114
  setErrorAction("places");
@@ -157203,11 +157140,10 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157203
157140
  message: "Check the highlighted fields and try again."
157204
157141
  };
157205
157142
  }
157206
- if (isSoldOutWithoutWaitlist({
157207
- hasWaitlistClaim: waitlistClaim.claim !== null,
157208
- eligibility
157209
- })) return blockDetailsCompletion("Sorry, there aren’t enough places left for your selection. Please check the available places and choose again.");
157210
- if (!eligibility?.canJoinWaitlist && requiresPaymentStep({
157143
+ const next = await checkDetailsNextStep();
157144
+ if (next.kind === "unavailable") return blockDetailsCompletion(next.message);
157145
+ const canJoinWaitlist = next.kind === "waitlist";
157146
+ if (!canJoinWaitlist && requiresPaymentStep({
157211
157147
  eventRequiresPayment,
157212
157148
  paymentSelection
157213
157149
  })) {
@@ -157220,7 +157156,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157220
157156
  const submitPlan = resolveEventRegistrationSubmitPlan({
157221
157157
  paymentSelection,
157222
157158
  eventRequiresPayment,
157223
- canJoinWaitlist: eligibility?.canJoinWaitlist
157159
+ canJoinWaitlist
157224
157160
  });
157225
157161
  if (!submitPlan.ok) return blockDetailsCompletion(submitPlan.message);
157226
157162
  const submitResult = await handleSubmit(submitPlan.args.method, submitPlan.args.passId, submitPlan.args.membershipId, submitPlan.args.selection);
@@ -157238,7 +157174,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157238
157174
  const submitPlan = resolveEventRegistrationSubmitPlan({
157239
157175
  paymentSelection,
157240
157176
  eventRequiresPayment,
157241
- canJoinWaitlist: eligibility?.canJoinWaitlist
157177
+ canJoinWaitlist: false
157242
157178
  });
157243
157179
  if (!submitPlan.ok) {
157244
157180
  setErrorMessage(submitPlan.message);
@@ -157270,6 +157206,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157270
157206
  const selectionMethod = paymentSelection.method;
157271
157207
  const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
157272
157208
  const handleSubmit = deps.useEventRegistrationSubmit({
157209
+ commandRef,
157273
157210
  setErrorAction,
157274
157211
  api,
157275
157212
  registrationTarget,
@@ -157286,7 +157223,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157286
157223
  setPendingRegistrationReference,
157287
157224
  setStep,
157288
157225
  setRegistrationResult: (result) => setRegistrationResult(result),
157289
- setErrorMessage
157226
+ setErrorMessage,
157227
+ setPaymentStatusRecovery
157290
157228
  });
157291
157229
  const handleEventSelect = (event) => {
157292
157230
  setSelectedEvent(event);
@@ -157345,8 +157283,6 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157345
157283
  scopedEvents,
157346
157284
  preSelectedEvent,
157347
157285
  hasPreSelectedContext,
157348
- checkoutRecovery,
157349
- startCheckoutRecovery,
157350
157286
  step,
157351
157287
  setStep,
157352
157288
  selectedEvent,
@@ -157400,7 +157336,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157400
157336
  waitlistClaim,
157401
157337
  eligibility,
157402
157338
  registrationOptionsState: eligibilityResult.state,
157403
- eligibilityLoading,
157339
+ eligibilityLoading: eligibilityLoading || checkingNextStep,
157404
157340
  eligibilityError,
157405
157341
  existingRegistration: existingRegistrationResult.registration,
157406
157342
  existingRegistrationLoading: existingRegistrationResult.isLoading || portalAuthState === "authenticated" && eligibilityLoading,
@@ -157420,6 +157356,11 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157420
157356
  discountContext,
157421
157357
  shouldShowDiscountToggle,
157422
157358
  verification,
157359
+ paymentStatusRecovery,
157360
+ handleCheckPaymentStatus,
157361
+ handleContinueExistingPayment,
157362
+ handleReturnToPayment,
157363
+ handleReturnToBooking,
157423
157364
  handleDetailsComplete,
157424
157365
  handlePaymentSelect,
157425
157366
  handleUseCardInsteadOfPass,
@@ -157431,12 +157372,9 @@ function useEventRegistrationWizardWithDeps(options, deps) {
157431
157372
  }
157432
157373
  var eventRegistrationWizardDeps;
157433
157374
  var init_useEventRegistrationWizard = __esmMin((() => {
157434
- init_checkoutRecovery();
157435
- init_useCheckoutRecovery();
157436
157375
  init_src$2();
157437
157376
  init_registrationErrorRecovery();
157438
157377
  init_api();
157439
- init_domain();
157440
157378
  init_validation();
157441
157379
  init_hooks();
157442
157380
  init_portalLogout();
@@ -157456,6 +157394,7 @@ var init_useEventRegistrationWizard = __esmMin((() => {
157456
157394
  init_waitlistClaimRestoration();
157457
157395
  init_useWaitlistClaimRestoration();
157458
157396
  init_registrationCompletion();
157397
+ init_usePaymentStatusRecovery();
157459
157398
  eventRegistrationWizardDeps = {
157460
157399
  usePortalAuth,
157461
157400
  useEligibility,
@@ -157639,7 +157578,6 @@ var init_ErrorStep = __esmMin((() => {
157639
157578
  start: "Start again",
157640
157579
  details: "Check my details",
157641
157580
  "payment-options": "View payment options",
157642
- "payment-status": "Check payment status",
157643
157581
  portal: "View my bookings",
157644
157582
  event: "View event"
157645
157583
  };
@@ -157658,7 +157596,7 @@ var init_ErrorStep = __esmMin((() => {
157658
157596
  className: "er-text--muted er-message",
157659
157597
  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
157660
157598
  }),
157661
- actions: action === "none" ? void 0 : action === "portal" || action === "payment-status" ? /* @__PURE__ */ jsx("a", {
157599
+ actions: action === "none" ? void 0 : action === "portal" ? /* @__PURE__ */ jsx("a", {
157662
157600
  href: "/portal",
157663
157601
  className: "er-retry-btn",
157664
157602
  children: labels[action]
@@ -157919,8 +157857,11 @@ var init_EventRegistrationSummaryBar = __esmMin((() => {
157919
157857
  */
157920
157858
  function resolveDetailsButtonText(input) {
157921
157859
  const { wizard } = input;
157922
- if (wizard.eligibility?.canJoinWaitlist) return "Join waitlist";
157923
- if (!input.hasWaitlistClaim && wizard.eligibility?.isFull) return "Sold out";
157860
+ const availability = wizard.eligibility?.availability;
157861
+ const full = availability?.kind === "waitlist" || isSelectionSoldOut(availability);
157862
+ if (wizard.portalAuthState !== "authenticated" && full) return "Continue";
157863
+ if (canRecoverToWaitlist(wizard.eligibility)) return "Join waitlist";
157864
+ if (!input.hasWaitlistClaim && full && wizard.eligibility?.registration.kind !== "pending_payment") return "Sold out";
157924
157865
  if (wizard.paymentSelection.method === "pass") return "Book using class pass";
157925
157866
  if (wizard.paymentSelection.method === "membership") return input.fallbackText;
157926
157867
  return wizard.eventRequiresPayment ? "Continue to payment" : input.fallbackText;
@@ -157935,44 +157876,28 @@ function isExistingRegistrationBlocking$1(wizard) {
157935
157876
  hasWaitlistClaim: wizard.waitlistClaim.claim !== null
157936
157877
  });
157937
157878
  }
157938
- /**
157939
- * Full for the visitor's selected attendance mode (or the whole event when no
157940
- * mode is chosen) with no waitlist to fall back on. Reads the same capacity
157941
- * source as the steps above the action bar so the button never disagrees
157942
- * with them on a hybrid event.
157943
- */
157944
- function isFullWithNoWaitlist(event, attendanceMode) {
157945
- if (!event) return false;
157946
- const source = selectEventCapacitySource(event, attendanceMode);
157947
- return getEventAvailability(source).isFull && !source.waitlistEnabled;
157948
- }
157949
157879
  function resolveTicketSelectionContinueLabel(input) {
157950
157880
  if (input.isCheckingExistingRegistration) return "Checking registration...";
157951
157881
  if (input.registrationOptionsPending) return "Checking availability...";
157952
157882
  if (input.registrationOptionsFailed) return "Availability unavailable";
157953
157883
  if (input.hasExistingRegistration) return resolveExistingRegistrationLabel(input.wizard);
157954
- if (input.isSoldOutWithoutWaitlist) return "Sold out";
157955
157884
  if (input.ticketTypeSelectionBlocked) return "Choose a ticket";
157956
157885
  return "Continue";
157957
157886
  }
157958
157887
  function SelectTicketsActions(props) {
157959
157888
  const { wizard } = props;
157960
- const hasWaitlistClaim = wizard.waitlistClaim.claim !== null;
157961
- const currentEvent = wizard.selectedEvent ?? wizard.preSelectedEvent;
157962
157889
  const registrationOptionsPending = wizard.registrationOptionsState.tag === "idle" || wizard.registrationOptionsState.tag === "loading";
157963
157890
  const registrationOptionsFailed = wizard.registrationOptionsState.tag === "failed";
157964
- const isSoldOutWithoutWaitlist = !wizard.checkoutRecovery && !hasWaitlistClaim && isFullWithNoWaitlist(currentEvent, wizard.selectedAttendanceMode);
157965
157891
  const isCheckingExistingRegistration = wizard.portalAuthState === "authenticated" && wizard.existingRegistrationLoading;
157966
157892
  const hasExistingRegistration = isExistingRegistrationBlocking$1(wizard);
157967
157893
  const ticketTypeSelectionBlocked = wizard.ticketTypeSelectionRequired && !wizard.hasValidTicketSelection;
157968
- const isContinueDisabled = registrationOptionsPending || registrationOptionsFailed || isCheckingExistingRegistration || hasExistingRegistration || isSoldOutWithoutWaitlist || ticketTypeSelectionBlocked;
157894
+ const isContinueDisabled = registrationOptionsPending || registrationOptionsFailed || isCheckingExistingRegistration || hasExistingRegistration || ticketTypeSelectionBlocked;
157969
157895
  const continueLabel = resolveTicketSelectionContinueLabel({
157970
157896
  wizard,
157971
157897
  registrationOptionsPending,
157972
157898
  registrationOptionsFailed,
157973
157899
  isCheckingExistingRegistration,
157974
157900
  hasExistingRegistration,
157975
- isSoldOutWithoutWaitlist,
157976
157901
  ticketTypeSelectionBlocked
157977
157902
  });
157978
157903
  return /* @__PURE__ */ jsxs("div", {
@@ -158003,8 +157928,12 @@ function EnterDetailsActions(props) {
158003
157928
  const { wizard } = props;
158004
157929
  const hasWaitlistClaim = wizard.waitlistClaim.claim !== null;
158005
157930
  const isCheckingEligibility = wizard.eligibilityLoading;
158006
- const eligibilityUnavailable = !hasWaitlistClaim && (Boolean(wizard.eligibilityError) || !wizard.eligibility || wizard.eligibility.availability.kind === "unavailable" || !wizard.eligibility.eligible);
158007
- const isSoldOut = !hasWaitlistClaim && wizard.eligibility?.isFull === true && wizard.eligibility.canJoinWaitlist !== true;
157931
+ const eligibilityUnavailable = Boolean(resolveRegistrationAvailabilityBlocker({
157932
+ hasWaitlistClaim,
157933
+ eligibility: wizard.eligibility,
157934
+ eligibilityError: wizard.eligibilityError
157935
+ }));
157936
+ const isSoldOut = !hasWaitlistClaim && wizard.portalAuthState === "authenticated" && wizard.eligibility?.registration.kind !== "pending_payment" && isSelectionSoldOut(wizard.eligibility?.availability);
158008
157937
  const isContinueDisabled = isCheckingEligibility || eligibilityUnavailable || isSoldOut;
158009
157938
  const continueLabel = isCheckingEligibility ? "Checking availability..." : wizard.eligibilityError ? "Availability unavailable" : eligibilityUnavailable ? "Registration unavailable" : resolveDetailsButtonText({
158010
157939
  wizard,
@@ -158055,6 +157984,7 @@ function EventRegistrationWizardActions(props) {
158055
157984
  case "redirecting":
158056
157985
  case "verifying-payment":
158057
157986
  case "verifying-timeout":
157987
+ case "payment-status":
158058
157988
  case "payment-failed": return null;
158059
157989
  case "select-event": return null;
158060
157990
  case "select-tickets": return /* @__PURE__ */ jsx(SelectTicketsActions, { ...props });
@@ -158066,7 +157996,8 @@ function EventRegistrationWizardActions(props) {
158066
157996
  var init_EventRegistrationWizardActions = __esmMin((() => {
158067
157997
  init_registrationStateMachine();
158068
157998
  init_spinner();
158069
- init_domain();
157999
+ init_registrationCompletion();
158000
+ init_registrationErrorRecovery();
158070
158001
  }));
158071
158002
  //#endregion
158072
158003
  //#region ../blocks/src/system/runtime/nodes/event-registration/siteCreditPreview.ts
@@ -158147,7 +158078,7 @@ var init_siteCreditPreview = __esmMin((() => {
158147
158078
  function resolvePaymentStepStatus(input) {
158148
158079
  if (input.loading) return "loading";
158149
158080
  if (input.error || !input.eligibility) return "error";
158150
- if (input.eligibility.registration.kind !== "none" || !input.eligibility.eligible && !input.eligibility.isFree) return "not-eligible";
158081
+ if (input.eligibility.registration.kind === "waitlisted" || input.eligibility.paymentOptions.length === 0) return "not-eligible";
158151
158082
  return "ready";
158152
158083
  }
158153
158084
  function shouldPromptForLogin(status, isAuthenticated, eligibility) {
@@ -158182,7 +158113,7 @@ function UnavailableEntitlementMessage(props) {
158182
158113
  ] });
158183
158114
  }
158184
158115
  function IneligiblePaymentPanel(props) {
158185
- if (props.eligibility.isFull && !props.eligibility.canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
158116
+ if (isSelectionSoldOut(props.eligibility.availability)) return /* @__PURE__ */ jsxs("div", {
158186
158117
  className: "rb-reg-stack er-stack",
158187
158118
  children: [/* @__PURE__ */ jsx("h3", {
158188
158119
  className: "er-title",
@@ -158251,26 +158182,23 @@ function PaymentBlockingPanel(props) {
158251
158182
  })
158252
158183
  });
158253
158184
  if (!props.eligibility) return /* @__PURE__ */ jsx(MissingEligibilityPanel, {});
158254
- if (props.eligibility.registration.kind !== "none") {
158255
- const isBooked = props.eligibility.registration.kind === "booked";
158256
- return /* @__PURE__ */ jsxs("div", {
158257
- className: "rb-reg-stack er-stack",
158258
- children: [/* @__PURE__ */ jsx("h3", {
158259
- className: "er-title",
158260
- children: isBooked ? "Already booked" : "Already on the waitlist"
158261
- }), /* @__PURE__ */ jsxs("div", {
158262
- className: "er-center",
158263
- children: [/* @__PURE__ */ jsx("p", {
158264
- className: "er-text er-text--muted",
158265
- 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."
158266
- }), /* @__PURE__ */ jsx("a", {
158267
- href: "/portal",
158268
- className: "er-retry-btn",
158269
- children: "View my bookings"
158270
- })]
158185
+ if (props.eligibility.registration.kind === "waitlisted") return /* @__PURE__ */ jsxs("div", {
158186
+ className: "rb-reg-stack er-stack",
158187
+ children: [/* @__PURE__ */ jsx("h3", {
158188
+ className: "er-title",
158189
+ children: "Already on the waitlist"
158190
+ }), /* @__PURE__ */ jsxs("div", {
158191
+ className: "er-center",
158192
+ children: [/* @__PURE__ */ jsx("p", {
158193
+ className: "er-text er-text--muted",
158194
+ children: "You're already on the waitlist for this event."
158195
+ }), /* @__PURE__ */ jsx("a", {
158196
+ href: "/portal",
158197
+ className: "er-retry-btn",
158198
+ children: "View my bookings"
158271
158199
  })]
158272
- });
158273
- }
158200
+ })]
158201
+ });
158274
158202
  if (props.eligibility.isFree) return /* @__PURE__ */ jsxs("div", {
158275
158203
  className: "rb-reg-stack er-stack",
158276
158204
  children: [/* @__PURE__ */ jsx("h3", {
@@ -158291,7 +158219,7 @@ function PaymentBlockingPanel(props) {
158291
158219
  })]
158292
158220
  })]
158293
158221
  });
158294
- return props.eligibility.eligible ? null : /* @__PURE__ */ jsx(IneligiblePaymentPanel, {
158222
+ return props.eligibility.paymentOptions.length > 0 ? null : /* @__PURE__ */ jsx(IneligiblePaymentPanel, {
158295
158223
  eligibility: props.eligibility,
158296
158224
  email: props.email,
158297
158225
  isAuthenticated: props.isAuthenticated,
@@ -158301,6 +158229,7 @@ function PaymentBlockingPanel(props) {
158301
158229
  var init_PaymentBlockingPanel = __esmMin((() => {
158302
158230
  init_buttons();
158303
158231
  init_spinner();
158232
+ init_registrationCompletion();
158304
158233
  }));
158305
158234
  //#endregion
158306
158235
  //#region ../blocks/src/system/runtime/nodes/event-registration/types.ts
@@ -158430,7 +158359,7 @@ function SlidingScaleAmountField(props) {
158430
158359
  }
158431
158360
  function TicketTypeQuantityRows(props) {
158432
158361
  const totalSelectedQuantity = getTicketSelectionTotal(props.ticketSelections);
158433
- const effectiveMaxTickets = props.availableSpots == null ? props.maxTickets : Math.min(props.maxTickets, props.availableSpots);
158362
+ const effectiveMaxTickets = props.maxTickets;
158434
158363
  return /* @__PURE__ */ jsxs("div", {
158435
158364
  className: "er-ticket-lines",
158436
158365
  children: [
@@ -158440,16 +158369,14 @@ function TicketTypeQuantityRows(props) {
158440
158369
  "aria-label": props.bookingUnit === "place" ? "Places" : "Tickets",
158441
158370
  children: props.ticketTypes.map((ticketType) => {
158442
158371
  const quantity = getTicketLineQuantity(props.ticketSelections, ticketType.pricingOptionId);
158443
- const disabled = ticketType.availability.kind === "unavailable";
158372
+ const disabled = !canRequestTicketOption(ticketType.availability);
158444
158373
  const availabilityLabel = getTicketTypeAvailabilityLabel(ticketType);
158445
158374
  const ticketTypeRemainingLabel = formatTicketTypeRemaining(ticketType.availability.remainingPlaces);
158446
158375
  const priceLabel = ticketType.priceAmount > 0 ? formatPrice(ticketType.priceAmount, props.currency) : "Free";
158447
158376
  const maxAllowed = disabled ? 0 : getTicketTypeLineMax({
158448
158377
  currentQuantity: quantity,
158449
158378
  totalSelectedQuantity,
158450
- maxTickets: props.maxTickets,
158451
- availableSpots: props.availableSpots,
158452
- ticketTypeRemainingCapacity: ticketType.availability.remainingPlaces
158379
+ maxTickets: props.maxTickets
158453
158380
  });
158454
158381
  return /* @__PURE__ */ jsxs("div", {
158455
158382
  className: `er-ticket-line${disabled ? " er-ticket-line--disabled" : ""}`,
@@ -158554,33 +158481,13 @@ function AttendanceModeTiles(props) {
158554
158481
  })
158555
158482
  });
158556
158483
  }
158557
- function getMaxAllowedTicketCount(input) {
158558
- if (input.canJoinWaitlist) return input.maxTickets;
158559
- if (!input.usesTicketTypes) return Math.min(input.maxTickets, input.availableSpots ?? input.maxTickets);
158560
- if (!input.hasSelectedTicketType) return 1;
158561
- return Math.max(1, Math.min(input.maxTickets, input.selectedTicketTypeRemainingCapacity ?? input.maxTickets, input.availableSpots ?? input.maxTickets));
158562
- }
158563
158484
  function resolveTicketSelectionPricing(event) {
158564
158485
  return {
158565
158486
  mode: event ? publicEventPricingStrategy(event.pricing) : void 0,
158566
158487
  currency: event ? publicEventPricingCurrency(event.pricing) : null
158567
158488
  };
158568
158489
  }
158569
- function CheckoutRecoveryEntry(props) {
158570
- return props.onContinue ? /* @__PURE__ */ jsx("button", {
158571
- type: "button",
158572
- className: "er-back-btn",
158573
- onClick: props.onContinue,
158574
- children: "Continue an existing booking"
158575
- }) : null;
158576
- }
158577
- function getTicketSelectionCapacity(event, attendanceMode, checkoutRecovery) {
158578
- if (checkoutRecovery) return {
158579
- availableSpots: null,
158580
- isSoldOut: false,
158581
- canJoinWaitlist: false,
158582
- eventAvailabilityLabel: null
158583
- };
158490
+ function getTicketSelectionCapacity(event, attendanceMode) {
158584
158491
  const source = event ? selectEventCapacitySource(event, attendanceMode) : null;
158585
158492
  const availability = source ? getEventAvailability(source) : null;
158586
158493
  const canJoinWaitlist = source ? canJoinEventWaitlist(source) : false;
@@ -158597,29 +158504,21 @@ var init_TicketSelectionStep = __esmMin((() => {
158597
158504
  init_domain();
158598
158505
  init_utils();
158599
158506
  init_ticketSelectionLines();
158600
- 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 }) => {
158507
+ TicketSelectionStep = ({ event, occurrenceContext: _occurrenceContext, selectedAttendanceMode = null, onAttendanceModeChange, ticketsCount, maxTickets, visibleTicketTypes: visibleTicketTypesOverride, ticketSelections = [], onTicketSelectionsChange, slidingScale = null, selectedSlidingAmountInput = "", slidingScaleSelectionMessage = null, onSlidingAmountChange, onTicketsChange, bookingUnit = { kind: "ticket" } }) => {
158601
158508
  const unit = bookingUnit.kind;
158602
158509
  const deliveryMode = event?.deliveryMode ?? "in_person";
158603
158510
  const attendanceModes = event?.attendanceModes ?? [];
158604
- const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode, checkoutRecovery);
158511
+ const { availableSpots, isSoldOut, canJoinWaitlist, eventAvailabilityLabel } = getTicketSelectionCapacity(event, selectedAttendanceMode);
158605
158512
  const { mode: eventPricingMode, currency: eventPricingCurrency } = resolveTicketSelectionPricing(event);
158606
- const usesTicketTypes = eventPricingMode === "tiered" && !canJoinWaitlist;
158513
+ const usesTicketTypes = eventPricingMode === "tiered";
158607
158514
  const visibleTicketTypes = usesTicketTypes ? visibleTicketTypesOverride ?? getVisibleTicketTypes({
158608
158515
  event,
158609
158516
  eligibility: null,
158610
158517
  selectedAttendanceMode
158611
158518
  }) : [];
158612
- const implicitTicketType = usesTicketTypes ? getImplicitSingleAvailableTicketType(visibleTicketTypes) : null;
158613
158519
  const noVisibleTicketTypes = usesTicketTypes && visibleTicketTypes.length === 0;
158614
- const hasAvailableTicketTypes = usesTicketTypes && visibleTicketTypes.some((ticketType) => ticketType.availability.kind === "available");
158615
- const maxAllowed = getMaxAllowedTicketCount({
158616
- canJoinWaitlist,
158617
- usesTicketTypes,
158618
- maxTickets,
158619
- availableSpots,
158620
- selectedTicketTypeRemainingCapacity: implicitTicketType?.availability.remainingPlaces ?? null,
158621
- hasSelectedTicketType: implicitTicketType !== null
158622
- });
158520
+ const hasAvailableTicketTypes = usesTicketTypes && visibleTicketTypes.some((ticketType) => canRequestTicketOption(ticketType.availability));
158521
+ const maxAllowed = maxTickets;
158623
158522
  if (deliveryMode === "hybrid" && !selectedAttendanceMode) return /* @__PURE__ */ jsxs("div", {
158624
158523
  className: "rb-reg-stack er-stack",
158625
158524
  children: [
@@ -158638,20 +158537,6 @@ var init_TicketSelectionStep = __esmMin((() => {
158638
158537
  })
158639
158538
  ]
158640
158539
  });
158641
- if (isSoldOut && !canJoinWaitlist) return /* @__PURE__ */ jsxs("div", {
158642
- className: "rb-reg-stack er-stack",
158643
- children: [
158644
- /* @__PURE__ */ jsx("h3", {
158645
- className: "er-title",
158646
- children: "Sold out"
158647
- }),
158648
- /* @__PURE__ */ jsx("p", {
158649
- className: "er-text er-text--muted",
158650
- children: "Sorry you missed out! This event is fully booked."
158651
- }),
158652
- /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })
158653
- ]
158654
- });
158655
158540
  if (!eventPricingCurrency) return /* @__PURE__ */ jsx("div", {
158656
158541
  className: "rb-reg-stack er-stack",
158657
158542
  children: /* @__PURE__ */ jsx("p", {
@@ -158718,14 +158603,14 @@ var init_TicketSelectionStep = __esmMin((() => {
158718
158603
  })]
158719
158604
  })
158720
158605
  ] }),
158721
- canJoinWaitlist && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
158606
+ isSoldOut && !canJoinWaitlist && /* @__PURE__ */ jsx("p", {
158722
158607
  className: "er-text er-text--muted",
158723
- children: "This event is currently full. Continue to join the waitlist if a place opens up."
158724
- }), /* @__PURE__ */ jsx(CheckoutRecoveryEntry, { onContinue: onCheckoutRecovery })] }),
158725
- checkoutRecovery && /* @__PURE__ */ jsx("p", {
158608
+ children: "This event is fully booked."
158609
+ }),
158610
+ canJoinWaitlist && /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsx("p", {
158726
158611
  className: "er-text er-text--muted",
158727
- children: "Enter the details from your earlier booking. We’ll check your checkout before continuing to payment."
158728
- })
158612
+ children: "This event is currently full. Continue to join the waitlist if a place opens up."
158613
+ }) })
158729
158614
  ]
158730
158615
  });
158731
158616
  };
@@ -159313,7 +159198,7 @@ var init_PaymentSelectionStep = __esmMin((() => {
159313
159198
  const occurrenceId = occurrenceContext?.id ?? (event?.registrationSubject.kind === "occurrence" ? event.registrationSubject.occurrenceId : "");
159314
159199
  const selectedMethod = selectedSelection.method;
159315
159200
  const totalPrice = directPaymentTotalCents;
159316
- const canShowDirectPaymentOptions = Boolean(eligibility?.eligible && eligibility.canPayDirectly && eligibility.price);
159201
+ const canShowDirectPaymentOptions = Boolean(eligibility?.requiresPayment && eligibility.price);
159317
159202
  const directPaymentOptions = eligibility && canShowDirectPaymentOptions ? buildEventRegistrationPaymentOptionsViewModel({
159318
159203
  eventTitle: event?.title ?? "Event",
159319
159204
  approvedPaymentOptions: eligibility.paymentOptions,
@@ -159376,7 +159261,7 @@ var init_PaymentSelectionStep = __esmMin((() => {
159376
159261
  onRequestLogin
159377
159262
  });
159378
159263
  if (eligibilityLoading || eligibilityError || !eligibility) return blockingPanel;
159379
- if (eligibility.isFree || !eligibility.eligible) return blockingPanel;
159264
+ if (eligibility.isFree || paymentStepStatus !== "ready") return blockingPanel;
159380
159265
  const isMultiTicket = areEntitlementsDisabledForTicketCount(ticketsCount);
159381
159266
  return /* @__PURE__ */ jsxs("div", {
159382
159267
  className: "rb-reg-stack er-stack",
@@ -159595,7 +159480,7 @@ var init_VerifyingTimeoutStep = __esmMin((() => {
159595
159480
  title,
159596
159481
  body: /* @__PURE__ */ jsx("p", {
159597
159482
  className: "er-text--muted er-message",
159598
- children: message
159483
+ 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."
159599
159484
  }),
159600
159485
  actionsClassName: "er-button-group",
159601
159486
  actions: onCheckAgain ? /* @__PURE__ */ jsx("button", {
@@ -159603,11 +159488,7 @@ var init_VerifyingTimeoutStep = __esmMin((() => {
159603
159488
  onClick: onCheckAgain,
159604
159489
  className: "er-btn er-btn--primary",
159605
159490
  children: "Check payment status"
159606
- }) : /* @__PURE__ */ jsx("a", {
159607
- href: "/portal",
159608
- className: "er-btn er-btn--primary",
159609
- children: "Check payment status"
159610
- }),
159491
+ }) : void 0,
159611
159492
  secondaryBody: supportEmail ? /* @__PURE__ */ jsxs("p", {
159612
159493
  className: "er-text--sm er-text--muted er-message",
159613
159494
  children: [
@@ -159797,6 +159678,7 @@ function EventRegistrationWizardContent(props) {
159797
159678
  case "redirecting":
159798
159679
  case "verifying-payment":
159799
159680
  case "verifying-timeout":
159681
+ case "payment-status":
159800
159682
  case "payment-failed": return null;
159801
159683
  case "select-event": return /* @__PURE__ */ jsx(EventSelectionStep, {
159802
159684
  events: wizard.scopedEvents,
@@ -159812,8 +159694,6 @@ function EventRegistrationWizardContent(props) {
159812
159694
  onBookForSomeoneElse: wizard.handleBookForSomeoneElse
159813
159695
  }), /* @__PURE__ */ jsx(TicketSelectionStep, {
159814
159696
  event: wizard.selectedEvent,
159815
- checkoutRecovery: wizard.checkoutRecovery,
159816
- onCheckoutRecovery: canRecoverEventCheckout(wizard.selectedEvent) ? wizard.startCheckoutRecovery : void 0,
159817
159697
  occurrenceContext: wizard.occurrenceContext,
159818
159698
  selectedAttendanceMode: wizard.selectedAttendanceMode,
159819
159699
  onAttendanceModeChange: wizard.setSelectedAttendanceMode,
@@ -159841,13 +159721,90 @@ var init_EventRegistrationWizardContent = __esmMin((() => {
159841
159721
  init_client();
159842
159722
  init_src();
159843
159723
  init_shared();
159844
- init_checkoutRecovery();
159845
159724
  init_registrationStateMachine();
159846
159725
  init_siteCreditPreview();
159847
159726
  init_PaymentBlockingPanel();
159848
159727
  init_event_registration();
159849
159728
  }));
159850
159729
  //#endregion
159730
+ //#region ../blocks/src/system/runtime/nodes/event-registration/PaymentStatusStep.tsx
159731
+ function presentation(state) {
159732
+ switch (state.kind) {
159733
+ case "ready": return {
159734
+ title: "We haven’t confirmed your payment yet",
159735
+ 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.",
159736
+ action: { label: "Check payment status" }
159737
+ };
159738
+ case "checking": return {
159739
+ title: "We haven’t confirmed your payment yet",
159740
+ 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.",
159741
+ action: {
159742
+ label: "Checking payment…",
159743
+ disabled: true
159744
+ }
159745
+ };
159746
+ case "processing": return {
159747
+ title: "Your payment is still being processed",
159748
+ message: "Please don’t make another payment. You can check its status again in a moment.",
159749
+ action: { label: "Check payment status" }
159750
+ };
159751
+ case "paymentAvailable": return {
159752
+ title: "Your payment hasn’t been completed",
159753
+ message: "Your booking details are still saved. Continue to payment to finish your booking.",
159754
+ action: { label: "Continue to payment" }
159755
+ };
159756
+ case "retryAvailable": return {
159757
+ title: "Continue your booking",
159758
+ message: "You can return to payment. We’ll check your booking, any existing payment and availability before starting another checkout.",
159759
+ action: { label: "Return to payment" }
159760
+ };
159761
+ case "temporarilyUnavailable": return {
159762
+ title: "We couldn’t check your payment",
159763
+ message: "Please don’t make another payment yet. Try checking again in a moment.",
159764
+ action: { label: "Check payment status" }
159765
+ };
159766
+ case "assistanceRequired": return {
159767
+ title: "We still can’t confirm your payment",
159768
+ message: "Please don’t make another payment. Contact the organiser so they can check your booking.",
159769
+ action: { label: "Return to booking" }
159770
+ };
159771
+ }
159772
+ }
159773
+ function PaymentStatusStep(props) {
159774
+ const view = presentation(props.state);
159775
+ const onClick = props.state.kind === "paymentAvailable" ? props.onContinuePayment : props.state.kind === "retryAvailable" ? props.onReturnToPayment : props.state.kind === "assistanceRequired" ? props.onReturnToBooking : props.onCheck;
159776
+ return /* @__PURE__ */ jsx(TerminalPanel, {
159777
+ tone: "warning",
159778
+ className: "er-center",
159779
+ titleClassName: "er-title--lg er-message",
159780
+ icon: /* @__PURE__ */ jsx(StateIcon, {
159781
+ variant: "warning",
159782
+ children: /* @__PURE__ */ jsx(ClockIcon, {})
159783
+ }),
159784
+ title: view.title,
159785
+ body: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("p", {
159786
+ className: "er-text--muted er-message",
159787
+ children: view.message
159788
+ }), /* @__PURE__ */ jsx("span", {
159789
+ className: "rb-sr-only",
159790
+ "aria-live": "polite",
159791
+ "aria-atomic": "true",
159792
+ children: props.state.kind === "checking" ? "Checking payment…" : view.title
159793
+ })] }),
159794
+ actionsClassName: "er-button-group",
159795
+ actions: view.action ? /* @__PURE__ */ jsx("button", {
159796
+ type: "button",
159797
+ onClick,
159798
+ disabled: view.action.disabled,
159799
+ className: "er-btn er-btn--primary",
159800
+ children: /* @__PURE__ */ jsx("span", { children: view.action.label })
159801
+ }) : void 0
159802
+ });
159803
+ }
159804
+ var init_PaymentStatusStep = __esmMin((() => {
159805
+ init_shared();
159806
+ }));
159807
+ //#endregion
159851
159808
  //#region ../blocks/src/system/runtime/nodes/event-registration/EventRegistrationSurface.tsx
159852
159809
  function EventPortalAuthPrompt(props) {
159853
159810
  return /* @__PURE__ */ jsxs("div", {
@@ -159932,6 +159889,13 @@ function EventRegistrationTerminalState(props) {
159932
159889
  message: wizard.verification.status === "timeout" ? void 0 : wizard.errorMessage,
159933
159890
  supportEmail: props.supportEmail
159934
159891
  });
159892
+ case "payment-status": return wizard.paymentStatusRecovery ? /* @__PURE__ */ jsx(PaymentStatusStep, {
159893
+ state: wizard.paymentStatusRecovery,
159894
+ onCheck: wizard.handleCheckPaymentStatus,
159895
+ onContinuePayment: wizard.handleContinueExistingPayment,
159896
+ onReturnToPayment: wizard.handleReturnToPayment,
159897
+ onReturnToBooking: wizard.handleReturnToBooking
159898
+ }) : null;
159935
159899
  case "success": return wizard.registrationResult ? /* @__PURE__ */ jsx(SuccessStep, {
159936
159900
  title: wizard.registrationResult.title,
159937
159901
  variant: wizard.registrationResult.variant,
@@ -159940,7 +159904,7 @@ function EventRegistrationTerminalState(props) {
159940
159904
  case "error": return /* @__PURE__ */ jsx(ErrorStep, {
159941
159905
  message: wizard.errorMessage,
159942
159906
  action: wizard.errorAction,
159943
- canJoinWaitlist: wizard.eligibility?.isFull && wizard.eligibility.canJoinWaitlist,
159907
+ canJoinWaitlist: wizard.eligibility?.availability.kind === "waitlist" && wizard.eligibility.registration.kind !== "pending_payment",
159944
159908
  onRetry: wizard.handleRetry
159945
159909
  });
159946
159910
  case "select-event":
@@ -160002,6 +159966,7 @@ var init_EventRegistrationSurface = __esmMin((() => {
160002
159966
  init_EventRegistrationWizardActions();
160003
159967
  init_EventRegistrationWizardContent();
160004
159968
  init_PaymentFailedStep();
159969
+ init_PaymentStatusStep();
160005
159970
  init_StepIndicator();
160006
159971
  init_SuccessStep();
160007
159972
  init_VerifyingPaymentStep();
@@ -160139,6 +160104,7 @@ function getWizardStepLabel(input) {
160139
160104
  case "redirecting":
160140
160105
  case "verifying-payment":
160141
160106
  case "verifying-timeout":
160107
+ case "payment-status":
160142
160108
  case "payment-failed": return "";
160143
160109
  }
160144
160110
  }
@@ -165922,7 +165888,7 @@ var SimpleCache = class {
165922
165888
  * 1. This constant
165923
165889
  * 2. The "version" field in package.json
165924
165890
  */
165925
- const SDK_VERSION = "0.141.0";
165891
+ const SDK_VERSION = "0.143.0";
165926
165892
  //#endregion
165927
165893
  //#region src/client/error.ts
165928
165894
  let _Symbol$for;