@riverbankcms/sdk 0.135.1 → 0.137.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 (220) hide show
  1. package/CHANGELOG.md +114 -0
  2. package/README.md +4 -8
  3. package/dist/{PreviewEditorSidebar-D4p_5TdY.mjs → PreviewEditorSidebar-Bn6cONPa.mjs} +8 -8
  4. package/dist/{PreviewEditorUI-D0cRoTX1.mjs → PreviewEditorUI-LAwXZPSx.mjs} +3 -3
  5. package/dist/{PreviewQueryProvider-DcgaESkm.mjs → PreviewQueryProvider-ztQUdsNo.mjs} +1 -1
  6. package/dist/{SdkPreviewModeRuntime-BKLtM3Nz.mjs → SdkPreviewModeRuntime-BbbGsI_v.mjs} +621 -238
  7. package/dist/{SiteChromeCustomizeContext-61X2m7QV.mjs → SiteChromeCustomizeContext-BbkNSt5a.mjs} +5041 -2407
  8. package/dist/_dts/ai/src/contracts/proposals.d.ts +18 -850
  9. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +412 -2316
  10. package/dist/_dts/ai/src/designer/themePatch.d.ts +5 -10
  11. package/dist/_dts/api/src/accessAdmin.d.ts +1 -9
  12. package/dist/_dts/api/src/accountApi.d.ts +49 -2
  13. package/dist/_dts/api/src/contentRuntime.d.ts +7 -4
  14. package/dist/_dts/api/src/domainConnection.d.ts +41 -0
  15. package/dist/_dts/api/src/endpoints.d.ts +201 -181
  16. package/dist/_dts/api/src/index.d.ts +5 -3
  17. package/dist/_dts/api/src/media.d.ts +19 -2
  18. package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +7 -0
  19. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +26 -0
  20. package/dist/_dts/api/src/sdkBlockContentAdmission.d.ts +5 -0
  21. package/dist/_dts/api/src/sdkContracts.d.ts +2 -15
  22. package/dist/_dts/api/src/sdkMediaContracts.d.ts +40 -0
  23. package/dist/_dts/api/src/sdkMediaEndpointDefinitions.d.ts +61 -0
  24. package/dist/_dts/api/src/sdkThemeWire.d.ts +21 -436
  25. package/dist/_dts/api/src/siteInfrastructure.d.ts +17 -23
  26. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +7 -21
  27. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +27 -3
  28. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +37 -17
  29. package/dist/_dts/api/src/types.d.ts +1 -1
  30. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +2 -3
  31. package/dist/_dts/block-form/src/utils/slug.d.ts +6 -0
  32. package/dist/_dts/blocks/src/PageRenderer.d.ts +13 -7
  33. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +48 -0
  34. package/dist/_dts/blocks/src/definitions.d.ts +14 -0
  35. package/dist/_dts/blocks/src/index.d.ts +4 -3
  36. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +49 -0
  37. package/dist/_dts/blocks/src/pageRendererBlockSupport.d.ts +75 -0
  38. package/dist/_dts/blocks/src/pageRendererBoundaries.d.ts +2 -0
  39. package/dist/_dts/blocks/src/server.d.ts +2 -2
  40. package/dist/_dts/blocks/src/system/blocks/event-registration.d.ts +1 -1
  41. package/dist/_dts/blocks/src/system/data/index.d.ts +2 -0
  42. package/dist/_dts/blocks/src/system/data/publicLoaderCachePolicy.d.ts +78 -0
  43. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +2 -18
  44. package/dist/_dts/blocks/src/system/manifest/validation.d.ts +103 -16
  45. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
  46. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +4 -2
  47. package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +8 -0
  48. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  49. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +19 -0
  50. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +52 -0
  51. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -0
  52. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +47 -21
  53. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +38 -9
  54. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/ErrorStep.d.ts +3 -5
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/VerifyingTimeoutStep.d.ts +3 -1
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -0
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +1 -1
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +2 -0
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorPresentation.d.ts +5 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.d.ts +25 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.d.ts +4 -0
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +8 -3
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +2 -0
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +5 -2
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useWaitlistClaimRestoration.d.ts +2 -0
  66. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.client.d.ts +2 -2
  67. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +40 -0
  68. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +2 -0
  69. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +43 -0
  70. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/capacity.d.ts +164 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/cta.d.ts +29 -0
  72. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/dates.d.ts +47 -0
  73. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/index.d.ts +14 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/people.d.ts +6 -0
  75. package/dist/_dts/blocks/src/system/runtime/nodes/events/domain/pricing.d.ts +31 -0
  76. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/CalendarDayCell.d.ts +3 -1
  77. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/CalendarNavigationChevron.d.ts +4 -0
  78. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/DayEventsModal.d.ts +2 -1
  79. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventModalContext.d.ts +3 -2
  80. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/OfferingTitle.d.ts +11 -0
  81. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekAgendaView.d.ts +4 -1
  82. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +31 -3
  83. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekTimetableView.d.ts +3 -1
  84. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +9 -1
  85. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/index.d.ts +3 -1
  86. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/listingLayout.d.ts +23 -0
  87. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/timetableModel.d.ts +4 -3
  88. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +0 -1
  89. package/dist/_dts/calendar/src/grid.d.ts +24 -66
  90. package/dist/_dts/calendar/src/index.d.ts +2 -2
  91. package/dist/_dts/calendar/src/timetable.d.ts +5 -9
  92. package/dist/_dts/commerce/src/purchase/allocation.d.ts +11 -0
  93. package/dist/_dts/commerce/src/purchase/event-registration-errors.d.ts +57 -0
  94. package/dist/_dts/commerce/src/purchase/index.d.ts +3 -0
  95. package/dist/_dts/commerce/src/purchase/settlement.d.ts +33 -0
  96. package/dist/_dts/commerce/src/purchase/stripeCheckoutReturnUrl.d.ts +8 -0
  97. package/dist/_dts/content-model/src/templates/defaults.d.ts +6 -0
  98. package/dist/_dts/core/src/slug.d.ts +20 -5
  99. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +8 -40
  100. package/dist/_dts/db/src/index.d.ts +1 -0
  101. package/dist/_dts/db/src/utils/postgrestFilter.d.ts +2 -0
  102. package/dist/_dts/media-core/src/bulkDeletePlanning.d.ts +4 -0
  103. package/dist/_dts/media-core/src/fileDomain.d.ts +3 -0
  104. package/dist/_dts/preview-next/src/client/blocks/EditablePageRenderer.d.ts +1 -1
  105. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +1 -0
  106. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +1 -0
  107. package/dist/_dts/preview-next/src/client/preview/SiteChromeCustomizeContext.d.ts +3 -2
  108. package/dist/_dts/preview-next/src/client/preview/headerInteractionPaletteSurfaceState.d.ts +2 -1
  109. package/dist/_dts/preview-next/src/client/preview/siteChromeBrandPreferences.d.ts +1 -1
  110. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlHistoryState.d.ts +2 -0
  111. package/dist/_dts/preview-next/src/client/preview/siteChromeQuickControlSaveRequest.d.ts +51 -0
  112. package/dist/_dts/preview-next/src/client/preview/siteChromeSavePlan.d.ts +24 -2
  113. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +23 -1
  114. package/dist/_dts/preview-next/src/client/preview/usePersistedHeaderPreferences.d.ts +8 -0
  115. package/dist/_dts/sdk/src/client/publicLoaderCacheAccess.d.ts +6 -0
  116. package/dist/_dts/sdk/src/public-api/contracts.d.ts +7 -2
  117. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +10 -6
  118. package/dist/_dts/sdk/src/rendering/components/Block.shared.d.ts +0 -1
  119. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +4 -4
  120. package/dist/_dts/sdk/src/rendering/helpers/footerPageOutline.d.ts +3 -0
  121. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +3 -0
  122. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +1 -1
  123. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +17 -0
  124. package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +9 -3
  125. package/dist/_dts/sdk/src/rendering/hooks/usePage.d.ts +1 -1
  126. package/dist/_dts/sdk/src/rendering/index.d.ts +2 -2
  127. package/dist/_dts/sdk/src/rendering/overrideResolution.d.ts +7 -4
  128. package/dist/_dts/sdk/src/version.d.ts +1 -1
  129. package/dist/_dts/theme-core/src/cards/types.d.ts +8 -8
  130. package/dist/_dts/theme-core/src/data.d.ts +12 -0
  131. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  132. package/dist/_dts/theme-core/src/gradients/types.d.ts +5 -0
  133. package/dist/_dts/theme-core/src/header/interactionPalette.d.ts +25 -2
  134. package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +2 -6
  135. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +9 -810
  136. package/dist/_dts/theme-core/src/schema.d.ts +460 -1285
  137. package/dist/_dts/theme-core/src/site-styles/compilationPlan.d.ts +43 -3
  138. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +223 -1
  139. package/dist/_dts/theme-core/src/site-styles/headerBrandPresentation.d.ts +63 -0
  140. package/dist/_dts/theme-core/src/site-styles/headerBytesComparison.d.ts +30 -0
  141. package/dist/_dts/theme-core/src/site-styles/headerInteractionPalette.d.ts +50 -1
  142. package/dist/_dts/theme-core/src/site-styles/headerLayoutCatalog.d.ts +48 -38
  143. package/dist/_dts/theme-core/src/site-styles/headerLayoutStyles.d.ts +10 -0
  144. package/dist/_dts/theme-core/src/site-styles/headerLayoutTypes.d.ts +8 -5
  145. package/dist/_dts/theme-core/src/site-styles/headerOpeningForeground.d.ts +4 -4
  146. package/dist/_dts/theme-core/src/site-styles/headerPreferences.d.ts +162 -0
  147. package/dist/_dts/theme-core/src/site-styles/headerPreferencesPersistence.d.ts +73 -0
  148. package/dist/_dts/theme-core/src/site-styles/headerRecompile.d.ts +118 -0
  149. package/dist/_dts/theme-core/src/site-styles/headerStyleCompiler.d.ts +25 -2
  150. package/dist/_dts/theme-core/src/site-styles/headerStyleDefaults.d.ts +465 -0
  151. package/dist/_dts/theme-core/src/site-styles/headerStyleRecipe.d.ts +168 -0
  152. package/dist/_dts/theme-core/src/site-styles/index.d.ts +5 -0
  153. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +1 -1
  154. package/dist/_dts/theme-core/src/site-styles/siteChromeBackgrounds.d.ts +20 -1
  155. package/dist/_dts/theme-core/src/site-styles/siteChromeNavPreferences.d.ts +43 -2
  156. package/dist/client/{BookingConsentAgreement-Bz9znbpn.mjs → BookingConsentAgreement--_fUCZe-.mjs} +2 -2
  157. package/dist/client/{DiscountCodeDisclosure-35Ru8yB9.mjs → DiscountCodeDisclosure-BMipSoDJ.mjs} +1 -1
  158. package/dist/client/{EventCombined.client-BKB0ZxRR.mjs → EventCombined.client-CwJOxn7A.mjs} +274 -278
  159. package/dist/client/{EventListing.client-Dx8I21ok.mjs → EventListing.client-eVwiylPW.mjs} +2 -2
  160. package/dist/client/{LeafletStaticMap-CEWx-Bhe.mjs → LeafletStaticMap-IKenna5u.mjs} +1 -1
  161. package/dist/client/{accordion-KIDsKTwS.mjs → accordion-MGAO3PuE.mjs} +1 -1
  162. package/dist/client/{bookingForm-D96Rmp-5.mjs → bookingForm-CudlQPUu.mjs} +5 -5
  163. package/dist/client/bookings.mjs +476 -98
  164. package/dist/client/capacity-BW00PO7s.mjs +271 -0
  165. package/dist/client/{carousel-YwUgyL66.mjs → carousel-BrbGJ2Jl.mjs} +1 -1
  166. package/dist/client/{cart-BbwuNrUT.mjs → cart-Bq5eU0xZ.mjs} +3 -3
  167. package/dist/client/{checkout-hp1ucmEY.mjs → checkout-BAFVRdrK.mjs} +3 -3
  168. package/dist/client/client.mjs +4641 -2721
  169. package/dist/client/{context-DljQn8L5.mjs → context-DCkiHVdD.mjs} +20 -5
  170. package/dist/client/dates-2RPXHQy4.mjs +264 -0
  171. package/dist/client/{eventCalendar-DU4iNLpo.mjs → eventCalendar-B0O-hPF7.mjs} +261 -126
  172. package/dist/client/{eventCombined-CZuupW8m.mjs → eventCombined-DCkDaoDI.mjs} +3 -3
  173. package/dist/client/{eventDetails-DPQWwCIi.mjs → eventDetails-D8GG2dnD.mjs} +7 -4
  174. package/dist/client/{eventListing-C7oMidwS.mjs → eventListing-3ssV_bxz.mjs} +3 -3
  175. package/dist/client/{eventRegistration-zEiunlUs.mjs → eventRegistration-bPQo3kVw.mjs} +610 -313
  176. package/dist/client/{form-D2KIyCVJ.mjs → form-qMv8RDkk.mjs} +2 -2
  177. package/dist/client/{headerSection-CK5uChUK.mjs → headerSection-CH0Sc5hX.mjs} +2 -2
  178. package/dist/client/hooks.mjs +2514 -308
  179. package/dist/client/{locationMap-DLQNH1ln.mjs → locationMap-0_xlBnNI.mjs} +2 -2
  180. package/dist/client/{newsletterForm-ZuhIG7fZ.mjs → newsletterForm-NUW7m9RI.mjs} +2 -2
  181. package/dist/client/{productDetail-7hIcGeae.mjs → productDetail-FBEOM7jW.mjs} +3 -3
  182. package/dist/client/{productList-T4Cii1ot.mjs → productList-R0OSGhnn.mjs} +3 -3
  183. package/dist/client/{propsDecoder-mB0aC_Fi.mjs → propsDecoder-pYvx_Srl.mjs} +179 -401
  184. package/dist/client/rendering/client.mjs +3496 -2223
  185. package/dist/client/rendering/islands.mjs +17 -17
  186. package/dist/client/rendering.mjs +4400 -2510
  187. package/dist/client/{scrollToBlock-Du5mHgvL.mjs → scrollToBlock-ByQv96M2.mjs} +1 -1
  188. package/dist/client/{shop-B5zAcKZn.mjs → shop-RUG9DmRE.mjs} +6 -6
  189. package/dist/client/{shop-commerce-BKBZB6l5.mjs → shop-commerce-B76Jz23B.mjs} +5 -5
  190. package/dist/client/{shop-commerce-store-Cq4qlNtQ.mjs → shop-commerce-store-QuQNdDsD.mjs} +1 -1
  191. package/dist/client/{shopShared-DYGzEs9D.mjs → shopShared-vXU1omwJ.mjs} +3 -3
  192. package/dist/client/{useEventFilters-Bphkda8m.mjs → useEventFilters-ByuU6HLA.mjs} +33 -18
  193. package/dist/preview-next/before-render.mjs +86 -51
  194. package/dist/preview-next/client/runtime.mjs +4 -4
  195. package/dist/preview-next/keepAlive.mjs +86 -51
  196. package/dist/preview-next/middleware.mjs +86 -51
  197. package/dist/{previewAuthStore-C7ksxt5b.mjs → previewAuthStore-L_cKW8Sb.mjs} +86 -51
  198. package/dist/{sdk-runtime-BbIC8G4J.mjs → sdk-runtime-sUMr5d70.mjs} +2 -2
  199. package/dist/{separator-CadhAtI7.mjs → separator-BIHkie5i.mjs} +1 -1
  200. package/dist/server/components.mjs +4397 -2960
  201. package/dist/server/config-validation.mjs +354 -145
  202. package/dist/server/config.mjs +354 -145
  203. package/dist/server/data.mjs +354 -144
  204. package/dist/server/index.mjs +201 -55
  205. package/dist/server/manifest.mjs +0 -1
  206. package/dist/server/next.mjs +4046 -2611
  207. package/dist/server/page-converter.mjs +225 -122
  208. package/dist/server/prebuild.mjs +1 -1
  209. package/dist/server/rendering/server.mjs +4105 -2636
  210. package/dist/server/rendering.mjs +4522 -3087
  211. package/dist/server/routing.mjs +3289 -1637
  212. package/dist/server/server.mjs +23175 -21079
  213. package/dist/server/theme-bridge.mjs +708 -272
  214. package/dist/server/theme.mjs +29 -25
  215. package/dist/styles/index.css +624 -181
  216. package/package.json +1 -1
  217. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCapacity.d.ts +0 -48
  218. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/pricing.d.ts +0 -17
  219. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +0 -100
  220. /package/dist/_dts/blocks/src/system/runtime/nodes/events/{shared → domain}/destination.d.ts +0 -0
@@ -2565,6 +2565,10 @@ const EVENTS = {
2565
2565
  registrationStatus: {
2566
2566
  path: "/public/sites/{siteId}/events/registration-status",
2567
2567
  method: "GET"
2568
+ },
2569
+ checkoutReturn: {
2570
+ path: "/public/sites/{siteId}/events/checkout-return",
2571
+ method: "POST"
2568
2572
  }
2569
2573
  };
2570
2574
  const WHOLE_SERIES = {
@@ -2834,10 +2838,11 @@ function encodePublicProductCategorySelector(selector) {
2834
2838
  * Error thrown when an API request fails
2835
2839
  */
2836
2840
  var BlockApiError = class extends Error {
2837
- constructor(message, status, code) {
2841
+ constructor(message, status, code, tag) {
2838
2842
  super(message);
2839
2843
  this.status = status;
2840
2844
  this.code = code;
2845
+ this.tag = tag;
2841
2846
  this.name = "BlockApiError";
2842
2847
  }
2843
2848
  };
@@ -2869,7 +2874,8 @@ function getBlockApiErrorDetails(data) {
2869
2874
  const nestedError = isRecord$7(data.error) ? data.error : void 0;
2870
2875
  return {
2871
2876
  message: typeof nestedError?.message === "string" ? nestedError.message : typeof data.message === "string" ? data.message : void 0,
2872
- code: typeof nestedError?.code === "string" ? nestedError.code : typeof data.code === "string" ? data.code : void 0
2877
+ code: typeof nestedError?.code === "string" ? nestedError.code : typeof data.code === "string" ? data.code : void 0,
2878
+ tag: typeof nestedError?.tag === "string" ? nestedError.tag : void 0
2873
2879
  };
2874
2880
  }
2875
2881
  function buildUnexpectedJsonResponseMessage(parseResult) {
@@ -2888,7 +2894,8 @@ async function extractErrorDetails(response) {
2888
2894
  const details = getBlockApiErrorDetails(parseResult.value);
2889
2895
  return {
2890
2896
  message: details.message ?? fallbackMessage,
2891
- code: details.code
2897
+ code: details.code,
2898
+ tag: details.tag
2892
2899
  };
2893
2900
  }
2894
2901
  case "invalid-json": return { message: `${fallbackMessage} (received invalid JSON)` };
@@ -2985,7 +2992,7 @@ function createBlockApi(config) {
2985
2992
  const response = await fetch(url, fetchOptions);
2986
2993
  if (!response.ok) {
2987
2994
  const details = await extractErrorDetails(response);
2988
- throw new BlockApiError(details.message, response.status, details.code);
2995
+ throw new BlockApiError(details.message, response.status, details.code, details.tag);
2989
2996
  }
2990
2997
  const json = await parseJsonApiResponse(response);
2991
2998
  if (isApiSuccessResponse(json)) return json.data;
@@ -3161,6 +3168,14 @@ function createBlockApi(config) {
3161
3168
  skipDedup: true
3162
3169
  });
3163
3170
  },
3171
+ async resolveEventCheckoutReturn(data) {
3172
+ const sid = requireSiteId();
3173
+ const path = buildPath(EVENTS.checkoutReturn.path, { siteId: sid });
3174
+ return request(EVENTS.checkoutReturn, {
3175
+ path,
3176
+ body: data
3177
+ });
3178
+ },
3164
3179
  async resolveWaitlistClaim(data) {
3165
3180
  const sid = requireSiteId();
3166
3181
  const path = buildPath(WHOLE_SERIES.waitlistClaimResolve.path, { siteId: sid });
@@ -3811,6 +3826,18 @@ function isRecord$6(value) {
3811
3826
  return typeof value === "object" && value !== null && !Array.isArray(value);
3812
3827
  }
3813
3828
  //#endregion
3829
+ //#region ../core/src/money-input.ts
3830
+ function unsafeAsNonNegativeCents(value) {
3831
+ return value;
3832
+ }
3833
+ /**
3834
+ * Normalizes a derived amount to non-negative whole cents. This intentionally
3835
+ * clamps negatives to zero; use parseNonNegativeCents for validation.
3836
+ */
3837
+ function toNonNegativeCents(value) {
3838
+ return unsafeAsNonNegativeCents(Math.max(0, Math.trunc(value)));
3839
+ }
3840
+ //#endregion
3814
3841
  //#region ../core/src/booking-flexible-balance.ts
3815
3842
  function clampFlexibleBalanceConfiguredAmount(amountCents, totalAmountCents) {
3816
3843
  return Math.max(0, Math.min(amountCents, totalAmountCents));
@@ -8771,6 +8798,11 @@ const gradientConfigSchema = z.object({
8771
8798
  position: z.string().optional(),
8772
8799
  stops: z.array(gradientStopSchema).min(2)
8773
8800
  });
8801
+ const gradientsSchema = z.object({
8802
+ button: z.string().min(1).nullable().optional(),
8803
+ hero: z.string().min(1).nullable().optional(),
8804
+ background: z.string().min(1).nullable().optional()
8805
+ });
8774
8806
  //#endregion
8775
8807
  //#region ../theme-core/src/interactive/baseSchema.ts
8776
8808
  /**
@@ -9383,12 +9415,8 @@ const legacyHeaderVariantValues = Object.keys(legacyHeaderVariants);
9383
9415
  * `@riverbankcms/api` is `z.input<typeof themeSchema>`, so a widened input here
9384
9416
  * would leak straight into a public type.
9385
9417
  *
9386
- * Not every read of a persisted theme goes through the schema:
9387
- * `resolveRuntimeTheme` in
9388
- * `apps/dashboard/src/server/services/sites/runtimeSiteResponse.ts` returns the
9389
- * raw database JSON asserted as `Theme` with no parse, so a theme still
9390
- * carrying a legacy spelling reaches the theme editor un-aliased. That gap
9391
- * predates this alias and is harmless while persisted usage is zero.
9418
+ * Persisted runtime themes are admitted through `parseThemeForPersistence`
9419
+ * before reaching consumers, so legacy spellings normalize at that boundary.
9392
9420
  */
9393
9421
  const headerVariantWithLegacyAliasSchema = z.enum([...headerVariantValues, ...legacyHeaderVariantValues]).transform((value) => value in legacyHeaderVariants ? legacyHeaderVariants[value] : value);
9394
9422
  const BREAKPOINT_LG = 1024;
@@ -9440,11 +9468,30 @@ const headerContainerSchema = z.object({
9440
9468
  tint: z.string().nullable().optional(),
9441
9469
  opacity: z.number().min(0).max(1).default(.12)
9442
9470
  }).optional();
9443
- const headerInteractionPaletteSchema = z.enum([
9471
+ //#endregion
9472
+ //#region ../theme-core/src/header/interactionPalette.ts
9473
+ /**
9474
+ * The palettes that fill the nav link with a colour on hover and focus. Each
9475
+ * one names a background/foreground token pair.
9476
+ */
9477
+ const headerInteractionPillPaletteValues = [
9444
9478
  "primary",
9445
9479
  "secondary",
9446
9480
  "accent"
9447
- ]);
9481
+ ];
9482
+ /**
9483
+ * "No pill": the nav link keeps whatever hover treatment its recipe compiled,
9484
+ * and the palette step writes nothing at all (#1318 Phase 4c decision 2).
9485
+ *
9486
+ * It exists because "a colour change on hover, no filled background" was not
9487
+ * expressible in the vocabulary, and it is what
9488
+ * `anna-raven-therapy-and-yoga` and `kirtan-lucy` have rendered since before
9489
+ * the palette existed. Without it those two rows can only be classified as a
9490
+ * conscious visual change.
9491
+ */
9492
+ const headerInteractionQuietPalette = "quiet";
9493
+ const headerInteractionPaletteValues = [...headerInteractionPillPaletteValues, headerInteractionQuietPalette];
9494
+ const headerInteractionPaletteSchema = z.enum(headerInteractionPaletteValues);
9448
9495
  //#endregion
9449
9496
  //#region ../theme-core/src/boxBackgroundSchema.ts
9450
9497
  const boxBackgroundOverlaySchema = z.preprocess(normalizeAuthoringOpacity, z.discriminatedUnion("type", [
@@ -9847,7 +9894,6 @@ const navFontWeight = z.enum([
9847
9894
  "bold"
9848
9895
  ]);
9849
9896
  const headerMaxWidth = z.enum(["container", "full"]);
9850
- const headerBarFrame = z.enum(["full-bleed", "inset-shell"]);
9851
9897
  const headerBorderSchema = componentBorderSchema.extend({ position: z.enum([
9852
9898
  "bottom",
9853
9899
  "top",
@@ -9876,12 +9922,6 @@ const headerLogoTextSchema = z.object({
9876
9922
  ]).optional(),
9877
9923
  hideOnShrink: z.boolean().optional()
9878
9924
  }).optional();
9879
- const navEffectsSchema = z.object({
9880
- underlineGradient: z.boolean().default(false),
9881
- glow: z.boolean().default(false),
9882
- glowColor: z.string().optional(),
9883
- neumorphic: z.boolean().default(false)
9884
- }).optional();
9885
9925
  const dropdownStyleSchema = z.object({
9886
9926
  background: themeColorTokenSchema.default("surface"),
9887
9927
  textColor: themeColorTokenSchema.default("text"),
@@ -9972,10 +10012,8 @@ const headerSchema = z.object({
9972
10012
  variant: headerVariantWithLegacyAliasSchema,
9973
10013
  positioning: headerPositioning,
9974
10014
  shrinkOnScroll: z.boolean(),
9975
- maxWidth: headerMaxWidth,
9976
- barFrame: headerBarFrame.optional(),
10015
+ maxWidth: headerMaxWidth.default("container"),
9977
10016
  scrollTreatment: headerScrollTreatmentSchema,
9978
- logoOverride: mediaSchema.nullable().optional(),
9979
10017
  background: headerBackgroundSchema.default({
9980
10018
  type: "color",
9981
10019
  color: "surface"
@@ -9987,13 +10025,11 @@ const headerSchema = z.object({
9987
10025
  navFontRole: z.enum(["body", "heading"]).optional(),
9988
10026
  navTextSize: navLinkStyleSchema.shape.textSize,
9989
10027
  interactionPalette: headerInteractionPaletteSchema.optional(),
9990
- navPlacement: z.enum(["end", "center"]).optional(),
9991
10028
  container: headerContainerSchema,
9992
10029
  border: headerBorderSchema,
9993
10030
  shadow: componentShadowSchema.optional(),
9994
10031
  logo: logoStyleSchema,
9995
10032
  logoText: headerLogoTextSchema,
9996
- navEffects: navEffectsSchema,
9997
10033
  navContainer: navContainerSchema,
9998
10034
  navLinkStyle: navLinkStyleSchema.optional(),
9999
10035
  ctaGap: headerCtaGapSchema.optional(),
@@ -10175,11 +10211,6 @@ const bodyTextSchema = z.object({ intro: z.object({
10175
10211
  paragraphSize: bodyTextIntroTypographySizeSchema.optional(),
10176
10212
  headingSize: bodyTextIntroTypographySizeSchema.optional()
10177
10213
  }).optional() }).optional();
10178
- const gradientsSchema = z.object({
10179
- button: z.string().min(1).nullable().optional(),
10180
- hero: z.string().min(1).nullable().optional(),
10181
- background: z.string().min(1).nullable().optional()
10182
- });
10183
10214
  /**
10184
10215
  * Testimonial quote-mark treatment, owned by the site style (analogous to the
10185
10216
  * accordion icon). `style` is the coarse selector; the optional fields fine-tune
@@ -14303,7 +14334,113 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
14303
14334
  });
14304
14335
  };
14305
14336
  //#endregion
14306
- //#region ../blocks/src/system/runtime/nodes/events/shared/destination.ts
14337
+ //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorRecovery.ts
14338
+ function resolveRegistrationRecoveryAction(step, action) {
14339
+ if (step === "payment-failed") return "payment-options";
14340
+ if (step === "verifying-payment" || step === "verifying-timeout" || step === "redirecting") return "payment-status";
14341
+ return action;
14342
+ }
14343
+ function canRecoverToWaitlist(eligibility) {
14344
+ return Boolean(eligibility?.isFull && eligibility.canJoinWaitlist);
14345
+ }
14346
+ function shouldRefreshAfterRegistrationError(step, action, enabled) {
14347
+ return enabled || step === "error" && action === "places";
14348
+ }
14349
+ function resetRegistrationAfterExpiry(input) {
14350
+ input.dispatchFlow({
14351
+ type: "reset",
14352
+ hasPreSelectedContext: input.hasPreSelectedContext
14353
+ });
14354
+ input.setSelectedTicketLines([]);
14355
+ input.setSelectedSlidingAmountInput("");
14356
+ const mode = input.preSelectedEvent?.deliveryMode;
14357
+ input.setSelectedAttendanceMode(mode === "online" || mode === "in_person" ? mode : null);
14358
+ input.setErrorMessage("");
14359
+ input.setPendingRegistrationReference(null);
14360
+ }
14361
+ /** Recovery never starts another payment. Unknown payment outcomes go to the portal. */
14362
+ function recoverRegistrationError(action, handlers) {
14363
+ switch (action) {
14364
+ case "none": return;
14365
+ case "portal":
14366
+ case "payment-status":
14367
+ window.location.assign("/portal");
14368
+ return;
14369
+ case "event":
14370
+ window.location.assign(window.location.pathname);
14371
+ return;
14372
+ case "retry":
14373
+ window.location.reload();
14374
+ return;
14375
+ case "details":
14376
+ handlers.clearError();
14377
+ handlers.setStep("enter-details");
14378
+ return;
14379
+ case "payment-options":
14380
+ case "places":
14381
+ handlers.refreshOptions();
14382
+ handlers.clearError();
14383
+ handlers.setStep(action === "places" ? handlers.canJoinWaitlist ? "enter-details" : "select-tickets" : "select-payment");
14384
+ return;
14385
+ case "start":
14386
+ handlers.refreshOptions();
14387
+ handlers.reset();
14388
+ return;
14389
+ }
14390
+ }
14391
+ //#endregion
14392
+ //#region ../blocks/src/system/runtime/nodes/events/domain/capacity.ts
14393
+ /**
14394
+ * Compute remaining spots for an event from `availableSpots` with a fallback
14395
+ * to `capacity - registeredCount`. Returns `{ available: null, isFull: false }`
14396
+ * for uncapped events so call sites can render no capacity indicator at all.
14397
+ *
14398
+ * The single source of truth for capacity math across event cards, agenda
14399
+ * rows, and timetable cells — keep wording variations in the call sites.
14400
+ */
14401
+ function getEventAvailability(event) {
14402
+ if (event.capacity == null) return {
14403
+ available: null,
14404
+ isFull: false
14405
+ };
14406
+ const available = event.availableSpots ?? event.capacity - event.registeredCount;
14407
+ if (available <= 0) return {
14408
+ available: 0,
14409
+ isFull: true
14410
+ };
14411
+ return {
14412
+ available,
14413
+ isFull: false
14414
+ };
14415
+ }
14416
+ /**
14417
+ * Pick the capacity row a booking decision should read: the selected
14418
+ * attendance mode's availability when the visitor has chosen one and the
14419
+ * event publishes it, otherwise the event-level aggregate.
14420
+ *
14421
+ * The mode row is used wholesale. A mode with `capacity: null` on a capped
14422
+ * event is uncapped *by design*: the registration write path applies the
14423
+ * same rule via `getEffectiveOccurrenceCapacityForAttendanceMode`, so falling
14424
+ * back to the event's `availableSpots` here would block bookings the server
14425
+ * accepts. (Waitlist claims are still occurrence-scoped; see issue 1377.)
14426
+ */
14427
+ function selectEventCapacitySource(event, attendanceMode) {
14428
+ if (!attendanceMode) return event;
14429
+ return (event.attendanceModes ?? []).find((mode) => mode.mode === attendanceMode) ?? event;
14430
+ }
14431
+ /**
14432
+ * Whether the visitor's next step is the waitlist: the source is full *and*
14433
+ * a waitlist is open. The one place this is decided — cards, rows, the
14434
+ * wizard's steps and its action bar all route through here so they agree,
14435
+ * including for producers that omit `availableSpots` and rely on the
14436
+ * `capacity - registeredCount` fallback.
14437
+ */
14438
+ function canJoinEventWaitlist(event, options) {
14439
+ const source = selectEventCapacitySource(event, options?.attendanceMode);
14440
+ return getEventAvailability(source).isFull && source.waitlistEnabled === true;
14441
+ }
14442
+ //#endregion
14443
+ //#region ../blocks/src/system/runtime/nodes/events/domain/destination.ts
14307
14444
  function isRecord$2(value) {
14308
14445
  return typeof value === "object" && value !== null && !Array.isArray(value);
14309
14446
  }
@@ -14321,7 +14458,7 @@ function resolveRuntimeEventDestination(event) {
14321
14458
  };
14322
14459
  }
14323
14460
  //#endregion
14324
- //#region ../blocks/src/system/runtime/nodes/events/shared/pricing.ts
14461
+ //#region ../blocks/src/system/runtime/nodes/events/domain/pricing.ts
14325
14462
  const DEFAULT_EVENT_CURRENCY = "USD";
14326
14463
  function resolveRuntimeEventPricing(event) {
14327
14464
  if (isPublicEventPricing(event.pricing)) return event.pricing;
@@ -14831,11 +14968,11 @@ function useEligibilityWithDeps(params, deps) {
14831
14968
  type: "resolved",
14832
14969
  eligibility: transformRegistrationOptionsResponse(result)
14833
14970
  });
14834
- } catch (err) {
14971
+ } catch {
14835
14972
  if (cancelled || requestIdRef.current !== requestId) return;
14836
14973
  dispatch({
14837
14974
  type: "failed",
14838
- message: err instanceof Error ? err.message : "Failed to check eligibility"
14975
+ message: "We couldn’t load the booking options for this event. Please refresh this page and try again. If this keeps happening, contact the organiser for help."
14839
14976
  });
14840
14977
  }
14841
14978
  }
@@ -14847,6 +14984,7 @@ function useEligibilityWithDeps(params, deps) {
14847
14984
  }, [
14848
14985
  api,
14849
14986
  params.enabled,
14987
+ params.refreshKey,
14850
14988
  params.subject?.kind,
14851
14989
  params.subject?.kind === "occurrence" ? params.subject.occurrenceId : params.subject?.eventSeriesId,
14852
14990
  params.attendanceMode,
@@ -14956,8 +15094,122 @@ function logoutPortal(anchorId) {
14956
15094
  form.submit();
14957
15095
  }
14958
15096
  //#endregion
15097
+ //#region ../commerce/src/purchase/checkoutSessionMetadata.ts
15098
+ const datedOfferingSharedEngineMetadataShape = {
15099
+ datedOfferingEngineContractVersion: z.literal("shared_v1"),
15100
+ datedOfferingEngineRouteKind: z.literal("shared_whole_series_registration"),
15101
+ datedOfferingCapacityHoldId: z.string().uuid(),
15102
+ datedOfferingCapacityHoldAuditRef: z.string().uuid(),
15103
+ customerId: z.string().uuid(),
15104
+ eventSeriesId: z.string().uuid()
15105
+ };
15106
+ z.object(datedOfferingSharedEngineMetadataShape);
15107
+ const orderCheckoutSessionMetadataBaseShape = {
15108
+ type: z.literal("order"),
15109
+ site_id: z.string().uuid(),
15110
+ order_id: z.string().uuid().optional(),
15111
+ customer_email: z.string().email(),
15112
+ customer_name: z.string().optional(),
15113
+ product_id: z.string().uuid().optional(),
15114
+ attendee_id: z.string().uuid().optional(),
15115
+ occurrence_id: z.string().uuid().optional(),
15116
+ tickets_count: z.string().optional(),
15117
+ notes: z.string().optional(),
15118
+ discount_redemption_id: z.string().uuid().optional(),
15119
+ discount_code_id: z.string().uuid().optional(),
15120
+ discount_code: z.string().optional(),
15121
+ discount_public_label: z.string().optional(),
15122
+ credit_reservation_id: z.string().uuid().optional(),
15123
+ credit_reserved_cents: z.string().optional(),
15124
+ discount_code_amount_cents: z.string().optional(),
15125
+ order_payment_reason: z.enum([
15126
+ "instalment_payoff",
15127
+ "flexible_balance_initial",
15128
+ "flexible_balance_paydown"
15129
+ ]).optional(),
15130
+ order_payment_plan_id: z.string().uuid().optional(),
15131
+ order_flexible_balance_contract_id: z.string().uuid().optional()
15132
+ };
15133
+ const absentDatedOfferingSharedEngineMetadataShape = {
15134
+ datedOfferingEngineContractVersion: z.never().optional(),
15135
+ datedOfferingEngineRouteKind: z.never().optional(),
15136
+ datedOfferingCapacityHoldId: z.never().optional(),
15137
+ datedOfferingCapacityHoldAuditRef: z.never().optional(),
15138
+ customerId: z.never().optional(),
15139
+ eventSeriesId: z.never().optional()
15140
+ };
15141
+ const LegacyOrderCheckoutSessionMetadataSchema = z.object({
15142
+ ...orderCheckoutSessionMetadataBaseShape,
15143
+ ...absentDatedOfferingSharedEngineMetadataShape
15144
+ });
15145
+ const SharedDatedOfferingOrderCheckoutSessionMetadataSchema = z.object({
15146
+ ...orderCheckoutSessionMetadataBaseShape,
15147
+ ...datedOfferingSharedEngineMetadataShape
15148
+ });
15149
+ z.union([SharedDatedOfferingOrderCheckoutSessionMetadataSchema, LegacyOrderCheckoutSessionMetadataSchema]);
15150
+ toNonNegativeCents(0);
15151
+ //#endregion
15152
+ //#region ../commerce/src/purchase/event-registration-errors.ts
15153
+ const eventRegistrationErrors = {
15154
+ registrationClosed: {
15155
+ message: "Booking is currently closed for this event. Please contact the organiser if you’d like to find out more.",
15156
+ action: "none"
15157
+ },
15158
+ paymentUncertain: {
15159
+ 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.",
15160
+ action: "payment-status"
15161
+ },
15162
+ paymentPageUnavailable: {
15163
+ message: "We couldn’t open the payment page. Please refresh this page and try again. If this keeps happening, contact the organiser for help.",
15164
+ action: "retry"
15165
+ },
15166
+ paymentUnavailable: {
15167
+ message: "Online payment is not available for this event right now. Please contact the organiser for help with booking.",
15168
+ action: "none"
15169
+ },
15170
+ capacityChanged: {
15171
+ message: "Sorry, there aren’t enough places left for your selection. Please check the available places and choose again.",
15172
+ action: "places"
15173
+ },
15174
+ selectionChanged: {
15175
+ message: "The booking options for this event have changed. Please check the latest options and choose your places again.",
15176
+ action: "places"
15177
+ },
15178
+ registrationPreparationChanged: {
15179
+ message: "The booking options for this event have changed. Please check the latest options and choose your places again.",
15180
+ action: "places"
15181
+ },
15182
+ registrationAlreadyExists: {
15183
+ message: "You already have a booking for this event. Please check your bookings to see its status. If you need help, contact the organiser.",
15184
+ action: "portal"
15185
+ },
15186
+ holdExpired: {
15187
+ message: "Your reservation has timed out. Please check availability and choose your places again.",
15188
+ action: "start"
15189
+ },
15190
+ waitlistUnavailable: {
15191
+ message: "Sorry, the waiting list place offered in this invitation is no longer available. Please check the event for available places or contact the organiser for help.",
15192
+ action: "event"
15193
+ },
15194
+ paymentContextMismatch: {
15195
+ message: "The payment options for this event have changed. Please check the latest options before continuing.",
15196
+ action: "payment-options"
15197
+ },
15198
+ idempotencyConflict: {
15199
+ message: "You’ve already started booking this event. Please finish in the other tab if it’s still open, or check your booking status before starting again.",
15200
+ action: "portal"
15201
+ },
15202
+ invalidCommitInput: {
15203
+ message: "We couldn’t accept your booking details. Please check the information you entered and try again. If this keeps happening, contact the organiser for help.",
15204
+ action: "details"
15205
+ }
15206
+ };
15207
+ function parseEventRegistrationErrorReason(value) {
15208
+ return typeof value === "string" && Object.prototype.hasOwnProperty.call(eventRegistrationErrors, value) ? value : null;
15209
+ }
15210
+ //#endregion
14959
15211
  //#region ../blocks/src/system/runtime/shared/useWaitlistClaim.state.ts
14960
- const DEFAULT_WAITLIST_CLAIM_ERROR = "Failed to resolve waitlist claim";
15212
+ const DEFAULT_WAITLIST_CLAIM_ERROR = "Online booking is unavailable right now. Please contact the organiser for help with booking.";
14961
15213
  function createInitialWaitlistClaimState(hasToken) {
14962
15214
  return hasToken ? { kind: "resolving" } : { kind: "idle" };
14963
15215
  }
@@ -14973,14 +15225,13 @@ function waitlistClaimReducer(_state, action) {
14973
15225
  }
14974
15226
  }
14975
15227
  function toWaitlistClaimResolveFailure(error) {
14976
- const message = error instanceof Error ? error.message : DEFAULT_WAITLIST_CLAIM_ERROR;
14977
15228
  if (isUnauthorizedBlockApiError(error)) return {
14978
15229
  kind: "portal-login-required",
14979
- message
15230
+ message: "Please log in to continue with your waiting list invitation."
14980
15231
  };
14981
15232
  return {
14982
15233
  kind: "error",
14983
- message
15234
+ message: hasStatus(error) && (error.status === 404 || error.status === 409 || error.status === 410) ? eventRegistrationErrors.waitlistUnavailable.message : DEFAULT_WAITLIST_CLAIM_ERROR
14984
15235
  };
14985
15236
  }
14986
15237
  function isUnauthorizedBlockApiError(error) {
@@ -15341,47 +15592,136 @@ function cleanupStaleRegistrations() {
15341
15592
  //#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.ts
15342
15593
  const eventRegistrationStripeReturnDeps = {
15343
15594
  usePaymentVerification,
15344
- consumeReturnParams: () => consumeSearchParams(["registration", EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM]),
15595
+ readReturnParams: () => {
15596
+ const params = new URLSearchParams(window.location.search);
15597
+ return {
15598
+ registration: params.get("registration"),
15599
+ registration_attempt: params.get(EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM),
15600
+ session_id: params.get("session_id")
15601
+ };
15602
+ },
15603
+ clearReturnParams: () => {
15604
+ consumeSearchParams([
15605
+ "registration",
15606
+ EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM,
15607
+ "session_id"
15608
+ ]);
15609
+ },
15345
15610
  scrollToBlock,
15346
15611
  cleanupStaleRegistrations,
15347
15612
  clearPendingRegistration,
15348
15613
  getPendingRegistration
15349
15614
  };
15615
+ function restorePendingPresentation(options, pending) {
15616
+ options.setFormData(pending.formData);
15617
+ options.setTicketSelections(pending.ticketSelections);
15618
+ options.setTicketsCount(getTicketSelectionTotal(pending.ticketSelections));
15619
+ if (pending.selectedEventId) {
15620
+ const event = options.events.find((item) => item.selectionId === pending.selectedEventId) ?? null;
15621
+ if (event) options.setSelectedEvent(event);
15622
+ }
15623
+ options.setSelectedAttendanceMode(pending.selectedAttendanceMode ?? null);
15624
+ options.setPaymentSelection(pending.paymentSelection);
15625
+ }
15626
+ function showReturnReconciliation(options, message) {
15627
+ options.setErrorMessage(message);
15628
+ options.setStep("verifying-timeout");
15629
+ }
15630
+ function checkoutReturnCommand(params) {
15631
+ const checkoutAttemptId = params.registration_attempt;
15632
+ if (!checkoutAttemptId) return null;
15633
+ if (params.registration === "cancelled") return {
15634
+ kind: "abandon",
15635
+ checkoutAttemptId
15636
+ };
15637
+ if (params.registration === "success" && params.session_id) return {
15638
+ kind: "resolveSuccess",
15639
+ checkoutAttemptId,
15640
+ sessionId: params.session_id
15641
+ };
15642
+ return null;
15643
+ }
15644
+ async function handleCheckoutReturn(options, deps, checkoutAttemptIdRef) {
15645
+ deps.cleanupStaleRegistrations();
15646
+ const params = deps.readReturnParams();
15647
+ if (params.registration !== "cancelled" && params.registration !== "success") return "settled";
15648
+ deps.scrollToBlock(EVENT_REGISTRATION_ANCHOR_ID);
15649
+ const siteId = options.api.config.siteId;
15650
+ const command = checkoutReturnCommand(params);
15651
+ if (!siteId) return "settled";
15652
+ if (!command) {
15653
+ 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.");
15654
+ return "settled";
15655
+ }
15656
+ const { checkoutAttemptId } = command;
15657
+ const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
15658
+ checkoutAttemptIdRef.current = checkoutAttemptId;
15659
+ if (pending) restorePendingPresentation(options, pending);
15660
+ options.setStep("verifying-payment");
15661
+ try {
15662
+ const outcome = await options.api.resolveEventCheckoutReturn(command);
15663
+ switch (outcome.kind) {
15664
+ case "resolved":
15665
+ deps.clearReturnParams();
15666
+ options.setPendingRegistrationReference(outcome.reference);
15667
+ options.setStep("verifying-payment");
15668
+ return "settled";
15669
+ case "abandoned":
15670
+ deps.clearReturnParams();
15671
+ options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
15672
+ options.setStep("select-payment");
15673
+ return "settled";
15674
+ case "notFound":
15675
+ if (params.registration === "cancelled" && (options.registrationSubject?.kind === "occurrence" || pending?.reference.scope === "occurrence")) {
15676
+ deps.clearReturnParams();
15677
+ options.setErrorMessage("Your payment was cancelled. You can choose a payment option and try again.");
15678
+ options.setStep("select-payment");
15679
+ return "settled";
15680
+ }
15681
+ 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.");
15682
+ return "settled";
15683
+ case "reconciliationRequired": break;
15684
+ }
15685
+ 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.");
15686
+ } catch {
15687
+ 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.");
15688
+ }
15689
+ return "retryable";
15690
+ }
15350
15691
  function useEventRegistrationStripeReturn(options) {
15351
15692
  return useEventRegistrationStripeReturnWithDeps(options, eventRegistrationStripeReturnDeps);
15352
15693
  }
15353
15694
  function useEventRegistrationStripeReturnWithDeps(options, deps) {
15354
- const { api, events, pendingRegistrationReference, setErrorMessage, setFormData, setPaymentSelection, setPendingRegistrationReference, setRegistrationResult, setSelectedEvent, setSelectedAttendanceMode, setTicketSelections, setStep, setTicketsCount, step } = options;
15695
+ const { api, pendingRegistrationReference, setErrorMessage, setRegistrationResult, setStep, step } = options;
15355
15696
  const checkoutAttemptIdRef = useRef(null);
15697
+ const lookupInFlightRef = useRef(false);
15698
+ const [lookupState, setLookupState] = useState("settled");
15699
+ const resolveReturn = useCallback(async () => {
15700
+ if (lookupInFlightRef.current) return;
15701
+ lookupInFlightRef.current = true;
15702
+ setLookupState("loading");
15703
+ try {
15704
+ setLookupState(await handleCheckoutReturn(options, deps, checkoutAttemptIdRef));
15705
+ } finally {
15706
+ lookupInFlightRef.current = false;
15707
+ }
15708
+ }, [options, deps]);
15356
15709
  const verificationConfig = useMemo(() => step === "verifying-payment" && pendingRegistrationReference ? { reference: pendingRegistrationReference } : null, [step, pendingRegistrationReference]);
15357
15710
  const verification = deps.usePaymentVerification(verificationConfig);
15358
- useEffect(() => {
15359
- deps.cleanupStaleRegistrations();
15360
- const returnParams = deps.consumeReturnParams();
15361
- const registrationStatus = returnParams.registration;
15362
- if (registrationStatus !== "cancelled" && registrationStatus !== "success") return;
15363
- deps.scrollToBlock(EVENT_REGISTRATION_ANCHOR_ID);
15364
- const siteId = api.config.siteId;
15365
- if (!siteId) return;
15366
- const checkoutAttemptId = returnParams[EVENT_REGISTRATION_CHECKOUT_ATTEMPT_PARAM];
15367
- if (!checkoutAttemptId) return;
15368
- const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
15369
- if (!pending) return;
15370
- checkoutAttemptIdRef.current = checkoutAttemptId;
15371
- setFormData(pending.formData);
15372
- setTicketSelections(pending.ticketSelections);
15373
- setTicketsCount(getTicketSelectionTotal(pending.ticketSelections));
15374
- if (pending.selectedEventId) {
15375
- const event = events.find((e) => e.selectionId === pending.selectedEventId) ?? null;
15376
- if (event) setSelectedEvent(event);
15377
- }
15378
- setSelectedAttendanceMode(pending.selectedAttendanceMode ?? null);
15379
- setPaymentSelection(pending.paymentSelection);
15380
- if (registrationStatus === "cancelled") setStep("select-payment");
15381
- else if (registrationStatus === "success") {
15382
- setPendingRegistrationReference(pending.reference);
15711
+ const hasVerificationTimeout = step === "verifying-timeout" && pendingRegistrationReference !== null;
15712
+ const retry = useCallback(() => {
15713
+ if (hasVerificationTimeout) {
15383
15714
  setStep("verifying-payment");
15715
+ return;
15384
15716
  }
15717
+ verification.retry();
15718
+ }, [
15719
+ hasVerificationTimeout,
15720
+ setStep,
15721
+ verification.retry
15722
+ ]);
15723
+ useEffect(() => {
15724
+ resolveReturn();
15385
15725
  }, []);
15386
15726
  useEffect(() => {
15387
15727
  if (verification.status === "completed") {
@@ -15391,7 +15731,7 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
15391
15731
  setRegistrationResult({ status: "confirmed" });
15392
15732
  setStep("success");
15393
15733
  } else if (verification.status === "failed") {
15394
- setErrorMessage(verification.error ?? "Payment failed. Please try again.");
15734
+ setErrorMessage("Please try again or choose another payment option. If this keeps happening, contact the organiser for help.");
15395
15735
  setStep("payment-failed");
15396
15736
  } else if (verification.status === "timeout") setStep("verifying-timeout");
15397
15737
  }, [
@@ -15404,7 +15744,22 @@ function useEventRegistrationStripeReturnWithDeps(options, deps) {
15404
15744
  setRegistrationResult,
15405
15745
  setStep
15406
15746
  ]);
15407
- return verification;
15747
+ return {
15748
+ ...verification,
15749
+ status: hasVerificationTimeout ? "timeout" : verification.status,
15750
+ retry,
15751
+ retryReturn: lookupState === "retryable" ? () => {
15752
+ resolveReturn();
15753
+ } : void 0
15754
+ };
15755
+ }
15756
+ //#endregion
15757
+ //#region ../blocks/src/system/runtime/nodes/event-registration/registrationErrorPresentation.ts
15758
+ function registrationErrorPresentation(error) {
15759
+ const reason = error instanceof BlockApiError ? parseEventRegistrationErrorReason(error.tag) : null;
15760
+ if (reason) return eventRegistrationErrors[reason];
15761
+ if (error instanceof BlockApiError && error.status < 500) return eventRegistrationErrors.invalidCommitInput;
15762
+ return eventRegistrationErrors.paymentUncertain;
15408
15763
  }
15409
15764
  //#endregion
15410
15765
  //#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.ts
@@ -15464,7 +15819,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
15464
15819
  options.setStep("submitting");
15465
15820
  try {
15466
15821
  const prepared = prepareSubmitContext(options, target, method, passId, membershipId, selection);
15467
- if (prepared.subject.kind === "wholeSeries" && method === "stripe") return submitWholeSeriesCheckout(options, deps, {
15822
+ if (prepared.subject.kind === "wholeSeries" && method === "stripe") return await submitWholeSeriesCheckout(options, deps, {
15468
15823
  ...prepared,
15469
15824
  subject: prepared.subject
15470
15825
  }, submitOptions);
@@ -15485,7 +15840,7 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
15485
15840
  claimToken: options.claimToken ?? void 0,
15486
15841
  guests: prepared.guestsPayload
15487
15842
  });
15488
- if (needsOccurrenceCheckout(result, method)) return submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
15843
+ if (needsOccurrenceCheckout(result, method)) return await submitOccurrenceCheckout(options, deps, prepared, result, method, submitOptions);
15489
15844
  options.setRegistrationResult(toRegistrationResult(result));
15490
15845
  options.setStep("success");
15491
15846
  return {
@@ -15493,7 +15848,8 @@ function useEventRegistrationSubmitWithDeps(options, deps) {
15493
15848
  outcome: { kind: "completed" }
15494
15849
  };
15495
15850
  } catch (error) {
15496
- const message = error instanceof Error ? error.message : "Registration failed";
15851
+ const { message, action } = registrationErrorPresentation(error);
15852
+ options.setErrorAction?.(action);
15497
15853
  options.setErrorMessage(message);
15498
15854
  options.setStep("error");
15499
15855
  return {
@@ -15568,6 +15924,7 @@ async function submitWholeSeriesCheckout(options, deps, prepared, submitOptions)
15568
15924
  claimToken: options.claimToken ?? void 0,
15569
15925
  discountCode: options.discountCode.trim() || void 0,
15570
15926
  collectionOptionKind: prepared.selectionSnapshot.collectionOptionKind,
15927
+ checkoutAttemptId,
15571
15928
  ...urls
15572
15929
  });
15573
15930
  if (result.scope !== "wholeSeries") throw new Error("Unexpected registration scope for event checkout.");
@@ -16577,12 +16934,12 @@ function getEventRegistrationOverrideInput(props) {
16577
16934
  if (!props.siteId) return {
16578
16935
  ok: false,
16579
16936
  reason: "missing-site-id",
16580
- message: "Event registration is missing site context."
16937
+ message: "Online booking is unavailable right now. Please contact the organiser for help with booking."
16581
16938
  };
16582
16939
  if (!props.apiBaseUrl) return {
16583
16940
  ok: false,
16584
16941
  reason: "missing-api-base-url",
16585
- message: "Event registration is missing API configuration."
16942
+ message: "Online booking is unavailable right now. Please contact the organiser for help with booking."
16586
16943
  };
16587
16944
  const content = props.content ?? {};
16588
16945
  const data = isRecord(props.data) ? props.data : {};
@@ -16769,7 +17126,8 @@ function resolveHeadlessEventRegistrationStatus(wizard) {
16769
17126
  } : { tag: "ready" };
16770
17127
  case "error": return {
16771
17128
  tag: "error",
16772
- message: wizard.errorMessage
17129
+ message: wizard.errorMessage,
17130
+ ...wizard.errorAction ? { action: wizard.errorAction } : {}
16773
17131
  };
16774
17132
  case "select-event":
16775
17133
  case "select-tickets":
@@ -16784,7 +17142,7 @@ function resolveHeadlessEventRegistrationView(wizard) {
16784
17142
  };
16785
17143
  if (!wizard.scopedEvents.some(isEventRegistrationAvailable) && !wizard.occurrenceContext) return {
16786
17144
  kind: "unavailable",
16787
- message: "Registration is not currently available for this event."
17145
+ message: "Booking is currently closed for this event. Please contact the organiser if you’d like to find out more."
16788
17146
  };
16789
17147
  switch (wizard.step) {
16790
17148
  case "verifying-payment": return {
@@ -16802,7 +17160,7 @@ function resolveHeadlessEventRegistrationView(wizard) {
16802
17160
  };
16803
17161
  case "verifying-timeout": return {
16804
17162
  kind: "verifying",
16805
- message: "Your registration is saved."
17163
+ message: "Your booking is not confirmed yet. Please don’t make another booking while we check. You can check your payment status again in a moment."
16806
17164
  };
16807
17165
  case "select-event":
16808
17166
  case "select-tickets":
@@ -17039,6 +17397,13 @@ function toWholeSeriesRegistrationEvents(offerings) {
17039
17397
  }
17040
17398
  //#endregion
17041
17399
  //#region ../blocks/src/system/runtime/nodes/event-registration/registrationWizardContext.ts
17400
+ function getEventSelectionDefaults(event) {
17401
+ const suggestedAmount = getSlidingScaleForEvent(event)?.suggestedAmount;
17402
+ return {
17403
+ slidingAmountInput: suggestedAmount == null ? "" : formatCentsAsCurrencyInput(suggestedAmount),
17404
+ attendanceMode: event.deliveryMode === "hybrid" ? null : event.deliveryMode ?? "in_person"
17405
+ };
17406
+ }
17042
17407
  function parseCurrencyInputToCents(value) {
17043
17408
  const trimmed = value.trim();
17044
17409
  if (!trimmed) return null;
@@ -17086,7 +17451,7 @@ function resolveWaitlistClaimRestoration(input) {
17086
17451
  const event = findEventByOccurrenceId(input.scopedEvents, subject.occurrenceId);
17087
17452
  if (!event && input.occurrenceContextId !== subject.occurrenceId) return {
17088
17453
  ok: false,
17089
- message: "This waitlist claim is for a different event."
17454
+ message: "This waiting list invitation is for a different event. Please open the link in your invitation email."
17090
17455
  };
17091
17456
  return {
17092
17457
  ok: true,
@@ -17103,7 +17468,7 @@ function resolveWaitlistClaimRestoration(input) {
17103
17468
  const event = input.scopedEvents.find((candidate) => candidate.registrationSubject.kind === "wholeSeries" && candidate.registrationSubject.eventSeriesId === subject.eventSeriesId);
17104
17469
  if (!event) return {
17105
17470
  ok: false,
17106
- message: "This waitlist claim is for a different event run."
17471
+ message: "This waiting list invitation is for a different event. Please open the link in your invitation email."
17107
17472
  };
17108
17473
  return {
17109
17474
  ok: true,
@@ -17136,6 +17501,7 @@ function useWaitlistClaimRestoration(input) {
17136
17501
  occurrenceContextId: input.occurrenceContextId
17137
17502
  });
17138
17503
  if (!restoration.ok) {
17504
+ input.setters.setErrorAction?.("none");
17139
17505
  input.setters.setErrorMessage(restoration.message);
17140
17506
  input.setters.setStep("error");
17141
17507
  return;
@@ -17214,6 +17580,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17214
17580
  });
17215
17581
  const [registrationResult, setRegistrationResult] = useState(null);
17216
17582
  const [errorMessage, setErrorMessage] = useState("");
17583
+ const [errorAction, setErrorAction] = useState("retry");
17584
+ const [optionsRefreshKey, setOptionsRefreshKey] = useState(0);
17217
17585
  const [altchaSolution, setAltchaSolution] = useState(null);
17218
17586
  const { authState: portalAuthState, profile: portalProfile } = deps.usePortalAuth();
17219
17587
  const waitlistClaim = deps.useWaitlistClaim();
@@ -17243,10 +17611,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17243
17611
  const currentEvent = selectedEvent ?? preSelectedEvent;
17244
17612
  const currentEventPricing = currentEvent ? resolveRuntimeEventPricing(currentEvent) : null;
17245
17613
  const currentEventUsesTicketTypes = currentEventPricing !== null && publicEventPricingMode(currentEventPricing) === "ticket_types";
17246
- const selectedModeAvailability = selectedAttendanceMode ? (currentEvent?.attendanceModes ?? []).find((mode) => mode.mode === selectedAttendanceMode) ?? null : null;
17247
- const currentAvailableSpots = selectedModeAvailability?.availableSpots ?? currentEvent?.availableSpots;
17248
- const currentWaitlistEnabled = selectedModeAvailability?.waitlistEnabled ?? currentEvent?.waitlistEnabled ?? false;
17249
- const usesTicketTypeSelections = currentEventUsesTicketTypes && !(currentAvailableSpots === 0 && currentWaitlistEnabled === true);
17614
+ const currentCanJoinWaitlist = currentEvent ? canJoinEventWaitlist(currentEvent, { attendanceMode: selectedAttendanceMode }) : false;
17615
+ const usesTicketTypeSelections = currentEventUsesTicketTypes && !currentCanJoinWaitlist;
17250
17616
  const eventTicketTypesForSelection = useMemo(() => getVisibleTicketTypes({
17251
17617
  event: currentEvent,
17252
17618
  eligibility: null,
@@ -17277,7 +17643,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17277
17643
  });
17278
17644
  }, [flowState.ticketsCount, ticketsCount]);
17279
17645
  const eligibilityResult = deps.useEligibility({
17280
- enabled: shouldLoadRegistrationOptions(portalAuthState, step),
17646
+ refreshKey: optionsRefreshKey,
17647
+ enabled: shouldRefreshAfterRegistrationError(step, errorAction, shouldLoadRegistrationOptions(portalAuthState, step)),
17281
17648
  subject: registrationTarget?.subject ?? null,
17282
17649
  attendanceMode: selectedAttendanceMode,
17283
17650
  ticketSelections,
@@ -17306,6 +17673,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17306
17673
  });
17307
17674
  }, [waitlistClaim.claim]);
17308
17675
  const waitlistRestorationSetters = useMemo(() => ({
17676
+ setErrorAction,
17309
17677
  setErrorMessage,
17310
17678
  setStep,
17311
17679
  setSelectedEvent,
@@ -17329,6 +17697,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17329
17697
  if (waitlistClaim.requiresPortalLogin) return;
17330
17698
  if (!waitlistClaim.error) return;
17331
17699
  setErrorMessage(waitlistClaim.error);
17700
+ setErrorAction("event");
17332
17701
  setStep("error");
17333
17702
  }, [
17334
17703
  waitlistClaim.error,
@@ -17431,8 +17800,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17431
17800
  const event = currentEvent;
17432
17801
  if (!event || publicEventPricingMode(resolveRuntimeEventPricing(event)) !== "ticket_types") return false;
17433
17802
  if ((event.deliveryMode ?? "in_person") === "hybrid" && !selectedAttendanceMode) return false;
17434
- const selectedModeAvailability = selectedAttendanceMode ? (event.attendanceModes ?? []).find((mode) => mode.mode === selectedAttendanceMode) ?? null : null;
17435
- return !((selectedModeAvailability?.availableSpots ?? event.availableSpots) === 0 && (selectedModeAvailability?.waitlistEnabled ?? event.waitlistEnabled) === true);
17803
+ return !canJoinEventWaitlist(event, { attendanceMode: selectedAttendanceMode });
17436
17804
  }, [currentEvent, selectedAttendanceMode]);
17437
17805
  const hasValidTicketSelection = !ticketTypeSelectionRequired || normalizedSelectedTicketLines.length > 0 && normalizedSelectedTicketLines.every((line) => {
17438
17806
  if (!line.ticketTypeId) return false;
@@ -17513,6 +17881,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17513
17881
  ]);
17514
17882
  const handleDetailsComplete = async () => {
17515
17883
  if (ticketTypeSelectionRequired && !hasValidTicketSelection) {
17884
+ setErrorAction("places");
17516
17885
  const message = "Choose at least one available ticket to continue.";
17517
17886
  setErrorMessage(message);
17518
17887
  setStep("error");
@@ -17523,6 +17892,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17523
17892
  };
17524
17893
  }
17525
17894
  if (slidingScaleSelectionMessage) {
17895
+ setErrorAction("places");
17526
17896
  setErrorMessage(slidingScaleSelectionMessage);
17527
17897
  setStep("error");
17528
17898
  return {
@@ -17540,7 +17910,8 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17540
17910
  };
17541
17911
  }
17542
17912
  if (waitlistClaim.claim === null && eligibility?.isFull && !eligibility.canJoinWaitlist) {
17543
- const message = "This event is sold out.";
17913
+ const message = "Sorry, there aren’t enough places left for your selection. Please check the available places and choose again.";
17914
+ setErrorAction("places");
17544
17915
  setErrorMessage(message);
17545
17916
  setStep("error");
17546
17917
  return {
@@ -17656,6 +18027,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17656
18027
  const selectionMethod = paymentSelection.method;
17657
18028
  const shouldShowDiscountToggle = discountContext !== null && discountUi.manualCodeEntryAllowed && (selectionMethod === "stripe" || selectionMethod === "pass_bundle" || selectionMethod === "membership_bundle");
17658
18029
  const handleSubmit = deps.useEventRegistrationSubmit({
18030
+ setErrorAction,
17659
18031
  api,
17660
18032
  registrationTarget,
17661
18033
  selectedAttendanceMode,
@@ -17678,26 +18050,31 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17678
18050
  ...current,
17679
18051
  consentAccepted: false
17680
18052
  }));
17681
- const slidingScale = getSlidingScaleForEvent(event);
17682
- setSelectedSlidingAmountInput(slidingScale?.suggestedAmount !== null && slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(slidingScale.suggestedAmount) : "");
17683
- setSelectedAttendanceMode((event.deliveryMode ?? "in_person") === "hybrid" ? null : (event.deliveryMode ?? "in_person") === "online" ? "online" : "in_person");
18053
+ const defaults = getEventSelectionDefaults(event);
18054
+ setSelectedSlidingAmountInput(defaults.slidingAmountInput);
18055
+ setSelectedAttendanceMode(defaults.attendanceMode);
17684
18056
  setSelectedTicketLines([]);
17685
18057
  dispatchFlow({
17686
18058
  type: "event-changed",
17687
18059
  hasPreSelectedContext: true
17688
18060
  });
17689
18061
  };
17690
- const handleRetry = () => {
17691
- dispatchFlow({
17692
- type: "reset",
17693
- hasPreSelectedContext
17694
- });
17695
- setSelectedTicketLines([]);
17696
- setSelectedSlidingAmountInput("");
17697
- setSelectedAttendanceMode(preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null);
17698
- setErrorMessage("");
17699
- setPendingRegistrationReference(null);
17700
- };
18062
+ const handleRetry = () => recoverRegistrationError(resolveRegistrationRecoveryAction(step, errorAction), {
18063
+ canJoinWaitlist: canRecoverToWaitlist(eligibility),
18064
+ refreshOptions: () => setOptionsRefreshKey((value) => value + 1),
18065
+ clearError: () => setErrorMessage(""),
18066
+ setStep,
18067
+ reset: () => resetRegistrationAfterExpiry({
18068
+ hasPreSelectedContext,
18069
+ preSelectedEvent,
18070
+ dispatchFlow,
18071
+ setSelectedTicketLines,
18072
+ setSelectedSlidingAmountInput,
18073
+ setSelectedAttendanceMode,
18074
+ setErrorMessage,
18075
+ setPendingRegistrationReference
18076
+ })
18077
+ });
17701
18078
  const handlePaymentStepStateChange = useCallback((state) => {
17702
18079
  setPaymentStepState(state);
17703
18080
  }, []);
@@ -17760,6 +18137,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17760
18137
  handleGuestShakeEnd,
17761
18138
  registrationResult,
17762
18139
  errorMessage,
18140
+ errorAction,
17763
18141
  altchaSolution,
17764
18142
  setAltchaSolution,
17765
18143
  portalAuthState,