@riverbankcms/sdk 0.130.0 → 0.132.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 (468) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/README.md +1 -1
  3. package/dist/{PreviewEditorSidebar-DiEpbOdw.mjs → PreviewEditorSidebar-DKQ5eFK9.mjs} +365 -106
  4. package/dist/{PreviewEditorUI-C6MvxnIa.mjs → PreviewEditorUI-CNTcOjCC.mjs} +3 -3
  5. package/dist/{PreviewQueryProvider-C2rnoPz6.mjs → PreviewQueryProvider-D51gQaG3.mjs} +1 -1
  6. package/dist/{SdkPreviewModeRuntime-DRXA_m5L.mjs → SdkPreviewModeRuntime-DJu3qu33.mjs} +91 -25
  7. package/dist/{SiteChromeCustomizeContext-BTHdv5_-.mjs → SiteChromeCustomizeContext-2TzT3vbj.mjs} +12577 -9240
  8. package/dist/_dts/ai/src/contracts/proposals.d.ts +991 -142
  9. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +1092 -148
  10. package/dist/_dts/api/src/accountApi.d.ts +213 -0
  11. package/dist/_dts/api/src/accountEndpointDefinitions.d.ts +30 -0
  12. package/dist/_dts/api/src/accountEndpoints.d.ts +254 -0
  13. package/dist/_dts/api/src/apiCallParams.d.ts +60 -0
  14. package/dist/_dts/api/src/bookingConfig.d.ts +18 -24
  15. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +12 -24
  16. package/dist/_dts/api/src/bookingManagementEventEndpointTypes.d.ts +44 -0
  17. package/dist/_dts/api/src/bookingSettingsSections.d.ts +9 -0
  18. package/dist/_dts/api/src/bookingVerticals.d.ts +1 -140
  19. package/dist/_dts/api/src/commercePortalEndpoints.d.ts +47 -12
  20. package/dist/_dts/api/src/contentRuntime.d.ts +2 -1
  21. package/dist/_dts/api/src/courses.d.ts +1 -19
  22. package/dist/_dts/api/src/endpoints.d.ts +885 -721
  23. package/dist/_dts/api/src/event-destination-policy.d.ts +2 -2
  24. package/dist/_dts/api/src/eventManagementContracts.d.ts +173 -7
  25. package/dist/_dts/api/src/eventManagementEndpointDefinitions.d.ts +58 -0
  26. package/dist/_dts/api/src/giftingDashboard.d.ts +117 -0
  27. package/dist/_dts/api/src/giftingEndpointDefinitions.d.ts +124 -0
  28. package/dist/_dts/api/src/index.d.ts +12 -4
  29. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -0
  30. package/dist/_dts/api/src/indexExtendedTypes.d.ts +1 -0
  31. package/dist/_dts/api/src/media.d.ts +1 -0
  32. package/dist/_dts/api/src/navigation/dashboardBookingsNav.d.ts +3 -4
  33. package/dist/_dts/api/src/oauth.d.ts +8 -0
  34. package/dist/_dts/api/src/preview-auth.d.ts +26 -0
  35. package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +11 -0
  36. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +29 -16
  37. package/dist/_dts/api/src/publicExperience/sharedTypes.d.ts +2 -0
  38. package/dist/_dts/api/src/publicExperience/wholeSeriesEndpoints.d.ts +1 -1
  39. package/dist/_dts/api/src/sdk-event-upsert.d.ts +3 -1
  40. package/dist/_dts/api/src/sdkBlockUpsertContracts.d.ts +48 -0
  41. package/dist/_dts/api/src/sdkBookingVerticalContracts.d.ts +29 -0
  42. package/dist/_dts/api/src/sdkContracts.d.ts +14 -45
  43. package/dist/_dts/api/src/sdkEndpointDefinitions.d.ts +23 -0
  44. package/dist/_dts/api/src/sdkEventCategoryContracts.d.ts +9 -0
  45. package/dist/_dts/api/src/sdkSettingsContracts.d.ts +25 -0
  46. package/dist/_dts/api/src/sdkThemeCatalogContracts.d.ts +20 -0
  47. package/dist/_dts/api/src/sdkThemeWire.d.ts +54 -12
  48. package/dist/_dts/api/src/settings/permissions.d.ts +2 -2
  49. package/dist/_dts/api/src/siteApiKeyEndpointDefinitions.d.ts +66 -0
  50. package/dist/_dts/api/src/siteInfrastructure.d.ts +3 -3
  51. package/dist/_dts/api/src/siteOnboarding.d.ts +3 -3
  52. package/dist/_dts/api/src/siteOperations.d.ts +1 -1
  53. package/dist/_dts/api/src/sitePlatformEndpoints.d.ts +16 -14
  54. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +0 -3
  55. package/dist/_dts/api/src/types.d.ts +8 -61
  56. package/dist/_dts/block-form/src/client/index.d.ts +15 -23
  57. package/dist/_dts/block-form/src/index.d.ts +23 -22
  58. package/dist/_dts/blocks/src/PageRenderer.d.ts +2 -13
  59. package/dist/_dts/blocks/src/contracts/non-block-islands.d.ts +9 -0
  60. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +26 -44
  61. package/dist/_dts/blocks/src/index.d.ts +1 -1
  62. package/dist/_dts/blocks/src/primitives/layout/Grid.d.ts +18 -1
  63. package/dist/_dts/blocks/src/subroutes/fold.d.ts +2 -1
  64. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +1 -0
  65. package/dist/_dts/blocks/src/system/blocks/courses/shared/index.d.ts +0 -3
  66. package/dist/_dts/blocks/src/system/blocks/courses/shared/pricing.d.ts +2 -50
  67. package/dist/_dts/blocks/src/system/blocks/courses/shared/schemas.d.ts +1 -929
  68. package/dist/_dts/blocks/src/system/blocks/courses/shared/types.d.ts +1 -97
  69. package/dist/_dts/blocks/src/system/blocks/event-details.d.ts +39 -6
  70. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +2 -1
  71. package/dist/_dts/blocks/src/system/blocks/events/event-listing.d.ts +3 -3
  72. package/dist/_dts/blocks/src/system/blocks/events/event-spotlight.d.ts +2 -3
  73. package/dist/_dts/blocks/src/system/blocks/events/shared/filtering.d.ts +2 -2
  74. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +64 -3
  75. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +26 -31
  76. package/dist/_dts/blocks/src/system/blocks/events/whole-series/index.d.ts +3 -0
  77. package/dist/_dts/blocks/src/system/blocks/events/whole-series/pricing.d.ts +50 -0
  78. package/dist/_dts/blocks/src/system/blocks/events/whole-series/schemas.d.ts +135 -0
  79. package/dist/_dts/blocks/src/system/blocks/events/whole-series/types.d.ts +81 -0
  80. package/dist/_dts/blocks/src/system/blocks/feature-cards.d.ts +25 -1
  81. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +16 -39
  82. package/dist/_dts/blocks/src/system/blocks/offerings-preview/model.d.ts +1 -1
  83. package/dist/_dts/blocks/src/system/blocks/site-header.d.ts +0 -1
  84. package/dist/_dts/blocks/src/system/blocks/team-members.d.ts +4 -63
  85. package/dist/_dts/blocks/src/system/customize/backgrounds.d.ts +1 -3
  86. package/dist/_dts/blocks/src/system/fields/boxStyles.d.ts +13 -2
  87. package/dist/_dts/blocks/src/system/fields/gridLayout.d.ts +20 -0
  88. package/dist/_dts/blocks/src/system/node/fragments/classNameBinding.d.ts +6 -1
  89. package/dist/_dts/blocks/src/system/node/fragments/styledCard.d.ts +31 -0
  90. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
  91. package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +4 -0
  92. package/dist/_dts/blocks/src/system/runtime/api/types/courses.d.ts +0 -1
  93. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +0 -1
  94. package/dist/_dts/blocks/src/system/runtime/blockComposition.d.ts +1 -1
  95. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +45 -72
  96. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +21 -36
  97. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.state.d.ts +4 -2
  98. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessWholeSeriesRegistrationFlow.d.ts +6 -6
  99. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +24 -8
  100. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.server.d.ts +8 -0
  101. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.validationErrors.d.ts +17 -0
  102. package/dist/_dts/blocks/src/system/runtime/nodes/course-page-surface-scope.d.ts +2 -5
  103. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.client.d.ts +4 -2
  104. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration.interactive.d.ts +19 -7
  105. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +25 -4
  106. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/presentation.d.ts +75 -0
  107. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/view.d.ts +4 -1
  108. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.client.d.ts +5 -2
  109. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.server.d.ts +5 -2
  110. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/PaymentSelectionStep.d.ts +4 -0
  111. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/RegistrationClosedState.d.ts +5 -0
  112. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SiteCreditPreviewPanel.d.ts +6 -0
  113. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.d.ts +1 -1
  114. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.d.ts +2 -0
  115. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventScope.d.ts +1 -1
  116. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/hooks.d.ts +17 -0
  117. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/registrationSurface.d.ts +3 -3
  118. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/siteCreditPreview.d.ts +51 -0
  119. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +3 -3
  120. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +2 -0
  121. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/BookingModeStep.d.ts +1 -1
  122. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/CheckIcon.d.ts +1 -1
  123. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/ErrorStep.d.ts +1 -1
  124. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/MembershipHero.d.ts +3 -3
  125. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/PaymentFailedStep.d.ts +1 -1
  126. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/StepIndicator.d.ts +6 -0
  127. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/VerifyingTimeoutStep.d.ts +1 -1
  128. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WholeSeriesRegistrationActiveSteps.d.ts +9 -0
  129. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration/CourseRegistrationErrorBoundary.d.ts → event-registration/whole-series/WholeSeriesRegistrationErrorBoundary.d.ts} +5 -2
  130. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WholeSeriesRegistrationTerminalContent.d.ts +8 -0
  131. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/WholeSeriesRegistrationWizard.d.ts +8 -0
  132. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/components.d.ts +45 -0
  133. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/index.d.ts +4 -4
  134. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/presentation.d.ts +7 -0
  135. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/pricing.d.ts +14 -0
  136. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/types.d.ts +18 -16
  137. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration/useCourseEligibility.d.ts → event-registration/whole-series/useWholeSeriesEligibility.d.ts} +6 -6
  138. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesPaymentVerification.d.ts +10 -0
  139. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationActions.d.ts +35 -0
  140. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration/useCourseRegistrationPortal.d.ts → event-registration/whole-series/useWholeSeriesRegistrationPortal.d.ts} +2 -2
  141. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationSelection.d.ts +35 -0
  142. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationWizard.d.ts +185 -0
  143. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration/useCourseWaitlistSelection.d.ts → event-registration/whole-series/useWholeSeriesWaitlistSelection.d.ts} +5 -5
  144. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/utils.d.ts +4 -4
  145. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/whole-series-registration.headless.contract.d.ts +5 -7
  146. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/whole-series-registration.headless.planning.d.ts +2 -2
  147. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/whole-series/wholeSeriesPageSurfaceScope.d.ts +17 -0
  148. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration/courseRegistrationViewState.d.ts → event-registration/whole-series/wholeSeriesRegistrationViewState.d.ts} +7 -7
  149. package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/wizardSteps.d.ts +4 -4
  150. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +24 -54
  151. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +1 -1
  152. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +2 -0
  153. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +3 -0
  154. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.interactive.d.ts +12 -11
  155. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventListing.server.d.ts +3 -2
  156. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventSpotlight.d.ts +3 -2
  157. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventCard.d.ts +3 -2
  158. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventDetailModal.d.ts +4 -3
  159. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventModalCloseButton.d.ts +7 -0
  160. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventModals.d.ts +4 -3
  161. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +14 -0
  162. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +59 -2
  163. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +4 -1
  164. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.d.ts +1 -1
  165. package/dist/_dts/blocks/src/system/runtime/shared/components/DiscountCodeDisclosure.d.ts +12 -12
  166. package/dist/_dts/blocks/src/system/runtime/shared/components/FeedbackMessage.d.ts +17 -1
  167. package/dist/_dts/blocks/src/system/runtime/shared/components/index.d.ts +1 -1
  168. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.d.ts +1 -0
  169. package/dist/_dts/blocks/src/system/spacing.d.ts +1 -1
  170. package/dist/_dts/blocks/src/system/transforms/registry/_utils/boxStyleClassNames.d.ts +109 -0
  171. package/dist/_dts/blocks/src/system/transforms/registry/_utils/surfaceForegroundStyles.d.ts +4 -0
  172. package/dist/_dts/blocks/src/system/transforms/registry/boxStyles.d.ts +40 -3
  173. package/dist/_dts/blocks/src/system/transforms/registry/index.d.ts +1 -0
  174. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +4 -37
  175. package/dist/_dts/blocks/src/system/transforms/typed.d.ts +1 -4
  176. package/dist/_dts/commerce/src/purchase/bookingInstalmentSchedule.d.ts +13 -0
  177. package/dist/_dts/commerce/src/purchase/cancellationPolicy.d.ts +7 -0
  178. package/dist/_dts/commerce/src/purchase/canonicalRefundPlanner.d.ts +48 -0
  179. package/dist/_dts/commerce/src/purchase/checkoutCollectionPlan.d.ts +39 -0
  180. package/dist/_dts/commerce/src/purchase/checkoutCommitPlan.d.ts +40 -0
  181. package/dist/_dts/commerce/src/purchase/checkoutDiscountContextPlanning.d.ts +80 -0
  182. package/dist/_dts/commerce/src/purchase/checkoutErrorCodes.d.ts +1 -0
  183. package/dist/_dts/commerce/src/purchase/checkoutOrderItemProjection.d.ts +22 -0
  184. package/dist/_dts/commerce/src/purchase/checkoutPaymentFlow.d.ts +50 -0
  185. package/dist/_dts/commerce/src/purchase/checkoutPaymentPlanPlanning.d.ts +30 -0
  186. package/dist/_dts/commerce/src/purchase/checkoutPaymentTermPlanning.d.ts +10 -0
  187. package/dist/_dts/commerce/src/purchase/checkoutPaymentTerms.d.ts +53 -0
  188. package/dist/_dts/commerce/src/purchase/checkoutQuantity.d.ts +8 -0
  189. package/dist/_dts/commerce/src/purchase/checkoutSessionMetadata.d.ts +76 -0
  190. package/dist/_dts/commerce/src/purchase/checkoutSettlement.d.ts +46 -0
  191. package/dist/_dts/commerce/src/purchase/checkoutStripeFinalizationPlanning.d.ts +12 -0
  192. package/dist/_dts/commerce/src/purchase/checkoutStripeSessionPlanning.d.ts +125 -0
  193. package/dist/_dts/commerce/src/purchase/checkoutValidatedItemPlanning.d.ts +55 -0
  194. package/dist/_dts/commerce/src/purchase/confirmationEmailPayment.d.ts +91 -0
  195. package/dist/_dts/commerce/src/purchase/discountApplication.d.ts +74 -0
  196. package/dist/_dts/commerce/src/purchase/index.d.ts +55 -0
  197. package/dist/_dts/commerce/src/purchase/oneTimeCheckoutPlanning.d.ts +86 -0
  198. package/dist/_dts/commerce/src/purchase/order-number.d.ts +33 -0
  199. package/dist/_dts/commerce/src/purchase/orderCancellationPlan.d.ts +19 -0
  200. package/dist/_dts/commerce/src/purchase/orderCompletionEmailPlan.d.ts +71 -0
  201. package/dist/_dts/commerce/src/purchase/orderConfirmationPlanning.d.ts +120 -0
  202. package/dist/_dts/commerce/src/purchase/orderFulfillmentPlan.d.ts +81 -0
  203. package/dist/_dts/commerce/src/purchase/orderFulfillmentResult.d.ts +8 -0
  204. package/dist/_dts/commerce/src/purchase/orderHistoryLedgerFilters.d.ts +1 -0
  205. package/dist/_dts/commerce/src/purchase/orderHistorySource.d.ts +11 -0
  206. package/dist/_dts/commerce/src/purchase/orderInstalmentAdminSettlement.d.ts +43 -0
  207. package/dist/_dts/commerce/src/purchase/orderInstalmentClosure.d.ts +29 -0
  208. package/dist/_dts/commerce/src/purchase/orderInstalmentLifecycle.d.ts +44 -0
  209. package/dist/_dts/commerce/src/purchase/orderInstalmentPayoff.d.ts +24 -0
  210. package/dist/_dts/commerce/src/purchase/orderInstalmentPlan.d.ts +40 -0
  211. package/dist/_dts/commerce/src/purchase/orderItemMetadata.d.ts +151 -0
  212. package/dist/_dts/commerce/src/purchase/orderItemSupport.d.ts +14 -0
  213. package/dist/_dts/commerce/src/purchase/orderListFilters.d.ts +3 -0
  214. package/dist/_dts/commerce/src/purchase/orderPaymentLinkPlanning.d.ts +60 -0
  215. package/dist/_dts/commerce/src/purchase/orderPaymentReceipt.d.ts +184 -0
  216. package/dist/_dts/commerce/src/purchase/orderPaymentState.d.ts +135 -0
  217. package/dist/_dts/commerce/src/purchase/orderPlanningTypes.d.ts +102 -0
  218. package/dist/_dts/commerce/src/purchase/orderRefundPlanning.d.ts +50 -0
  219. package/dist/_dts/commerce/src/purchase/orderRefundPolicy.d.ts +36 -0
  220. package/dist/_dts/commerce/src/purchase/orderTotals.d.ts +23 -0
  221. package/dist/_dts/commerce/src/purchase/orderTypes.d.ts +39 -0
  222. package/dist/_dts/commerce/src/purchase/pendingCheckoutSessionClaim.d.ts +1 -0
  223. package/dist/_dts/commerce/src/purchase/persistedCheckoutLines.d.ts +27 -0
  224. package/dist/_dts/commerce/src/purchase/protectedDepositRefundPolicy.d.ts +86 -0
  225. package/dist/_dts/commerce/src/purchase/refundPolicy.d.ts +8 -0
  226. package/dist/_dts/commerce/src/purchase/refundRailSplit.d.ts +40 -0
  227. package/dist/_dts/commerce/src/purchase/result.d.ts +2 -0
  228. package/dist/_dts/commerce/src/purchase/settlement.d.ts +97 -0
  229. package/dist/_dts/commerce/src/purchase/shopRefundPlanning.d.ts +43 -0
  230. package/dist/_dts/commerce/src/purchase/stateTransitions.d.ts +31 -0
  231. package/dist/_dts/commerce/src/purchase/stripeMinimumCharge.d.ts +10 -0
  232. package/dist/_dts/commerce/src/purchase/types.d.ts +168 -0
  233. package/dist/_dts/commerce/src/shop/shipmentEligibility.d.ts +14 -0
  234. package/dist/_dts/commerce/src/utils/assertNever.d.ts +1 -0
  235. package/dist/_dts/content-editor/src/components/ContentFieldsForm.d.ts +2 -2
  236. package/dist/_dts/content-model/src/content-types/builtin-schemas.d.ts +10 -6
  237. package/dist/_dts/content-model/src/content-types/builtins.d.ts +10 -6
  238. package/dist/_dts/core/src/booking-vertical-catalog.d.ts +741 -0
  239. package/dist/_dts/core/src/booking-vertical-config.d.ts +66 -0
  240. package/dist/_dts/core/src/booking-vertical-definitions.d.ts +68 -0
  241. package/dist/_dts/{api/src/bookingVerticalPreset.d.ts → core/src/booking-vertical-preset.d.ts} +1 -1
  242. package/dist/_dts/core/src/booking-verticals.d.ts +98 -0
  243. package/dist/_dts/core/src/branded.d.ts +4 -0
  244. package/dist/_dts/core/src/event-page-selection.d.ts +22 -0
  245. package/dist/_dts/core/src/event-page-surface-subject.d.ts +25 -4
  246. package/dist/_dts/core/src/event-pricing.d.ts +5 -0
  247. package/dist/_dts/core/src/event-series-behaviour.d.ts +16 -0
  248. package/dist/_dts/core/src/index.d.ts +6 -0
  249. package/dist/_dts/core/src/public-event-booking-availability.d.ts +8 -0
  250. package/dist/_dts/core/src/secret.d.ts +44 -0
  251. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +413 -0
  252. package/dist/_dts/db/src/schemas/forms.d.ts +4 -4
  253. package/dist/_dts/editor-blocks/src/BlockEditor.d.ts +2 -1
  254. package/dist/_dts/editor-blocks/src/BlockForm.d.ts +2 -2
  255. package/dist/_dts/editor-blocks/src/block-editor/BlockCard.d.ts +2 -2
  256. package/dist/_dts/editor-blocks/src/block-editor/BlockCardBody.d.ts +1 -1
  257. package/dist/_dts/editor-blocks/src/block-editor/BlockCardHeader.d.ts +1 -1
  258. package/dist/_dts/editor-blocks/src/block-editor/SortableBlockItem.d.ts +1 -1
  259. package/dist/_dts/editor-blocks/src/block-editor/hooks/useBlockValidationManifests.d.ts +1 -1
  260. package/dist/_dts/editor-blocks/src/block-editor/preparedManifest.d.ts +1 -1
  261. package/dist/_dts/editor-blocks/src/blockPayload.d.ts +1 -1
  262. package/dist/_dts/editor-blocks/src/index.d.ts +2 -2
  263. package/dist/_dts/editor-blocks/src/media/MediaField.d.ts +2 -2
  264. package/dist/_dts/editor-blocks/src/widgets/button/ButtonField.d.ts +1 -1
  265. package/dist/_dts/editor-blocks/src/widgets/button/ButtonVariantField.d.ts +1 -1
  266. package/dist/_dts/editor-blocks/src/widgets/button/index.d.ts +1 -1
  267. package/dist/_dts/editor-blocks/src/widgets/content-type-select/ContentTypeSelectField.d.ts +1 -1
  268. package/dist/_dts/editor-blocks/src/widgets/entry-picker/EntryPickerField.d.ts +1 -1
  269. package/dist/_dts/editor-blocks/src/widgets/entry-picker/index.d.ts +1 -1
  270. package/dist/_dts/editor-blocks/src/widgets/icon-picker/IconPickerField.d.ts +1 -1
  271. package/dist/_dts/editor-blocks/src/widgets/inline-text/InlineTextField.d.ts +1 -1
  272. package/dist/_dts/editor-blocks/src/widgets/link/LinkField.d.ts +2 -2
  273. package/dist/_dts/editor-blocks/src/widgets/offerings-preview/OfferingsPreviewGroupOrderField.d.ts +1 -1
  274. package/dist/_dts/editor-blocks/src/widgets/reference/ReferenceField.d.ts +2 -2
  275. package/dist/_dts/editor-blocks/src/widgets/rich-text/RichTextField.d.ts +2 -2
  276. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/SiteOptionPickerField.d.ts +1 -1
  277. package/dist/_dts/editor-blocks/src/widgets/site-option-picker/utils.d.ts +1 -1
  278. package/dist/_dts/media-core/src/fileUploadCompletion.d.ts +3 -0
  279. package/dist/_dts/media-core/src/fileUploadDurableFinalization.d.ts +2 -0
  280. package/dist/_dts/media-core/src/identifiers.d.ts +10 -0
  281. package/dist/_dts/media-core/src/mediaWriteNormalizer.d.ts +2 -6
  282. package/dist/_dts/media-core/src/types.d.ts +2 -1
  283. package/dist/_dts/media-editor/src/index.d.ts +2 -2
  284. package/dist/_dts/media-editor/src/mediaSelection.d.ts +1 -22
  285. package/dist/_dts/media-editor/src/useMediaSelection.d.ts +0 -9
  286. package/dist/_dts/preview-next/src/client/blocks/useBlockCustomizeControls.d.ts +1 -1
  287. package/dist/_dts/preview-next/src/client/preview/ButtonHoverRoleControls.d.ts +10 -0
  288. package/dist/_dts/preview-next/src/client/preview/ButtonStylePicker.d.ts +3 -2
  289. package/dist/_dts/preview-next/src/client/preview/EntryEditorPanel.d.ts +1 -1
  290. package/dist/_dts/preview-next/src/client/preview/EntrySlotBlockEditorPanel.d.ts +1 -1
  291. package/dist/_dts/preview-next/src/client/preview/PreviewEditorSidebar.d.ts +3 -1
  292. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +4 -1
  293. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +2 -1
  294. package/dist/_dts/preview-next/src/client/preview/PreviewSiteFontStorageContext.d.ts +6 -0
  295. package/dist/_dts/preview-next/src/client/preview/StyleConfigurator.d.ts +3 -1
  296. package/dist/_dts/preview-next/src/client/preview/StyleConfiguratorWarningNotice.d.ts +7 -0
  297. package/dist/_dts/preview-next/src/client/preview/siteFontPreview.d.ts +5 -0
  298. package/dist/_dts/preview-next/src/client/preview/siteStylePreviewPlanner.d.ts +1 -1
  299. package/dist/_dts/preview-next/src/client/sdk/contentStorage.d.ts +10 -0
  300. package/dist/_dts/preview-next/src/client/widgets/widgetOverrides.d.ts +1 -1
  301. package/dist/_dts/preview-next/src/index.d.ts +1 -0
  302. package/dist/_dts/preview-next/src/keepAlive.d.ts +3 -5
  303. package/dist/_dts/preview-next/src/refresh-contract.d.ts +1 -0
  304. package/dist/_dts/preview-next/src/route-contract.d.ts +7 -0
  305. package/dist/_dts/sdk/src/client/eventSubrouteReadOperations.d.ts +11 -0
  306. package/dist/_dts/sdk/src/client/types.d.ts +12 -5
  307. package/dist/_dts/sdk/src/components.d.ts +1 -1
  308. package/dist/_dts/sdk/src/contracts/index.d.ts +1 -1
  309. package/dist/_dts/sdk/src/contracts/page.d.ts +2 -13
  310. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +64 -54
  311. package/dist/_dts/sdk/src/next/pageMetadataProjection.d.ts +7 -0
  312. package/dist/_dts/sdk/src/next/resolveEventPageSubroute.d.ts +12 -0
  313. package/dist/_dts/sdk/src/preview-next/keep-alive.d.ts +1 -1
  314. package/dist/_dts/sdk/src/public-api/contracts.d.ts +5 -19
  315. package/dist/_dts/sdk/src/public-api/eventSubrouteContracts.d.ts +12 -0
  316. package/dist/_dts/sdk/src/public-api/runtime.d.ts +1 -1
  317. package/dist/_dts/sdk/src/rendering/client.d.ts +44 -0
  318. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +1 -1
  319. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -1
  320. package/dist/_dts/sdk/src/rendering/islands/types.d.ts +9 -1
  321. package/dist/_dts/sdk/src/routing/entrySubroutes.d.ts +1 -1
  322. package/dist/_dts/sdk/src/routing/resolveOccurrence.d.ts +4 -3
  323. package/dist/_dts/sdk/src/routing/resolvePageContent.d.ts +7 -3
  324. package/dist/_dts/sdk/src/theme-bridge/types.d.ts +4 -2
  325. package/dist/_dts/sdk/src/version.d.ts +1 -1
  326. package/dist/_dts/theme-core/src/buttons/buttonSurfaceContext.d.ts +1 -1
  327. package/dist/_dts/theme-core/src/buttons/contextualHover.d.ts +41 -0
  328. package/dist/_dts/theme-core/src/buttons/index.d.ts +1 -0
  329. package/dist/_dts/theme-core/src/buttons/resolveButtonColourStates.d.ts +3 -0
  330. package/dist/_dts/theme-core/src/buttons/resolveButtonHoverTreatment.d.ts +14 -0
  331. package/dist/_dts/theme-core/src/buttons/styles/domain.d.ts +21 -4
  332. package/dist/_dts/theme-core/src/buttons/styles/recipes/flatInk.d.ts +92 -0
  333. package/dist/_dts/theme-core/src/buttons/styles/recipes/staticRecipes.d.ts +10 -150
  334. package/dist/_dts/theme-core/src/buttons/styles/registry.d.ts +57 -102
  335. package/dist/_dts/theme-core/src/buttons/styles/selection.d.ts +50 -2
  336. package/dist/_dts/theme-core/src/buttons/types.d.ts +29 -0
  337. package/dist/_dts/theme-core/src/cards/core.d.ts +54 -10
  338. package/dist/_dts/theme-core/src/cards/decorations.d.ts +33 -0
  339. package/dist/_dts/theme-core/src/cards/generateDefaultCardSystem.d.ts +7 -2
  340. package/dist/_dts/theme-core/src/cards/index.d.ts +3 -0
  341. package/dist/_dts/theme-core/src/cards/openCardVariant.d.ts +24 -0
  342. package/dist/_dts/theme-core/src/cards/roles.d.ts +38 -0
  343. package/dist/_dts/theme-core/src/cards/siteStyleDefaults.d.ts +53 -8
  344. package/dist/_dts/theme-core/src/cards/types.d.ts +474 -28
  345. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  346. package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +59 -0
  347. package/dist/_dts/theme-core/src/header/paintTargets.d.ts +2 -2
  348. package/dist/_dts/theme-core/src/header/scrollTreatment.d.ts +3 -2
  349. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +30 -138
  350. package/dist/_dts/theme-core/src/palette/utils/contrast.d.ts +1 -0
  351. package/dist/_dts/theme-core/src/palette/utils/opaqueSurfaceColor.d.ts +6 -0
  352. package/dist/_dts/theme-core/src/runtime/buildThemeRuntimeFromBridge.d.ts +1 -1
  353. package/dist/_dts/theme-core/src/schema.d.ts +302 -107
  354. package/dist/_dts/theme-core/src/site-styles/appearancePresetCatalog.d.ts +111 -102
  355. package/dist/_dts/theme-core/src/site-styles/appearancePresetResolution.d.ts +12 -1
  356. package/dist/_dts/theme-core/src/site-styles/appearancePresetTypes.d.ts +9 -4
  357. package/dist/_dts/theme-core/src/site-styles/backgroundAppearance.d.ts +0 -20
  358. package/dist/_dts/theme-core/src/site-styles/blockAppearancePresets.d.ts +111 -102
  359. package/dist/_dts/theme-core/src/site-styles/buttonSelectionCompiler.d.ts +18 -0
  360. package/dist/_dts/theme-core/src/site-styles/cardRoleVocabulary.d.ts +48 -0
  361. package/dist/_dts/theme-core/src/site-styles/compilationPlan.d.ts +21 -0
  362. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +21 -385
  363. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +10 -18
  364. package/dist/_dts/theme-core/src/site-styles/headerLayoutTypes.d.ts +2 -4
  365. package/dist/_dts/theme-core/src/site-styles/headerOpeningForeground.d.ts +2 -9
  366. package/dist/_dts/theme-core/src/site-styles/headerOpeningSection.d.ts +0 -2
  367. package/dist/_dts/theme-core/src/site-styles/index.d.ts +5 -0
  368. package/dist/_dts/theme-core/src/site-styles/pageDesignAppearanceAvailability.d.ts +3 -0
  369. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorCapabilities.d.ts +22 -0
  370. package/dist/_dts/theme-core/src/site-styles/pageDesignEditorModel.d.ts +9 -8
  371. package/dist/_dts/theme-core/src/site-styles/pageDesignIntentEquality.d.ts +3 -0
  372. package/dist/_dts/theme-core/src/site-styles/previewCompiler.d.ts +2 -11
  373. package/dist/_dts/theme-core/src/site-styles/previewRuntimeCapabilities.d.ts +19 -0
  374. package/dist/_dts/theme-core/src/site-styles/runtimeBackgroundResolution.d.ts +9 -0
  375. package/dist/_dts/theme-core/src/site-styles/runtimeCompiler.d.ts +1 -62
  376. package/dist/_dts/theme-core/src/site-styles/selectionFallbackWarning.d.ts +15 -0
  377. package/dist/_dts/theme-core/src/site-styles/sourceCatalogs.d.ts +13 -12
  378. package/dist/_dts/theme-core/src/site-styles/types.d.ts +62 -39
  379. package/dist/_dts/theme-core/src/siteChromePlanning.d.ts +9 -9
  380. package/dist/_dts/theme-core/src/status/generateStatusCss.d.ts +1 -0
  381. package/dist/_dts/theme-core/src/surfaces/index.d.ts +1 -0
  382. package/dist/_dts/theme-core/src/surfaces/resolveSurfaceForeground.d.ts +39 -0
  383. package/dist/_dts/ui/src/navigation-tabs.d.ts +5 -2
  384. package/dist/client/{DiscountCodeDisclosure-Ur-Xx1U_.mjs → DiscountCodeDisclosure-DO7llLxm.mjs} +12 -12
  385. package/dist/client/{EventCombined.client-EhscD4U6.mjs → EventCombined.client-xID7zN__.mjs} +38 -50
  386. package/dist/client/{EventListing.client-Bn26cFTY.mjs → EventListing.client-CriBslp0.mjs} +2 -2
  387. package/dist/client/{FeedbackMessage-ByMrs3cr.mjs → FeedbackMessage-CtLvvS_d.mjs} +15 -3
  388. package/dist/client/{LeafletStaticMap-BUw9Ntzr.mjs → LeafletStaticMap-DYmHnM8g.mjs} +1 -1
  389. package/dist/client/{StepIndicator-BfbdiVQI.mjs → StepIndicator-CGixP_LW.mjs} +3 -3
  390. package/dist/client/{CourseRegistrationWizard-Bvtz9G9g.mjs → WholeSeriesRegistrationWizard-BEjzSiOA.mjs} +1410 -1247
  391. package/dist/client/{accordion-CjIeof73.mjs → accordion-CgFbnnnQ.mjs} +1 -1
  392. package/dist/client/{bookingForm-DwEeovf_.mjs → bookingForm-dUyGpbxc.mjs} +56 -39
  393. package/dist/client/bookings.mjs +1096 -731
  394. package/dist/client/{carousel-BMrfgOba.mjs → carousel-BvBwkUzx.mjs} +2 -2
  395. package/dist/client/{carousel.client-CpwTUhIo.mjs → carousel.client-59G_WMr4.mjs} +1 -1
  396. package/dist/client/{cart-rXEdxTdb.mjs → cart-DiZENT2E.mjs} +3 -3
  397. package/dist/client/{checkout-D3JlSzh3.mjs → checkout-Dq13KIgR.mjs} +3 -3
  398. package/dist/client/client.mjs +10645 -6794
  399. package/dist/client/{colorStyles-BWpj_h4C.mjs → colorStyles-CrxJrPjJ.mjs} +277 -1
  400. package/dist/client/{context-CJz1Vlsz.mjs → context-B83PiNzm.mjs} +6 -21
  401. package/dist/client/{courseRegistration-DO5XvMAA.mjs → courseRegistration-CKC5NmyH.mjs} +11 -5
  402. package/dist/client/{eventCalendar-DO6rTqCn.mjs → eventCalendar-BF0Jatfw.mjs} +42 -45
  403. package/dist/client/{eventCombined-bJ3i_ovU.mjs → eventCombined-BuoCF8je.mjs} +3 -3
  404. package/dist/client/{eventDetails-CCbrXE7o.mjs → eventDetails-CKwh0S9s.mjs} +276 -94
  405. package/dist/client/{eventListing-Bdlt9YTm.mjs → eventListing-eUxaWFaB.mjs} +3 -3
  406. package/dist/client/{eventRegistration-B02lt6iY.mjs → eventRegistration-CfkNOkPb.mjs} +630 -138
  407. package/dist/client/{form-DrUBAAox.mjs → form-C17H1c_H.mjs} +4 -4
  408. package/dist/client/{headerSection-MzqvHL6T.mjs → headerSection-DEwUmrtt.mjs} +2 -2
  409. package/dist/client/hooks.mjs +3224 -2485
  410. package/dist/client/{locationMap-DG8BxTBm.mjs → locationMap-Pf2QwuvW.mjs} +3 -3
  411. package/dist/client/{media-CNE1Z-wb.mjs → media-BOHuueS5.mjs} +16 -4
  412. package/dist/client/{newsletterForm-BzO-Td3p.mjs → newsletterForm-BWQAH5Sv.mjs} +4 -4
  413. package/dist/client/pricing-CVdvbopJ.mjs +195 -0
  414. package/dist/client/{productDetail-CfQ7rhVK.mjs → productDetail-BZi1Fa_G.mjs} +3 -3
  415. package/dist/client/{productList-C23rOLUi.mjs → productList-qq-55DNk.mjs} +3 -3
  416. package/dist/client/{propsDecoder-CAZdhwjs.mjs → propsDecoder-BxmqPKdP.mjs} +859 -650
  417. package/dist/client/rendering/client.mjs +8658 -7862
  418. package/dist/client/rendering/islands.mjs +20 -20
  419. package/dist/client/rendering.mjs +11437 -7446
  420. package/dist/client/{scrollToBlock-DSSqVQr1.mjs → scrollToBlock-B3CcKdtG.mjs} +1 -1
  421. package/dist/client/{shop-BMToKLK7.mjs → shop-DNWJPut5.mjs} +7 -7
  422. package/dist/client/{shop-commerce-DB4JRKmp.mjs → shop-commerce-BhvQCosS.mjs} +8 -8
  423. package/dist/client/{shop-commerce-store-BOqSIOuc.mjs → shop-commerce-store-B04sCNnW.mjs} +1 -1
  424. package/dist/client/{shopShared-B6SK9DZv.mjs → shopShared-DNNgZlmW.mjs} +5 -5
  425. package/dist/client/{useEventFilters-CULOa4nB.mjs → useEventFilters-CUmhE24_.mjs} +329 -84
  426. package/dist/client/{usePolling-BGG_8-jl.mjs → usePolling-M5jG675x.mjs} +3 -3
  427. package/dist/preview-next/before-render.mjs +439 -168
  428. package/dist/preview-next/client/runtime.mjs +4 -4
  429. package/dist/preview-next/keepAlive.mjs +7593 -29
  430. package/dist/preview-next/middleware.mjs +433 -167
  431. package/dist/{previewAuthStore-_GXFRg2W.mjs → previewAuthStore-BFKd4LrN.mjs} +432 -167
  432. package/dist/{sdk-runtime-hhSOMShR.mjs → sdk-runtime-BEXb1wqo.mjs} +2 -2
  433. package/dist/{separator-flRaFc14.mjs → separator-DGMuip1D.mjs} +1 -1
  434. package/dist/server/components.mjs +9596 -6347
  435. package/dist/server/config-validation.mjs +3224 -2486
  436. package/dist/server/config.mjs +3224 -2486
  437. package/dist/server/data.mjs +3224 -2485
  438. package/dist/server/index.mjs +486 -200
  439. package/dist/server/manifest.mjs +0 -1
  440. package/dist/server/next.mjs +10343 -7188
  441. package/dist/server/page-converter.mjs +1828 -2094
  442. package/dist/server/prebuild.mjs +1 -1
  443. package/dist/server/rendering/server.mjs +6750 -4519
  444. package/dist/server/rendering.mjs +9591 -6342
  445. package/dist/server/routing.mjs +3403 -1594
  446. package/dist/server/server.mjs +3274 -2671
  447. package/dist/server/theme-bridge.mjs +2979 -1639
  448. package/dist/server/theme.mjs +590 -176
  449. package/dist/styles/index.css +1896 -1129
  450. package/package.json +3 -2
  451. package/dist/_dts/api/src/bookingVerticalCatalog.d.ts +0 -746
  452. package/dist/_dts/block-form/src/client/blockDraftSaveability.d.ts +0 -1
  453. package/dist/_dts/block-form/src/widgets/index.d.ts +0 -20
  454. package/dist/_dts/blocks/src/system/runtime/api/requestBody.d.ts +0 -7
  455. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/CourseRegistrationWizard.d.ts +0 -3
  456. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/StepIndicator.d.ts +0 -6
  457. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/components.d.ts +0 -45
  458. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/pricing.d.ts +0 -14
  459. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCoursePaymentVerification.d.ts +0 -9
  460. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationActions.d.ts +0 -35
  461. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationSelection.d.ts +0 -31
  462. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +0 -102
  463. package/dist/client/clsx-DgIEfj3H.mjs +0 -16
  464. package/dist/client/eventProductEligibility-AVxyCB1u.mjs +0 -50
  465. package/dist/client/pricing-NgK7ozkg.mjs +0 -174
  466. /package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/PortalAuthSidebar.d.ts +0 -0
  467. /package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/SuccessStep.d.ts +0 -0
  468. /package/dist/_dts/blocks/src/system/runtime/nodes/{course-registration → event-registration/whole-series}/WaitlistStep.d.ts +0 -0
@@ -2465,23 +2465,6 @@ function createDeduplicationCache(options = {}) {
2465
2465
  };
2466
2466
  }
2467
2467
  //#endregion
2468
- //#region ../blocks/src/system/runtime/api/requestBody.ts
2469
- function omitUndefinedOverrides(overrides) {
2470
- return Object.fromEntries(Object.entries(overrides).filter(([, value]) => value !== void 0));
2471
- }
2472
- /**
2473
- * Forward a typed request body unchanged, then apply a small set of explicit overrides.
2474
- *
2475
- * Undefined override values are stripped before merging so callers do not accidentally
2476
- * clobber an existing field when they mean "no override".
2477
- */
2478
- function withRequestOverrides(body, overrides) {
2479
- return {
2480
- ...body,
2481
- ...omitUndefinedOverrides(overrides)
2482
- };
2483
- }
2484
- //#endregion
2485
2468
  //#region ../blocks/src/system/runtime/api/endpoints.ts
2486
2469
  /**
2487
2470
  * Build endpoint path with parameter substitution
@@ -2567,7 +2550,8 @@ const EVENTS = {
2567
2550
  register: {
2568
2551
  path: "/public/sites/{siteId}/events/register",
2569
2552
  method: "POST",
2570
- authScope: "portal"
2553
+ authScope: "portal",
2554
+ skipPreviewStage: true
2571
2555
  },
2572
2556
  checkout: {
2573
2557
  path: "/public/sites/{siteId}/events/checkout",
@@ -2591,7 +2575,8 @@ const WHOLE_SERIES = {
2591
2575
  enroll: {
2592
2576
  path: "/public/sites/{siteId}/dated-offerings/whole-series/enroll",
2593
2577
  method: "POST",
2594
- authScope: "portal"
2578
+ authScope: "portal",
2579
+ skipPreviewStage: true
2595
2580
  },
2596
2581
  checkout: {
2597
2582
  path: "/public/sites/{siteId}/dated-offerings/whole-series/checkout",
@@ -3169,7 +3154,7 @@ function createBlockApi(config) {
3169
3154
  const path = buildPath(EVENTS.register.path, { siteId: sid });
3170
3155
  return request(EVENTS.register, {
3171
3156
  path,
3172
- body: withRequestOverrides(data, shouldUsePreviewStageForNonPortalRequests ? { stage: "preview" } : {})
3157
+ body: data
3173
3158
  });
3174
3159
  },
3175
3160
  async createEventCheckout(data) {
@@ -3202,7 +3187,7 @@ function createBlockApi(config) {
3202
3187
  const path = buildPath(WHOLE_SERIES.enroll.path, { siteId: sid });
3203
3188
  return request(WHOLE_SERIES.enroll, {
3204
3189
  path,
3205
- body: withRequestOverrides(data, shouldUsePreviewStageForNonPortalRequests ? { stage: "preview" } : {})
3190
+ body: data
3206
3191
  });
3207
3192
  },
3208
3193
  async checkWholeSeriesEligibility(data) {
@@ -3833,18 +3818,32 @@ function isFreePublicEventPriceDisplay(display) {
3833
3818
  }
3834
3819
  //#endregion
3835
3820
  //#region ../core/src/event-page-surface-subject.ts
3821
+ function createEventSeriesPageSurfaceSubject(eventSeriesId, bookingScope) {
3822
+ return bookingScope === "whole_series" ? {
3823
+ kind: "eventSeries",
3824
+ eventSeriesId,
3825
+ bookingScope,
3826
+ isWholeSeriesBooking: true
3827
+ } : {
3828
+ kind: "eventSeries",
3829
+ eventSeriesId,
3830
+ bookingScope
3831
+ };
3832
+ }
3836
3833
  function parseEventPageSurfaceSubject(value) {
3837
3834
  if (!isRecord$6(value)) return err$1({ kind: "notObject" });
3838
3835
  switch (value.kind) {
3839
3836
  case "eventSeries": {
3840
3837
  const eventSeriesId = parseEventSeriesId(value.eventSeriesId);
3841
- return eventSeriesId.ok ? ok({
3842
- kind: "eventSeries",
3843
- eventSeriesId: eventSeriesId.value
3844
- }) : err$1({
3838
+ if (!eventSeriesId.ok) return err$1({
3845
3839
  kind: "invalidEventSeriesId",
3846
3840
  error: eventSeriesId.error
3847
3841
  });
3842
+ if (value.bookingScope !== "single_occurrence" && value.bookingScope !== "whole_series") return err$1({
3843
+ kind: "invalidEventSeriesBookingScope",
3844
+ bookingScope: value.bookingScope
3845
+ });
3846
+ return ok(createEventSeriesPageSurfaceSubject(eventSeriesId.value, value.bookingScope));
3848
3847
  }
3849
3848
  case "eventOffering": {
3850
3849
  const eventOfferingId = parseEventOfferingId(value.eventOfferingId);
@@ -5711,8 +5710,12 @@ function formatScheduleDate(isoString, locale) {
5711
5710
  return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(date);
5712
5711
  }
5713
5712
  //#endregion
5714
- //#region ../blocks/src/system/runtime/nodes/booking-form.headless.state.ts
5715
- const unsafeAsBookingFieldId = (id) => id;
5713
+ //#region ../blocks/src/system/runtime/nodes/booking-form.validationErrors.ts
5714
+ function omitRecordKey(record, key) {
5715
+ if (!(key in record)) return record;
5716
+ const { [key]: _removed, ...rest } = record;
5717
+ return rest;
5718
+ }
5716
5719
  function createEmptyBookingValidationErrors() {
5717
5720
  return {
5718
5721
  formError: null,
@@ -5747,6 +5750,9 @@ function clearBookingFieldError(errors, fieldId) {
5747
5750
  fieldErrors: omitRecordKey(errors.fieldErrors, fieldId)
5748
5751
  };
5749
5752
  }
5753
+ //#endregion
5754
+ //#region ../blocks/src/system/runtime/nodes/booking-form.headless.state.ts
5755
+ const unsafeAsBookingFieldId = (id) => id;
5750
5756
  function createInitialBookingFlowReducerState(input) {
5751
5757
  const initialData = input.initialData ?? {};
5752
5758
  return {
@@ -5758,6 +5764,7 @@ function createInitialBookingFlowReducerState(input) {
5758
5764
  selectedSlot: null,
5759
5765
  fieldValues: collectInitialFieldValues(initialData),
5760
5766
  touchedFields: {},
5767
+ attemptedStepIds: {},
5761
5768
  discountCode: toOptionalString(initialData.discountCode) ?? "",
5762
5769
  selectedSlidingAmountInput: toOptionalString(initialData.selectedSlidingAmountInput) ?? "",
5763
5770
  selectedCollectionOptionKind: toSelectedCollectionOptionKind(initialData.selectedCollectionOptionKind),
@@ -5799,6 +5806,25 @@ function toOptionalCustomerPassId(value) {
5799
5806
  function isBookingFieldValue(value) {
5800
5807
  return value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean" || Array.isArray(value) && value.every((item) => typeof item === "string");
5801
5808
  }
5809
+ /**
5810
+ * Send the flow back to the date step when the slot it was holding went away,
5811
+ * leaving a scoped feedback message. A completed booking is left alone.
5812
+ */
5813
+ function applyAvailabilitySelectionInvalidation(state, invalidation) {
5814
+ if (state.phase !== "editing") return state;
5815
+ return {
5816
+ ...state,
5817
+ currentStepId: "datetime-selection",
5818
+ selectedDate: invalidation.kind === "date_unavailable" ? void 0 : state.selectedDate,
5819
+ selectedSlot: null,
5820
+ feedback: {
5821
+ kind: "error",
5822
+ scope: "availability",
5823
+ message: invalidation.message
5824
+ },
5825
+ validationErrors: clearBookingFormError(state.validationErrors)
5826
+ };
5827
+ }
5802
5828
  function bookingFlowReducer(state, event) {
5803
5829
  switch (event.type) {
5804
5830
  case "service-selected": return {
@@ -5847,6 +5873,13 @@ function bookingFlowReducer(state, event) {
5847
5873
  [event.fieldId]: true
5848
5874
  }
5849
5875
  };
5876
+ case "step-advance-attempted": return state.attemptedStepIds[event.stepId] ? state : {
5877
+ ...state,
5878
+ attemptedStepIds: {
5879
+ ...state.attemptedStepIds,
5880
+ [event.stepId]: true
5881
+ }
5882
+ };
5850
5883
  case "payment-option-selected": return {
5851
5884
  ...state,
5852
5885
  selectedCollectionOptionKind: event.kind ?? void 0,
@@ -5893,20 +5926,7 @@ function bookingFlowReducer(state, event) {
5893
5926
  phase: event.feedback.kind === "success" ? "completed" : "editing",
5894
5927
  feedback: event.feedback
5895
5928
  };
5896
- case "availability-selection-invalidated":
5897
- if (state.phase !== "editing") return state;
5898
- return {
5899
- ...state,
5900
- currentStepId: "datetime-selection",
5901
- selectedDate: event.invalidation.kind === "date_unavailable" ? void 0 : state.selectedDate,
5902
- selectedSlot: null,
5903
- feedback: {
5904
- kind: "error",
5905
- scope: "availability",
5906
- message: event.invalidation.message
5907
- },
5908
- validationErrors: clearBookingFormError(state.validationErrors)
5909
- };
5929
+ case "availability-selection-invalidated": return applyAvailabilitySelectionInvalidation(state, event.invalidation);
5910
5930
  case "feedback-cleared": return {
5911
5931
  ...state,
5912
5932
  phase: "editing",
@@ -6137,6 +6157,7 @@ function deriveBookingFlowSteps(input) {
6137
6157
  requiresResourceSelection: input.requiresResourceSelection,
6138
6158
  paymentResolution: stepResolution.paymentResolution
6139
6159
  }));
6160
+ const attemptedStepIds = input.attemptedStepIds ?? {};
6140
6161
  const steps = stepPlan.map((step, index) => {
6141
6162
  const validation = validations.get(step.id) ?? { ok: true };
6142
6163
  const state = index < currentStepIndex ? "complete" : index === currentStepIndex ? "active" : "available";
@@ -6146,7 +6167,7 @@ function deriveBookingFlowSteps(input) {
6146
6167
  state,
6147
6168
  index,
6148
6169
  visibleIndex: index,
6149
- errors: validation.ok ? createEmptyBookingValidationErrors() : validation.errors,
6170
+ errors: validation.ok || !attemptedStepIds[step.id] ? createEmptyBookingValidationErrors() : validation.errors,
6150
6171
  canEnter: index <= currentStepIndex,
6151
6172
  canLeave: validation.ok
6152
6173
  };
@@ -6415,11 +6436,6 @@ function isBlankFieldValue(value) {
6415
6436
  if (Array.isArray(value)) return value.length === 0;
6416
6437
  return false;
6417
6438
  }
6418
- function omitRecordKey(record, key) {
6419
- if (!(key in record)) return record;
6420
- const { [key]: _removed, ...rest } = record;
6421
- return rest;
6422
- }
6423
6439
  function readAppointmentBookingOverrideData(value) {
6424
6440
  if (!isRecord$4(value)) return null;
6425
6441
  const services = normalizeBookingServices(value.services);
@@ -6518,9 +6534,11 @@ function useHeadlessBookingFlow(options) {
6518
6534
  currentStepId: state.currentStepId,
6519
6535
  requiresServiceSelection: options.requiresServiceSelection,
6520
6536
  requiresResourceSelection: options.requiresResourceSelection,
6521
- enableAppointmentPackages: options.enableAppointmentPackages
6537
+ enableAppointmentPackages: options.enableAppointmentPackages,
6538
+ attemptedStepIds: state.attemptedStepIds
6522
6539
  }), [
6523
6540
  data,
6541
+ state.attemptedStepIds,
6524
6542
  defaultServiceId,
6525
6543
  defaultResourceId,
6526
6544
  options.enableAppointmentPackages,
@@ -6872,6 +6890,10 @@ function useHeadlessBookingFlow(options) {
6872
6890
  if (!latest.currentStep) return { ok: true };
6873
6891
  const validation = latest.validations.get(latest.currentStep.id) ?? { ok: true };
6874
6892
  if (!validation.ok) {
6893
+ dispatch({
6894
+ type: "step-advance-attempted",
6895
+ stepId: latest.currentStep.id
6896
+ });
6875
6897
  dispatch({
6876
6898
  type: "validation-errors-set",
6877
6899
  errors: validation.errors
@@ -7508,6 +7530,12 @@ const opaqueButtonColourTokenSchema = themeColorTokenSchema.refine((value) => pa
7508
7530
  if (token === null) throw new Error("Invariant: opaque button token passed its schema");
7509
7531
  return token;
7510
7532
  });
7533
+ const contextualButtonHoverSchema = z.strictObject({
7534
+ kind: z.literal("shade-shift"),
7535
+ seedToken: opaqueButtonColourTokenSchema,
7536
+ fallbackDirection: z.enum(["lighter", "darker"]),
7537
+ preferredToken: opaqueButtonColourTokenSchema.optional()
7538
+ });
7511
7539
  const buttonShadeAmountSchema = z.number().finite().min(0).max(900).multipleOf(100);
7512
7540
  const buttonShadowIntensitySchema = z.enum([
7513
7541
  "subtle",
@@ -7847,6 +7875,7 @@ const buttonVariantSchema = z.strictObject({
7847
7875
  shadow: variantShadowSchema.optional(),
7848
7876
  border: buttonBorderSchema.optional(),
7849
7877
  hoverBackgroundToken: opaqueButtonColourTokenSchema.optional(),
7878
+ contextualHover: contextualButtonHoverSchema.optional(),
7850
7879
  effects: variantEffectsSchema.optional(),
7851
7880
  sizes: variantSizeOverridesSchema.optional(),
7852
7881
  affordance: buttonVariantAffordanceSchema.optional()
@@ -8125,6 +8154,26 @@ const paletteSchema = z.object({
8125
8154
  //#region ../theme-core/src/cards/types.ts
8126
8155
  const cardVariantRoleValues = ["default", "alternative"];
8127
8156
  const boxlessCardVariantValue = "none";
8157
+ const openCardRoleValue = "open";
8158
+ /**
8159
+ * The roles a site style implements with an actual card variant. `none` is
8160
+ * deliberately absent: it is a role value only, never a variant.
8161
+ */
8162
+ const surfaceCardRoleValues = [...cardVariantRoleValues, openCardRoleValue];
8163
+ /**
8164
+ * The closed role vocabulary Looks and blocks use for surfaced and boxless
8165
+ * card choices.
8166
+ *
8167
+ * - `none` — no site-style card surface; the block's own composition and
8168
+ * the author's own card fields govern the item. This is *not*
8169
+ * a promise of visible boxlessness: a block whose base class
8170
+ * draws a border still draws one. It says the Look is not
8171
+ * asking the site style for a card.
8172
+ * - `open` — boxless but marked (a rule or accent edge, no enclosing box)
8173
+ * - `default` — the site's quiet everyday card
8174
+ * - `alternative` — the statement card carrying the site's personality
8175
+ */
8176
+ const cardRoleValues = [...surfaceCardRoleValues, boxlessCardVariantValue];
8128
8177
  const cardSpacingSchema = z.enum([
8129
8178
  "none",
8130
8179
  "compact",
@@ -8133,6 +8182,17 @@ const cardSpacingSchema = z.enum([
8133
8182
  "comfortable",
8134
8183
  "spacious"
8135
8184
  ]);
8185
+ /** Per-axis padding, for boxless cards whose inline padding differs from block. */
8186
+ const cardSpacingAxesSchema = z.object({
8187
+ block: cardSpacingSchema,
8188
+ inline: cardSpacingSchema
8189
+ });
8190
+ /**
8191
+ * A card's content padding: one value for both axes, or one per axis. Two
8192
+ * fields would let a variant say both and leave the reader to guess, so this is
8193
+ * a union — the legacy `spacingAxes` key is lifted into it on parse.
8194
+ */
8195
+ const cardSpacingValueSchema = z.union([cardSpacingSchema, cardSpacingAxesSchema]);
8136
8196
  const gradientDirectionSchema = z.enum([
8137
8197
  "to-r",
8138
8198
  "to-l",
@@ -8144,7 +8204,21 @@ const gradientDirectionSchema = z.enum([
8144
8204
  "to-bl"
8145
8205
  ]);
8146
8206
  z.enum(cardVariantRoleValues);
8147
- const boxStylesCardVariantSchema = z.enum([...cardVariantRoleValues, boxlessCardVariantValue]);
8207
+ const surfaceCardRoleSchema = z.enum(surfaceCardRoleValues);
8208
+ const cardRoleSchema = z.enum(cardRoleValues);
8209
+ const PRIORITY_ROLE_INFERENCE = {
8210
+ 1: "default",
8211
+ 2: "alternative"
8212
+ };
8213
+ /**
8214
+ * Role inference for legacy card systems authored before variants carried a
8215
+ * `role`. Priority 1 is the everyday card, priority 2 the statement card —
8216
+ * which is how variants are surfaced today. `open` is never inferred: a site
8217
+ * style has to opt into it.
8218
+ */
8219
+ function inferCardVariantRoleFromPriority(priority) {
8220
+ return PRIORITY_ROLE_INFERENCE[priority] ?? null;
8221
+ }
8148
8222
  const cardBackgroundSchema = z.discriminatedUnion("type", [
8149
8223
  z.object({
8150
8224
  type: z.literal("solid"),
@@ -8170,17 +8244,19 @@ const cardCornerValueSchema = z.enum([
8170
8244
  "pill",
8171
8245
  "expressive"
8172
8246
  ]);
8247
+ const cardEdgeSchema = z.enum([
8248
+ "left",
8249
+ "top",
8250
+ "right",
8251
+ "bottom"
8252
+ ]);
8173
8253
  /**
8174
- * A single accented card edge (e.g. a left accent bar). When set, it replaces
8175
- * the full `border` so the card reads as edge-accented rather than outlined.
8254
+ * Legacy single accented card edge (e.g. a left accent bar). Persisted and
8255
+ * curated data may still carry it; it lifts into a one-element `decorations`
8256
+ * list at the parse boundary and has no representation after that.
8176
8257
  */
8177
8258
  const cardAccentEdgeSchema = z.object({
8178
- edge: z.enum([
8179
- "left",
8180
- "top",
8181
- "right",
8182
- "bottom"
8183
- ]),
8259
+ edge: cardEdgeSchema,
8184
8260
  colorToken: themeColorTokenSchema,
8185
8261
  width: z.enum([
8186
8262
  "thin",
@@ -8189,13 +8265,43 @@ const cardAccentEdgeSchema = z.object({
8189
8265
  "heavy"
8190
8266
  ])
8191
8267
  });
8268
+ /** `hairline` (1px) is the widening the boxless `open` role needs. */
8269
+ const cardEdgeRuleWidthSchema = z.enum([
8270
+ "hairline",
8271
+ "thin",
8272
+ "medium",
8273
+ "thick",
8274
+ "heavy"
8275
+ ]);
8276
+ const cardEdgeRuleLengthSchema = z.enum(["full", "short"]);
8277
+ const cardEdgeRuleAlignSchema = z.enum([
8278
+ "start",
8279
+ "center",
8280
+ "end"
8281
+ ]);
8282
+ /**
8283
+ * Decorations are edge rules today. The alias exists so the list can grow into
8284
+ * a discriminated union without every call site changing.
8285
+ */
8286
+ const cardDecorationSchema = z.object({
8287
+ edge: cardEdgeSchema,
8288
+ colorToken: themeColorTokenSchema,
8289
+ width: cardEdgeRuleWidthSchema,
8290
+ /** Defaults to `full`. */
8291
+ length: cardEdgeRuleLengthSchema.optional(),
8292
+ /** Where a `short` rule sits along its edge. Defaults to `start`. */
8293
+ align: cardEdgeRuleAlignSchema.optional(),
8294
+ /** Opacity applied to `colorToken`, 0–1. Scoped here, not on the token. */
8295
+ alpha: z.number().min(0).max(1).optional()
8296
+ });
8297
+ const cardDecorationsSchema = z.array(cardDecorationSchema).max(2);
8192
8298
  const cardCornerRadiiSchema = z.object({
8193
8299
  topLeft: cardCornerValueSchema.optional(),
8194
8300
  topRight: cardCornerValueSchema.optional(),
8195
8301
  bottomLeft: cardCornerValueSchema.optional(),
8196
8302
  bottomRight: cardCornerValueSchema.optional()
8197
8303
  });
8198
- const cardVariantSchema = z.object({
8304
+ const cardVariantInputSchema = z.object({
8199
8305
  id: z.string(),
8200
8306
  name: z.string().min(1).max(20),
8201
8307
  enabled: z.boolean(),
@@ -8204,8 +8310,10 @@ const cardVariantSchema = z.object({
8204
8310
  z.literal(2),
8205
8311
  z.literal(3)
8206
8312
  ]),
8313
+ role: surfaceCardRoleSchema.optional(),
8207
8314
  background: cardBackgroundSchema,
8208
- spacing: cardSpacingSchema,
8315
+ spacing: cardSpacingValueSchema,
8316
+ spacingAxes: cardSpacingAxesSchema.optional(),
8209
8317
  foregroundToken: themeColorTokenSchema.optional(),
8210
8318
  shadow: z.object({
8211
8319
  elevation: z.enum([
@@ -8229,9 +8337,91 @@ const cardVariantSchema = z.object({
8229
8337
  ]).optional(),
8230
8338
  cornerRadii: cardCornerRadiiSchema.optional(),
8231
8339
  border: cardBorderSchema.optional(),
8340
+ decorations: cardDecorationsSchema.optional(),
8232
8341
  accentEdge: cardAccentEdgeSchema.optional()
8233
8342
  });
8234
- const cardSystemSchema = z.object({ variants: z.array(cardVariantSchema).min(1).max(3) });
8343
+ /**
8344
+ * Lift a legacy `accentEdge` into the decoration list. The old emitter reset
8345
+ * `border: 0` implicitly whenever an accent edge was present; conversion drops
8346
+ * the border instead, so the output is unchanged and the data says so.
8347
+ */
8348
+ function normalizeLegacyAccentEdge(variant) {
8349
+ const { accentEdge, ...rest } = normalizeLegacySpacingAxes(variant);
8350
+ if (!accentEdge) return rest;
8351
+ const { border: _droppedByAccentEdgeReset, ...withoutBorder } = rest;
8352
+ return {
8353
+ ...withoutBorder,
8354
+ decorations: [{
8355
+ ...accentEdge,
8356
+ length: "full"
8357
+ }]
8358
+ };
8359
+ }
8360
+ /**
8361
+ * Lift a legacy `spacingAxes` into `spacing`. It always won over the flat value
8362
+ * when both were set, so the lift preserves the emitted padding exactly.
8363
+ */
8364
+ function normalizeLegacySpacingAxes(variant) {
8365
+ const { spacingAxes, ...rest } = variant;
8366
+ return spacingAxes ? {
8367
+ ...rest,
8368
+ spacing: spacingAxes
8369
+ } : variant;
8370
+ }
8371
+ function validateSingleDecorationSource(variant, ctx) {
8372
+ if (!variant.accentEdge || !variant.decorations) return;
8373
+ ctx.addIssue({
8374
+ code: "custom",
8375
+ path: ["decorations"],
8376
+ message: "A card variant carries either the legacy `accentEdge` or `decorations`, never both."
8377
+ });
8378
+ }
8379
+ const cardVariantSchema = cardVariantInputSchema.superRefine(validateSingleDecorationSource).transform(normalizeLegacyAccentEdge);
8380
+ /**
8381
+ * Fill in roles for legacy systems whose variants declare none. Inference is
8382
+ * collision-tolerant on purpose: first claimant wins and a later variant that
8383
+ * would infer a taken role simply gets no role. Legacy data is not obliged to
8384
+ * be well-formed, and a card system that fails to parse takes the whole theme
8385
+ * down with it.
8386
+ */
8387
+ function withInferredRoles(variants) {
8388
+ const claimed = new Set(variants.flatMap((variant) => variant.role ? [variant.role] : []));
8389
+ return variants.map((variant) => {
8390
+ if (variant.role) return variant;
8391
+ const inferred = inferCardVariantRoleFromPriority(variant.priority);
8392
+ if (!inferred || claimed.has(inferred)) return variant;
8393
+ claimed.add(inferred);
8394
+ return {
8395
+ ...variant,
8396
+ role: inferred
8397
+ };
8398
+ });
8399
+ }
8400
+ /**
8401
+ * Only *declared* roles are validated — a site style saying "these two
8402
+ * variants are both the default card" is an authoring error worth rejecting.
8403
+ */
8404
+ function validateUniqueDeclaredCardVariantRoles(system, ctx) {
8405
+ const declared = /* @__PURE__ */ new Set();
8406
+ system.variants.forEach((variant, index) => {
8407
+ const role = variant.role;
8408
+ if (!role) return;
8409
+ if (declared.has(role)) {
8410
+ ctx.addIssue({
8411
+ code: "custom",
8412
+ path: [
8413
+ "variants",
8414
+ index,
8415
+ "role"
8416
+ ],
8417
+ message: `Card role "${role}" is already implemented by another variant.`
8418
+ });
8419
+ return;
8420
+ }
8421
+ declared.add(role);
8422
+ });
8423
+ }
8424
+ const cardSystemSchema = z.object({ variants: z.array(cardVariantSchema).min(1).max(3) }).superRefine(validateUniqueDeclaredCardVariantRoles).transform((system) => ({ variants: withInferredRoles(system.variants) }));
8235
8425
  //#endregion
8236
8426
  //#region ../theme-core/src/accordions/types.ts
8237
8427
  /**
@@ -9052,6 +9242,58 @@ const siteChromeBackgroundOverrideOwner = "site-chrome-editor";
9052
9242
  * palette context and happens in `parseThemeColorReference`.
9053
9243
  */
9054
9244
  const tokenOrCssColorValueSchema = z.string();
9245
+ //#endregion
9246
+ //#region ../theme-core/src/header/legacyHeaderVariant.ts
9247
+ /**
9248
+ * The header variants the system actually renders.
9249
+ *
9250
+ * Each one has a layout row in the site-header block and a paint target in
9251
+ * `paintTargets.ts`. This is the canonical list: the block transform's variant
9252
+ * class allowlist and the AI theme generator's enum both derive from it, so
9253
+ * they cannot drift.
9254
+ */
9255
+ const headerVariantValues = [
9256
+ "classic",
9257
+ "centered",
9258
+ "floating"
9259
+ ];
9260
+ z.enum(headerVariantValues);
9261
+ /**
9262
+ * Header variant spellings that were once authorable but no longer name a
9263
+ * layout of their own, and the variant they read as now.
9264
+ *
9265
+ * `transparent` was an overlay header with no CSS of its own: everything it
9266
+ * did (transparent root background, overlay content flow) is what `floating`
9267
+ * already does, and it had zero persisted usage in production or locally when
9268
+ * it was retired. It survives here as a one-boundary alias so a theme authored
9269
+ * against the old vocabulary still parses.
9270
+ *
9271
+ * This matters because the theme schema is strict and has no per-field
9272
+ * `.catch()`: an out-of-enum variant fails `themeSchema.safeParse` for the
9273
+ * *whole* theme, which silently swaps the site's theme for
9274
+ * `modernMinimalTheme`. Aliasing here keeps that from happening.
9275
+ */
9276
+ const legacyHeaderVariants = { transparent: "floating" };
9277
+ const legacyHeaderVariantValues = Object.keys(legacyHeaderVariants);
9278
+ /**
9279
+ * The header variant boundary for themes that go through `themeSchema`:
9280
+ * canonical variants pass through, legacy spellings normalize to the variant
9281
+ * they meant, everything else fails the parse.
9282
+ *
9283
+ * Deliberately an enum plus a transform rather than a `z.preprocess`, so the
9284
+ * schema's *input* type stays an accurate union (the legacy spelling is still
9285
+ * accepted on the wire) instead of widening to `unknown`. `SdkThemeWire` in
9286
+ * `@riverbankcms/api` is `z.input<typeof themeSchema>`, so a widened input here
9287
+ * would leak straight into a public type.
9288
+ *
9289
+ * Not every read of a persisted theme goes through the schema:
9290
+ * `resolveRuntimeTheme` in
9291
+ * `apps/dashboard/src/server/services/sites/runtimeSiteResponse.ts` returns the
9292
+ * raw database JSON asserted as `Theme` with no parse, so a theme still
9293
+ * carrying a legacy spelling reaches the theme editor un-aliased. That gap
9294
+ * predates this alias and is harmless while persisted usage is zero.
9295
+ */
9296
+ const headerVariantWithLegacyAliasSchema = z.enum([...headerVariantValues, ...legacyHeaderVariantValues]).transform((value) => value in legacyHeaderVariants ? legacyHeaderVariants[value] : value);
9055
9297
  const BREAKPOINT_LG = 1024;
9056
9298
  const BREAKPOINT_XL = 1280;
9057
9299
  const BREAKPOINT_LG_DOWN = BREAKPOINT_LG - 1;
@@ -9368,15 +9610,7 @@ const cardStylesOverrideSchema = z.object({
9368
9610
  spacing: semanticSpacingSchema.nullable().optional(),
9369
9611
  raised: z.boolean().nullable().optional(),
9370
9612
  rounded: boxRoundedSchema.nullable().optional(),
9371
- treatment: z.enum([
9372
- "accent-quote",
9373
- "editorial-rule",
9374
- "soft-panel",
9375
- "editorial-serif-quote",
9376
- "editorial-open",
9377
- "color-blocked"
9378
- ]).nullable().optional(),
9379
- cardVariant: boxStylesCardVariantSchema.nullable().optional()
9613
+ role: cardRoleSchema.nullable().optional()
9380
9614
  });
9381
9615
  const blockStyleOverridesSchema = z.object({
9382
9616
  sectionStyles: sectionStylesOverrideSchema.nullable().optional(),
@@ -9481,30 +9715,6 @@ const motion = z.object({
9481
9715
  ]).nullable()
9482
9716
  });
9483
9717
  z.object({ shape: corners });
9484
- z.object({
9485
- elevation: z.enum([
9486
- "none",
9487
- "low",
9488
- "medium",
9489
- "high"
9490
- ]),
9491
- border: z.enum([
9492
- "none",
9493
- "subtle",
9494
- "defined"
9495
- ]),
9496
- shape: corners,
9497
- headerStyle: z.enum([
9498
- "plain",
9499
- "accentBar",
9500
- "subtleBg"
9501
- ]).nullable(),
9502
- mediaTreatment: z.enum([
9503
- "square",
9504
- "rounded",
9505
- "bleed"
9506
- ]).nullable()
9507
- });
9508
9718
  const inputStyle = z.object({
9509
9719
  shape: corners,
9510
9720
  border: z.enum([
@@ -9519,12 +9729,6 @@ const inputStyle = z.object({
9519
9729
  ]),
9520
9730
  label: z.enum(["inside", "above"])
9521
9731
  });
9522
- const headerVariant = z.enum([
9523
- "classic",
9524
- "centered",
9525
- "transparent",
9526
- "floating"
9527
- ]);
9528
9732
  const headerPositioning = z.enum([
9529
9733
  "static",
9530
9734
  "sticky",
@@ -9668,7 +9872,7 @@ const headerBackgroundSchema = z.object({
9668
9872
  textColor: tokenOrCssColorValueSchema.nullable().optional()
9669
9873
  });
9670
9874
  const headerSchema = z.object({
9671
- variant: headerVariant,
9875
+ variant: headerVariantWithLegacyAliasSchema,
9672
9876
  positioning: headerPositioning,
9673
9877
  shrinkOnScroll: z.boolean(),
9674
9878
  maxWidth: headerMaxWidth,
@@ -10035,13 +10239,7 @@ function shadeBackgroundEffect(config) {
10035
10239
  buttonSizeNameSchema.options;
10036
10240
  //#endregion
10037
10241
  //#region ../theme-core/src/buttons/styles/domain.ts
10038
- const PUBLIC_BUTTON_ROLES = [
10039
- "primary",
10040
- "secondary",
10041
- "outline",
10042
- "ghost",
10043
- "accent"
10044
- ];
10242
+ const PUBLIC_BUTTON_ROLES = VARIANT_ROLES;
10045
10243
  function defineButtonStyleRecipe(recipe) {
10046
10244
  return recipe;
10047
10245
  }
@@ -10137,6 +10335,14 @@ const BUTTON_STYLE_IDS = [
10137
10335
  "quiet-arrow"
10138
10336
  ];
10139
10337
  const quietArrowParametersSchema = z.object({ secondaryTreatment: z.enum(["outlined", "solid-accent"]) }).strict();
10338
+ const flatInkHoverTreatmentSchema = z.enum([
10339
+ "contextual",
10340
+ "secondary",
10341
+ "accent"
10342
+ ]);
10343
+ const flatInkHoverPreferencesShape = Object.fromEntries(VARIANT_ROLES.map((role) => [role, flatInkHoverTreatmentSchema.optional()]));
10344
+ const flatInkHoverPreferencesSchema = z.strictObject(flatInkHoverPreferencesShape);
10345
+ const flatInkParametersSchema = z.strictObject({ hoverPreferences: flatInkHoverPreferencesSchema.optional() });
10140
10346
  const emptyParametersSchema$1 = z.object({}).strict();
10141
10347
  function selectionBranch(styleId, parameters) {
10142
10348
  return z.object({
@@ -10151,7 +10357,7 @@ z.discriminatedUnion("styleId", [
10151
10357
  selectionBranch("editorial-link", emptyParametersSchema$1),
10152
10358
  selectionBranch("pebble", emptyParametersSchema$1),
10153
10359
  selectionBranch("ink-stamp", emptyParametersSchema$1),
10154
- selectionBranch("flat-ink", emptyParametersSchema$1),
10360
+ selectionBranch("flat-ink", flatInkParametersSchema),
10155
10361
  selectionBranch("brushed-wash", emptyParametersSchema$1),
10156
10362
  selectionBranch("showtime-pill", emptyParametersSchema$1),
10157
10363
  selectionBranch("joy-stamp", emptyParametersSchema$1),
@@ -10288,93 +10494,276 @@ const quietArrowRecipe = defineButtonStyleRecipe({
10288
10494
  })
10289
10495
  });
10290
10496
  //#endregion
10291
- //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
10292
- const emptyParametersSchema = z.object({}).strict();
10293
- function defineStaticButtonStyleRecipe(input) {
10294
- const system = normalizeSystem(input.system);
10295
- return defineButtonStyleRecipe({
10296
- id: input.id,
10297
- accessibilityLabel: input.accessibilityLabel,
10298
- tags: input.tags,
10299
- parameterSchema: emptyParametersSchema,
10300
- defaultParameters: {},
10301
- controls: [],
10302
- defineSystem: () => system
10303
- });
10304
- }
10305
- function normalizeSystem(input) {
10306
- return {
10307
- global: buttonGlobalSettingsSchema.parse(input.global),
10308
- ...input.sizes ? { sizes: input.sizes } : {},
10309
- roles: {
10310
- primary: normalizeCompleteRole(input.roles.primary),
10311
- secondary: normalizeCompleteRole(input.roles.secondary),
10312
- outline: normalizeSupportingRole(input.roles.outline),
10313
- ghost: normalizeSupportingRole(input.roles.ghost),
10314
- accent: normalizeSupportingRole(input.roles.accent)
10497
+ //#region ../theme-core/src/buttons/styles/recipes/flatInk.ts
10498
+ const contextualRoleConfig = {
10499
+ primary: {
10500
+ contextualSeedToken: unsafeAsOpaqueButtonColourToken("primary"),
10501
+ fallbackDirection: "darker"
10502
+ },
10503
+ secondary: {
10504
+ contextualSeedToken: unsafeAsOpaqueButtonColourToken("surfaceAlt"),
10505
+ fallbackDirection: "darker"
10506
+ },
10507
+ outline: {
10508
+ contextualSeedToken: unsafeAsOpaqueButtonColourToken("surfaceAlt"),
10509
+ fallbackDirection: "darker"
10510
+ },
10511
+ ghost: {
10512
+ contextualSeedToken: unsafeAsOpaqueButtonColourToken("surfaceAlt"),
10513
+ fallbackDirection: "darker"
10514
+ },
10515
+ accent: {
10516
+ contextualSeedToken: unsafeAsOpaqueButtonColourToken("accent"),
10517
+ fallbackDirection: "darker"
10518
+ }
10519
+ };
10520
+ const hoverControl = {
10521
+ kind: "button-hover-by-role",
10522
+ parameter: "hoverPreferences",
10523
+ label: "Button hover",
10524
+ roles: contextualRoleConfig,
10525
+ options: [
10526
+ {
10527
+ value: "contextual",
10528
+ label: "Contextual shade shift"
10529
+ },
10530
+ {
10531
+ value: "secondary",
10532
+ label: "Secondary button colour"
10533
+ },
10534
+ {
10535
+ value: "accent",
10536
+ label: "Accent button colour"
10315
10537
  }
10316
- };
10317
- }
10318
- function normalizeCompleteRole(role) {
10319
- return {
10320
- kind: "complete",
10321
- appearance: normalizeAppearance(role.appearance)
10322
- };
10323
- }
10324
- function normalizeSupportingRole(role) {
10325
- if (role.kind === "complete") return normalizeCompleteRole(role);
10326
- return {
10327
- kind: "derive",
10328
- from: role.from,
10329
- ...role.overrides ? { overrides: normalizeAppearanceOverrides(role.overrides) } : {}
10330
- };
10331
- }
10332
- function normalizeAppearance(appearance) {
10333
- const { background, hoverBackgroundToken, ...rest } = appearance;
10334
- return {
10335
- ...rest,
10336
- background: buttonColourTreatmentSchema.parse(background),
10337
- ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
10338
- };
10339
- }
10340
- function normalizeAppearanceOverrides(overrides) {
10341
- const { background, hoverBackgroundToken, ...rest } = overrides;
10342
- return {
10343
- ...rest,
10344
- ...background ? { background: buttonColourTreatmentSchema.parse(background) } : {},
10345
- ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
10346
- };
10347
- }
10348
- //#endregion
10349
- //#region ../theme-core/src/buttons/styles/recipes/staticRecipes.ts
10350
- const softPillRecipe = defineStaticButtonStyleRecipe({
10351
- id: "soft-pill",
10352
- accessibilityLabel: "Rounded pill buttons with a gentle hover lift",
10538
+ ]
10539
+ };
10540
+ const lift = { effectId: "lift" };
10541
+ const flatInkRecipe = defineButtonStyleRecipe({
10542
+ id: "flat-ink",
10543
+ accessibilityLabel: "Flat rounded buttons with arrow affordances",
10353
10544
  tags: {
10354
10545
  tone: "classic",
10355
10546
  energy: "calm",
10356
10547
  motion: "subtle",
10357
- era: "organic"
10548
+ era: "editorial"
10358
10549
  },
10359
- system: {
10550
+ parameterSchema: flatInkParametersSchema,
10551
+ defaultParameters: {},
10552
+ controls: [hoverControl],
10553
+ defineSystem: (parameters) => ({
10360
10554
  global: {
10361
- cornerStyle: "pill",
10362
- shadow: "low",
10555
+ cornerStyle: "rounded",
10363
10556
  textTransform: "none",
10364
- fontWeight: 500,
10557
+ fontWeight: 600,
10558
+ typography: "body",
10559
+ letterSpacing: "tight",
10560
+ paddingPreset: "default",
10365
10561
  hoverTransform: "lift",
10366
10562
  hoverColor: "none"
10367
10563
  },
10368
- roles: {
10369
- primary: {
10370
- kind: "complete",
10371
- appearance: {
10372
- background: {
10373
- type: "solid",
10374
- colorToken: "primary"
10375
- },
10376
- borderRadius: "rounded-full",
10377
- shadow: {
10564
+ sizes: {
10565
+ sm: {
10566
+ padding: "0.625rem 1.125rem",
10567
+ fontSize: "text-sm"
10568
+ },
10569
+ md: { padding: "0.8125rem 1.375rem" },
10570
+ lg: {
10571
+ padding: "0.9375rem 1.625rem",
10572
+ fontSize: "text-lg"
10573
+ },
10574
+ xl: {
10575
+ padding: "1.0625rem 2rem",
10576
+ fontSize: "text-xl"
10577
+ }
10578
+ },
10579
+ roles: {
10580
+ primary: {
10581
+ kind: "complete",
10582
+ appearance: {
10583
+ background: {
10584
+ type: "solid",
10585
+ colorToken: unsafeAsOpaqueButtonColourToken("primary")
10586
+ },
10587
+ borderRadius: "rounded-lg",
10588
+ affordance: { iconId: "ArrowRight" },
10589
+ ...hoverAppearance("primary", parameters, [lift, {
10590
+ effectId: "background-on-hover",
10591
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("secondary") }
10592
+ }])
10593
+ }
10594
+ },
10595
+ secondary: {
10596
+ kind: "complete",
10597
+ appearance: {
10598
+ background: {
10599
+ type: "surface",
10600
+ role: "link"
10601
+ },
10602
+ borderRadius: "rounded-lg",
10603
+ border: { widthClass: "border" },
10604
+ ...hoverAppearance("secondary", parameters, [lift, {
10605
+ effectId: "background-on-hover",
10606
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
10607
+ }])
10608
+ }
10609
+ },
10610
+ outline: {
10611
+ kind: "complete",
10612
+ appearance: {
10613
+ background: {
10614
+ type: "surface",
10615
+ role: "link"
10616
+ },
10617
+ borderRadius: "rounded-lg",
10618
+ border: { widthClass: "border" },
10619
+ ...hoverAppearance("outline", parameters, [lift, {
10620
+ effectId: "background-on-hover",
10621
+ options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
10622
+ }])
10623
+ }
10624
+ },
10625
+ ghost: {
10626
+ kind: "complete",
10627
+ appearance: {
10628
+ background: {
10629
+ type: "surface",
10630
+ role: "link"
10631
+ },
10632
+ borderRadius: "rounded-lg",
10633
+ ...hoverAppearance("ghost", parameters, [lift])
10634
+ }
10635
+ },
10636
+ accent: {
10637
+ kind: "complete",
10638
+ appearance: {
10639
+ background: {
10640
+ type: "solid",
10641
+ colorToken: unsafeAsOpaqueButtonColourToken("accent")
10642
+ },
10643
+ borderRadius: "rounded-lg",
10644
+ affordance: { iconId: "ArrowRight" },
10645
+ ...hoverAppearance("accent", parameters, [lift])
10646
+ }
10647
+ }
10648
+ }
10649
+ })
10650
+ });
10651
+ function hoverAppearance(role, parameters, recommended) {
10652
+ const preference = parameters.hoverPreferences?.[role];
10653
+ if (preference === void 0) return { effects: { hover: [...recommended] } };
10654
+ if (preference === "contextual") {
10655
+ const config = contextualRoleConfig[role];
10656
+ return {
10657
+ effects: { hover: [lift] },
10658
+ contextualHover: {
10659
+ kind: "shade-shift",
10660
+ seedToken: config.contextualSeedToken,
10661
+ fallbackDirection: config.fallbackDirection
10662
+ }
10663
+ };
10664
+ }
10665
+ const config = contextualRoleConfig[role];
10666
+ return {
10667
+ effects: { hover: [lift] },
10668
+ contextualHover: {
10669
+ kind: "shade-shift",
10670
+ seedToken: config.contextualSeedToken,
10671
+ fallbackDirection: config.fallbackDirection,
10672
+ preferredToken: unsafeAsOpaqueButtonColourToken(paletteRole(preference))
10673
+ }
10674
+ };
10675
+ }
10676
+ function paletteRole(preference) {
10677
+ return preference;
10678
+ }
10679
+ //#endregion
10680
+ //#region ../theme-core/src/buttons/styles/recipes/defineStaticButtonStyleRecipe.ts
10681
+ const emptyParametersSchema = z.object({}).strict();
10682
+ function defineStaticButtonStyleRecipe(input) {
10683
+ const system = normalizeSystem(input.system);
10684
+ return defineButtonStyleRecipe({
10685
+ id: input.id,
10686
+ accessibilityLabel: input.accessibilityLabel,
10687
+ tags: input.tags,
10688
+ parameterSchema: emptyParametersSchema,
10689
+ defaultParameters: {},
10690
+ controls: [],
10691
+ defineSystem: () => system
10692
+ });
10693
+ }
10694
+ function normalizeSystem(input) {
10695
+ return {
10696
+ global: buttonGlobalSettingsSchema.parse(input.global),
10697
+ ...input.sizes ? { sizes: input.sizes } : {},
10698
+ roles: {
10699
+ primary: normalizeCompleteRole(input.roles.primary),
10700
+ secondary: normalizeCompleteRole(input.roles.secondary),
10701
+ outline: normalizeSupportingRole(input.roles.outline),
10702
+ ghost: normalizeSupportingRole(input.roles.ghost),
10703
+ accent: normalizeSupportingRole(input.roles.accent)
10704
+ }
10705
+ };
10706
+ }
10707
+ function normalizeCompleteRole(role) {
10708
+ return {
10709
+ kind: "complete",
10710
+ appearance: normalizeAppearance(role.appearance)
10711
+ };
10712
+ }
10713
+ function normalizeSupportingRole(role) {
10714
+ if (role.kind === "complete") return normalizeCompleteRole(role);
10715
+ return {
10716
+ kind: "derive",
10717
+ from: role.from,
10718
+ ...role.overrides ? { overrides: normalizeAppearanceOverrides(role.overrides) } : {}
10719
+ };
10720
+ }
10721
+ function normalizeAppearance(appearance) {
10722
+ const { background, hoverBackgroundToken, ...rest } = appearance;
10723
+ return {
10724
+ ...rest,
10725
+ background: buttonColourTreatmentSchema.parse(background),
10726
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
10727
+ };
10728
+ }
10729
+ function normalizeAppearanceOverrides(overrides) {
10730
+ const { background, hoverBackgroundToken, ...rest } = overrides;
10731
+ return {
10732
+ ...rest,
10733
+ ...background ? { background: buttonColourTreatmentSchema.parse(background) } : {},
10734
+ ...hoverBackgroundToken ? { hoverBackgroundToken: opaqueButtonColourTokenSchema.parse(hoverBackgroundToken) } : {}
10735
+ };
10736
+ }
10737
+ //#endregion
10738
+ //#region ../theme-core/src/buttons/styles/recipes/staticRecipes.ts
10739
+ const softPillRecipe = defineStaticButtonStyleRecipe({
10740
+ id: "soft-pill",
10741
+ accessibilityLabel: "Rounded pill buttons with a gentle hover lift",
10742
+ tags: {
10743
+ tone: "classic",
10744
+ energy: "calm",
10745
+ motion: "subtle",
10746
+ era: "organic"
10747
+ },
10748
+ system: {
10749
+ global: {
10750
+ cornerStyle: "pill",
10751
+ shadow: "low",
10752
+ textTransform: "none",
10753
+ fontWeight: 500,
10754
+ hoverTransform: "lift",
10755
+ hoverColor: "none"
10756
+ },
10757
+ roles: {
10758
+ primary: {
10759
+ kind: "complete",
10760
+ appearance: {
10761
+ background: {
10762
+ type: "solid",
10763
+ colorToken: "primary"
10764
+ },
10765
+ borderRadius: "rounded-full",
10766
+ shadow: {
10378
10767
  elevation: "low",
10379
10768
  softness: "soft",
10380
10769
  position: "bottom"
@@ -11134,113 +11523,6 @@ const inkStampRecipe = defineStaticButtonStyleRecipe({
11134
11523
  }
11135
11524
  }
11136
11525
  });
11137
- const flatInkRecipe = defineStaticButtonStyleRecipe({
11138
- id: "flat-ink",
11139
- accessibilityLabel: "Flat rounded buttons with arrow affordances",
11140
- tags: {
11141
- tone: "classic",
11142
- energy: "calm",
11143
- motion: "subtle",
11144
- era: "editorial"
11145
- },
11146
- system: {
11147
- global: {
11148
- cornerStyle: "rounded",
11149
- textTransform: "none",
11150
- fontWeight: 600,
11151
- typography: "body",
11152
- letterSpacing: "tight",
11153
- paddingPreset: "default",
11154
- hoverTransform: "lift",
11155
- hoverColor: "none"
11156
- },
11157
- sizes: {
11158
- sm: {
11159
- padding: "0.625rem 1.125rem",
11160
- fontSize: "text-sm"
11161
- },
11162
- md: { padding: "0.8125rem 1.375rem" },
11163
- lg: {
11164
- padding: "0.9375rem 1.625rem",
11165
- fontSize: "text-lg"
11166
- },
11167
- xl: {
11168
- padding: "1.0625rem 2rem",
11169
- fontSize: "text-xl"
11170
- }
11171
- },
11172
- roles: {
11173
- primary: {
11174
- kind: "complete",
11175
- appearance: {
11176
- background: {
11177
- type: "solid",
11178
- colorToken: "primary"
11179
- },
11180
- borderRadius: "rounded-lg",
11181
- affordance: { iconId: "ArrowRight" },
11182
- effects: { hover: [{ effectId: "lift" }, {
11183
- effectId: "background-on-hover",
11184
- options: { colorToken: unsafeAsOpaqueButtonColourToken("secondary") }
11185
- }] }
11186
- }
11187
- },
11188
- secondary: {
11189
- kind: "complete",
11190
- appearance: {
11191
- background: {
11192
- type: "surface",
11193
- role: "link"
11194
- },
11195
- borderRadius: "rounded-lg",
11196
- border: { widthClass: "border" },
11197
- effects: { hover: [{ effectId: "lift" }, {
11198
- effectId: "background-on-hover",
11199
- options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
11200
- }] }
11201
- }
11202
- },
11203
- outline: {
11204
- kind: "complete",
11205
- appearance: {
11206
- background: {
11207
- type: "surface",
11208
- role: "link"
11209
- },
11210
- borderRadius: "rounded-lg",
11211
- border: { widthClass: "border" },
11212
- effects: { hover: [{ effectId: "lift" }, {
11213
- effectId: "background-on-hover",
11214
- options: { colorToken: unsafeAsOpaqueButtonColourToken("surfaceAlt") }
11215
- }] }
11216
- }
11217
- },
11218
- ghost: {
11219
- kind: "complete",
11220
- appearance: {
11221
- background: {
11222
- type: "surface",
11223
- role: "link"
11224
- },
11225
- borderRadius: "rounded-lg",
11226
- effects: { hover: [{ effectId: "lift" }] }
11227
- }
11228
- },
11229
- accent: {
11230
- kind: "complete",
11231
- appearance: {
11232
- background: {
11233
- type: "solid",
11234
- colorToken: "accent"
11235
- },
11236
- borderRadius: "rounded-lg",
11237
- affordance: { iconId: "ArrowRight" },
11238
- effects: { hover: [{ effectId: "lift" }] }
11239
- }
11240
- }
11241
- }
11242
- }
11243
- });
11244
11526
  const showtimePillRecipe = defineStaticButtonStyleRecipe({
11245
11527
  id: "showtime-pill",
11246
11528
  accessibilityLabel: "Bold uppercase pill buttons with playful movement",
@@ -11656,13 +11938,25 @@ function presetCategory(recipe) {
11656
11938
  function joinClasses(...parts) {
11657
11939
  return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
11658
11940
  }
11659
- function FeedbackMessage({ tone, children, className, id, title, titleClassName, bodyClassName, role = "status", live }) {
11941
+ /**
11942
+ * The class each treatment contributes on top of whatever the caller passed.
11943
+ *
11944
+ * `panel` contributes nothing: its callers already pass `alert alert-*`, so
11945
+ * adopting the vocabulary changes no existing rendering. `field-note` needs a
11946
+ * single hook — its tone styling keys off `data-feedback-tone` in the
11947
+ * theme-generated CSS rather than off a second class.
11948
+ */
11949
+ function treatmentClass(treatment) {
11950
+ return treatment === "field-note" ? "feedback-note" : void 0;
11951
+ }
11952
+ function FeedbackMessage({ tone, treatment = "panel", children, className, id, title, titleClassName, bodyClassName, role = "status", live }) {
11660
11953
  const resolvedLive = live ?? (role === "alert" ? "assertive" : "polite");
11661
- const shouldWrapBody = Boolean(title || bodyClassName);
11954
+ const shouldWrapBody = Boolean(title || bodyClassName) || treatment === "field-note";
11662
11955
  return /* @__PURE__ */ jsxs("div", {
11663
11956
  id,
11664
- className,
11957
+ className: joinClasses(className, treatmentClass(treatment)) || void 0,
11665
11958
  "data-feedback-tone": tone,
11959
+ "data-feedback-treatment": treatment,
11666
11960
  role,
11667
11961
  "aria-live": resolvedLive === "off" ? void 0 : resolvedLive,
11668
11962
  children: [title ? /* @__PURE__ */ jsx("p", {
@@ -11983,17 +12277,17 @@ function StepIndicator({ currentStep, totalSteps, stepLabels, classPrefix, emitS
11983
12277
  //#endregion
11984
12278
  //#region ../blocks/src/system/runtime/shared/components/DiscountCodeDisclosure.tsx
11985
12279
  const BLOCK_DISCOUNT_CODE_DISCLOSURE_CLASSES = {
11986
- "course-registration": {
11987
- root: "cr-discount",
11988
- toggle: "cr-discount__toggle",
11989
- form: "cr-discount__form",
11990
- label: "cr-discount__label",
11991
- row: "cr-discount__row",
11992
- input: "cr-discount__input",
11993
- apply: "cr-discount__apply",
11994
- remove: "cr-discount__remove",
11995
- hint: "cr-discount__hint",
11996
- feedback: "cr-discount__feedback"
12280
+ "whole-series-registration": {
12281
+ root: "er-whole-series-discount",
12282
+ toggle: "er-whole-series-discount__toggle",
12283
+ form: "er-whole-series-discount__form",
12284
+ label: "er-whole-series-discount__label",
12285
+ row: "er-whole-series-discount__row",
12286
+ input: "er-whole-series-discount__input",
12287
+ apply: "er-whole-series-discount__apply",
12288
+ remove: "er-whole-series-discount__remove",
12289
+ hint: "er-whole-series-discount__hint",
12290
+ feedback: "er-whole-series-discount__feedback"
11997
12291
  },
11998
12292
  "event-registration": {
11999
12293
  root: "er-discount",
@@ -12841,16 +13135,10 @@ function DefaultBookingErrorSummary({ errors, id }) {
12841
13135
  if (!hasBookingValidationErrors(errors)) return null;
12842
13136
  return /* @__PURE__ */ jsxs(FeedbackMessage, {
12843
13137
  tone: "error",
12844
- className: "rb-mt-6 alert alert-error",
13138
+ treatment: "field-note",
12845
13139
  id,
12846
13140
  role: "alert",
12847
- children: [errors.formError ? /* @__PURE__ */ jsx("p", {
12848
- className: "rb-caption",
12849
- children: /* @__PURE__ */ jsx("strong", { children: errors.formError })
12850
- }) : null, Object.entries(errors.fieldErrors).map(([key, message]) => /* @__PURE__ */ jsx("p", {
12851
- className: "rb-caption",
12852
- children: message
12853
- }, key))]
13141
+ children: [errors.formError ? /* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("strong", { children: errors.formError }) }) : null, Object.entries(errors.fieldErrors).map(([key, message]) => /* @__PURE__ */ jsx("p", { children: message }, key))]
12854
13142
  });
12855
13143
  }
12856
13144
  function SelectedCheck() {
@@ -13555,6 +13843,15 @@ function existingRegistrationLookupReducer(state, action) {
13555
13843
  * Custom hooks for portal authentication and eligibility checking.
13556
13844
  * Extracted from the main EventRegistrationClient for better separation of concerns.
13557
13845
  */
13846
+ function scopePortalCreditStateToSubject(state, subjectEmail) {
13847
+ if (!subjectEmail) return { kind: "not_authenticated" };
13848
+ if (state.kind === "not_authenticated") return state;
13849
+ const normalizedSubject = subjectEmail.trim().toLowerCase();
13850
+ return state.subjectEmail === normalizedSubject ? state : {
13851
+ kind: "loading",
13852
+ subjectEmail: normalizedSubject
13853
+ };
13854
+ }
13558
13855
  const eventRegistrationHooksDeps = { useBlockApi };
13559
13856
  /**
13560
13857
  * Hook for managing portal authentication state.
@@ -13569,27 +13866,54 @@ function usePortalAuthWithDeps(deps) {
13569
13866
  const api = deps.useBlockApi();
13570
13867
  const [authState, setAuthState] = useState("checking");
13571
13868
  const [profile, setProfile] = useState(null);
13869
+ const [creditState, setCreditState] = useState({ kind: "not_authenticated" });
13572
13870
  useEffect(() => {
13573
13871
  let cancelled = false;
13574
13872
  async function checkPortalAuth() {
13575
13873
  if ((api.config.authOverrides?.portal ?? api.config.auth).type !== "bearer") {
13576
13874
  setAuthState("unauthenticated");
13875
+ setProfile(null);
13876
+ setCreditState({ kind: "not_authenticated" });
13577
13877
  return;
13578
13878
  }
13579
13879
  setAuthState("checking");
13880
+ setProfile(null);
13881
+ setCreditState({ kind: "not_authenticated" });
13580
13882
  try {
13581
13883
  const me = await api.getPortalProfile();
13582
13884
  if (cancelled) return;
13583
- setAuthState("authenticated");
13584
- setProfile({
13885
+ const nextProfile = {
13585
13886
  email: me.profile.email,
13586
13887
  name: me.profile.name,
13587
13888
  phone: me.profile.phone || ""
13889
+ };
13890
+ const subjectEmail = nextProfile.email.trim().toLowerCase();
13891
+ setProfile(nextProfile);
13892
+ setCreditState({
13893
+ kind: "loading",
13894
+ subjectEmail
13588
13895
  });
13896
+ setAuthState("authenticated");
13897
+ try {
13898
+ const credit = await api.getPortalCredit();
13899
+ if (cancelled) return;
13900
+ setCreditState({
13901
+ kind: "loaded",
13902
+ subjectEmail,
13903
+ credit
13904
+ });
13905
+ } catch {
13906
+ if (cancelled) return;
13907
+ setCreditState({
13908
+ kind: "unavailable",
13909
+ subjectEmail
13910
+ });
13911
+ }
13589
13912
  } catch {
13590
13913
  if (cancelled) return;
13591
13914
  setAuthState("unauthenticated");
13592
13915
  setProfile(null);
13916
+ setCreditState({ kind: "not_authenticated" });
13593
13917
  }
13594
13918
  }
13595
13919
  checkPortalAuth();
@@ -13609,6 +13933,7 @@ function usePortalAuthWithDeps(deps) {
13609
13933
  isAuthenticated: authState === "authenticated",
13610
13934
  isChecking: authState === "checking",
13611
13935
  profile,
13936
+ creditState: scopePortalCreditStateToSubject(creditState, authState === "authenticated" ? profile?.email ?? null : null),
13612
13937
  logout
13613
13938
  };
13614
13939
  }
@@ -13849,9 +14174,14 @@ function getWaitlistClaimTokenSnapshot() {
13849
14174
  function useWaitlistClaim() {
13850
14175
  return useWaitlistClaimWithDeps(useWaitlistClaimDeps);
13851
14176
  }
14177
+ function useWaitlistClaimForToken(token) {
14178
+ return useResolvedWaitlistClaim(useWaitlistClaimDeps, token);
14179
+ }
13852
14180
  function useWaitlistClaimWithDeps(deps) {
14181
+ return useResolvedWaitlistClaim(deps, useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimTokenSnapshot, () => null));
14182
+ }
14183
+ function useResolvedWaitlistClaim(deps, token) {
13853
14184
  const api = deps.useBlockApi();
13854
- const token = useSyncExternalStore(subscribeToWaitlistClaimToken, getWaitlistClaimTokenSnapshot, () => null);
13855
14185
  const [state, dispatch] = useReducer(waitlistClaimReducer, Boolean(token), createInitialWaitlistClaimState);
13856
14186
  useEffect(() => {
13857
14187
  let cancelled = false;
@@ -14564,19 +14894,171 @@ const RichTextDocSchema = z.object({
14564
14894
  content: z.array(TipTapNodeSchema)
14565
14895
  }).strict();
14566
14896
  //#endregion
14567
- //#region ../blocks/src/system/blocks/courses/shared/schemas.ts
14568
- /**
14569
- * Zod schema for course venue data
14570
- */
14571
- const courseVenueSchema = z.object({
14897
+ //#region ../blocks/src/system/blocks/events/whole-series/pricing.ts
14898
+ function isSaleWindowOpen(option, now) {
14899
+ if (!option.isActive) return false;
14900
+ if (option.saleStartsAt && new Date(option.saleStartsAt) > now) return false;
14901
+ if (option.saleEndsAt && new Date(option.saleEndsAt) < now) return false;
14902
+ return true;
14903
+ }
14904
+ function toExactOrFreeDisplay(amount, currency) {
14905
+ if (amount <= 0) return {
14906
+ kind: "free",
14907
+ currency
14908
+ };
14909
+ return {
14910
+ kind: "exact",
14911
+ amount,
14912
+ currency
14913
+ };
14914
+ }
14915
+ function getSelectableWholeSeriesPricingOptionsForNow(offering, now) {
14916
+ if (offering.pricing.pricingStrategy !== "tiered") return [];
14917
+ return [...offering.pricing.options].filter((option) => isSaleWindowOpen(option, now)).sort((left, right) => {
14918
+ if (left.sortOrder !== right.sortOrder) return left.sortOrder - right.sortOrder;
14919
+ if (left.priceAmount !== right.priceAmount) return left.priceAmount - right.priceAmount;
14920
+ return left.name.localeCompare(right.name);
14921
+ });
14922
+ }
14923
+ function resolveWholeSeriesPricingState(offering, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
14924
+ const selection = normalizePricingSelectionInput(selectedSlidingAmountOrNowInput, nowInput);
14925
+ const currency = offering.pricing.currency;
14926
+ switch (offering.pricing.pricingStrategy) {
14927
+ case "free": return resolveFreePricing(currency);
14928
+ case "single": return resolveSinglePricing(offering.pricing.singlePriceAmount ?? 0, currency);
14929
+ case "tiered": return resolveTieredPricing(offering, selectedPricingOptionId, selection.nowInput);
14930
+ case "sliding_scale": return resolveSlidingScalePricing(offering, selection.selectedSlidingAmount);
14931
+ }
14932
+ }
14933
+ function normalizePricingSelectionInput(selectedSlidingAmountOrNowInput, nowInput) {
14934
+ return typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? {
14935
+ selectedSlidingAmount: null,
14936
+ nowInput: selectedSlidingAmountOrNowInput
14937
+ } : {
14938
+ selectedSlidingAmount: typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null,
14939
+ nowInput
14940
+ };
14941
+ }
14942
+ function resolveFreePricing(currency) {
14943
+ return {
14944
+ currency,
14945
+ display: {
14946
+ kind: "free",
14947
+ currency
14948
+ },
14949
+ selectableOptions: [],
14950
+ requiresSelection: false,
14951
+ selectedOption: null,
14952
+ slidingScale: null,
14953
+ selectedSlidingAmount: null,
14954
+ selectedPriceAmount: 0,
14955
+ selectedRequiresPayment: false,
14956
+ hasPaidSelection: false,
14957
+ hasFreeSelection: true
14958
+ };
14959
+ }
14960
+ function resolveSinglePricing(amount, currency) {
14961
+ return {
14962
+ currency,
14963
+ display: toExactOrFreeDisplay(amount, currency),
14964
+ selectableOptions: [],
14965
+ requiresSelection: false,
14966
+ selectedOption: null,
14967
+ slidingScale: null,
14968
+ selectedSlidingAmount: null,
14969
+ selectedPriceAmount: amount,
14970
+ selectedRequiresPayment: amount > 0,
14971
+ hasPaidSelection: amount > 0,
14972
+ hasFreeSelection: amount <= 0
14973
+ };
14974
+ }
14975
+ function resolveTieredPricing(offering, selectedPricingOptionId, nowInput) {
14976
+ const currency = offering.pricing.currency;
14977
+ const selectableOptions = getSelectableWholeSeriesPricingOptionsForNow(offering, resolvePlanningDateInput(nowInput));
14978
+ const selectedOption = resolveSelectedTier(selectableOptions, selectedPricingOptionId);
14979
+ return {
14980
+ currency,
14981
+ display: resolveTieredDisplay(selectableOptions.reduce((lowest, option) => lowest === null || option.priceAmount < lowest ? option.priceAmount : lowest, null), selectableOptions.length, currency),
14982
+ selectableOptions,
14983
+ requiresSelection: selectableOptions.length > 1,
14984
+ selectedOption,
14985
+ slidingScale: null,
14986
+ selectedSlidingAmount: null,
14987
+ selectedPriceAmount: selectedOption?.priceAmount ?? null,
14988
+ selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
14989
+ hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
14990
+ hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
14991
+ };
14992
+ }
14993
+ function resolveSelectedTier(options, selectedId) {
14994
+ return (selectedId ? options.find((option) => option.id === selectedId) : null) ?? (options.length === 1 ? options[0] ?? null : null);
14995
+ }
14996
+ function resolveTieredDisplay(lowestAmount, optionCount, currency) {
14997
+ if (lowestAmount === null) return {
14998
+ kind: "unavailable",
14999
+ currency
15000
+ };
15001
+ return optionCount > 1 && lowestAmount > 0 ? {
15002
+ kind: "from",
15003
+ amount: lowestAmount,
15004
+ currency
15005
+ } : toExactOrFreeDisplay(lowestAmount, currency);
15006
+ }
15007
+ function resolveSlidingScalePricing(offering, selectedSlidingAmount) {
15008
+ const currency = offering.pricing.currency;
15009
+ const minAmount = offering.pricing.slidingMinAmount ?? null;
15010
+ const maxAmount = offering.pricing.slidingMaxAmount ?? null;
15011
+ if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) return unavailableSlidingScale(currency);
15012
+ const selectedAmount = Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
15013
+ return {
15014
+ currency,
15015
+ display: {
15016
+ kind: "range",
15017
+ minAmount,
15018
+ maxAmount,
15019
+ currency
15020
+ },
15021
+ selectableOptions: [],
15022
+ requiresSelection: selectedAmount === null,
15023
+ selectedOption: null,
15024
+ slidingScale: {
15025
+ minAmount,
15026
+ maxAmount,
15027
+ suggestedAmount: offering.pricing.slidingSuggestedAmount ?? null
15028
+ },
15029
+ selectedSlidingAmount: selectedAmount,
15030
+ selectedPriceAmount: selectedAmount,
15031
+ selectedRequiresPayment: (selectedAmount ?? 0) > 0,
15032
+ hasPaidSelection: maxAmount > 0,
15033
+ hasFreeSelection: minAmount === 0
15034
+ };
15035
+ }
15036
+ function unavailableSlidingScale(currency) {
15037
+ return {
15038
+ currency,
15039
+ display: {
15040
+ kind: "unavailable",
15041
+ currency
15042
+ },
15043
+ selectableOptions: [],
15044
+ requiresSelection: true,
15045
+ selectedOption: null,
15046
+ slidingScale: null,
15047
+ selectedSlidingAmount: null,
15048
+ selectedPriceAmount: null,
15049
+ selectedRequiresPayment: false,
15050
+ hasPaidSelection: false,
15051
+ hasFreeSelection: false
15052
+ };
15053
+ }
15054
+ //#endregion
15055
+ //#region ../blocks/src/system/blocks/events/whole-series/schemas.ts
15056
+ const wholeSeriesVenueSchema = z.object({
14572
15057
  id: z.string(),
14573
15058
  name: z.string(),
14574
15059
  address: z.string().nullable()
14575
15060
  });
14576
- /**
14577
- * Zod schema for course session (occurrence) data
14578
- */
14579
- const courseSessionSchema = z.object({
15061
+ const wholeSeriesSessionSchema = z.object({
14580
15062
  id: z.string(),
14581
15063
  startsAt: z.string(),
14582
15064
  endsAt: z.string(),
@@ -14584,14 +15066,14 @@ const courseSessionSchema = z.object({
14584
15066
  capacityOverride: z.number().nullable().optional(),
14585
15067
  overrides: z.record(z.string(), z.unknown()).nullable().optional()
14586
15068
  });
14587
- const courseTeamMemberSummarySchema = z.object({
15069
+ const wholeSeriesTeamMemberSummarySchema = z.object({
14588
15070
  id: z.string(),
14589
15071
  name: z.string(),
14590
15072
  roleLabel: z.string().nullable(),
14591
15073
  summary: z.string().nullable(),
14592
15074
  profilePath: z.string().nullable()
14593
15075
  });
14594
- const coursePricingOptionSchema = z.object({
15076
+ const wholeSeriesPricingOptionSchema = z.object({
14595
15077
  id: z.string(),
14596
15078
  name: z.string(),
14597
15079
  description: z.string().nullable(),
@@ -14607,7 +15089,7 @@ const coursePricingOptionSchema = z.object({
14607
15089
  "both"
14608
15090
  ]).nullable().optional()
14609
15091
  });
14610
- const coursePricingSchema = z.object({
15092
+ const wholeSeriesPricingSchema = z.object({
14611
15093
  bookingRequirement: z.enum(["none", "required"]),
14612
15094
  pricingStrategy: z.enum([
14613
15095
  "free",
@@ -14621,20 +15103,17 @@ const coursePricingSchema = z.object({
14621
15103
  slidingMaxAmount: z.number().nullable().optional(),
14622
15104
  slidingSuggestedAmount: z.number().nullable().optional(),
14623
15105
  paymentTerms: blockBookingPaymentTermsSchema,
14624
- options: z.array(coursePricingOptionSchema)
15106
+ options: z.array(wholeSeriesPricingOptionSchema)
14625
15107
  });
14626
- /**
14627
- * Zod schema for public course data
14628
- */
14629
15108
  const publicWholeSeriesOfferingSchema = z.object({
14630
15109
  eventSeriesId: z.string(),
14631
15110
  eventOfferingId: z.string(),
14632
15111
  title: z.string(),
14633
15112
  slug: z.string(),
14634
15113
  description: z.unknown().nullable(),
14635
- teamMembers: z.array(courseTeamMemberSummarySchema).optional(),
15114
+ teamMembers: z.array(wholeSeriesTeamMemberSummarySchema).optional(),
14636
15115
  enrollmentOpen: z.boolean(),
14637
- pricing: coursePricingSchema,
15116
+ pricing: wholeSeriesPricingSchema,
14638
15117
  currency: z.string(),
14639
15118
  paymentTerms: blockBookingPaymentTermsSchema,
14640
15119
  enrollmentCapacity: z.number().nullable(),
@@ -14647,8 +15126,8 @@ const publicWholeSeriesOfferingSchema = z.object({
14647
15126
  sessionsCount: z.number(),
14648
15127
  enrolledCount: z.number(),
14649
15128
  availableSpots: z.number().nullable(),
14650
- sessions: z.array(courseSessionSchema),
14651
- venue: courseVenueSchema.nullable()
15129
+ sessions: z.array(wholeSeriesSessionSchema),
15130
+ venue: wholeSeriesVenueSchema.nullable()
14652
15131
  });
14653
15132
  z.array(publicWholeSeriesOfferingSchema);
14654
15133
  //#endregion
@@ -14657,6 +15136,7 @@ const eventPresetSchema = z.enum([
14657
15136
  "event",
14658
15137
  "class",
14659
15138
  "course",
15139
+ "term",
14660
15140
  "workshop",
14661
15141
  "retreat",
14662
15142
  "performance"
@@ -14715,57 +15195,49 @@ z.enum([
14715
15195
  */
14716
15196
  const accessRestrictionSchema = z.enum(["none", "category"]);
14717
15197
  z.enum(["single", "ticket_types"]);
15198
+ const freePriceDisplaySchema = z.object({
15199
+ kind: z.literal("free"),
15200
+ currency: z.string()
15201
+ });
15202
+ const exactPriceDisplaySchema = z.object({
15203
+ kind: z.literal("exact"),
15204
+ amount: z.number(),
15205
+ currency: z.string()
15206
+ });
15207
+ const fromPriceDisplaySchema = z.object({
15208
+ kind: z.literal("from"),
15209
+ amount: z.number(),
15210
+ currency: z.string()
15211
+ });
15212
+ const unavailablePriceDisplaySchema = z.object({
15213
+ kind: z.literal("unavailable"),
15214
+ currency: z.string()
15215
+ });
15216
+ const rangePriceDisplaySchema = z.object({
15217
+ kind: z.literal("range"),
15218
+ minAmount: z.number(),
15219
+ maxAmount: z.number(),
15220
+ currency: z.string()
15221
+ });
15222
+ const mixedPriceDisplaySchema = z.object({
15223
+ kind: z.literal("mixed"),
15224
+ paidFromAmount: z.number(),
15225
+ paidToAmount: z.number(),
15226
+ currency: z.string()
15227
+ });
14718
15228
  const publicCoursePriceDisplaySchema = z.discriminatedUnion("kind", [
14719
- z.object({
14720
- kind: z.literal("free"),
14721
- currency: z.string()
14722
- }),
14723
- z.object({
14724
- kind: z.literal("exact"),
14725
- amount: z.number(),
14726
- currency: z.string()
14727
- }),
14728
- z.object({
14729
- kind: z.literal("from"),
14730
- amount: z.number(),
14731
- currency: z.string()
14732
- }),
14733
- z.object({
14734
- kind: z.literal("unavailable"),
14735
- currency: z.string()
14736
- })
15229
+ freePriceDisplaySchema,
15230
+ exactPriceDisplaySchema,
15231
+ fromPriceDisplaySchema,
15232
+ unavailablePriceDisplaySchema
14737
15233
  ]);
14738
15234
  z.discriminatedUnion("kind", [
14739
- z.object({
14740
- kind: z.literal("free"),
14741
- currency: z.string()
14742
- }),
14743
- z.object({
14744
- kind: z.literal("exact"),
14745
- amount: z.number(),
14746
- currency: z.string()
14747
- }),
14748
- z.object({
14749
- kind: z.literal("from"),
14750
- amount: z.number(),
14751
- currency: z.string()
14752
- }),
14753
- z.object({
14754
- kind: z.literal("range"),
14755
- minAmount: z.number(),
14756
- maxAmount: z.number(),
14757
- currency: z.string()
14758
- }),
14759
- z.object({
14760
- kind: z.literal("mixed"),
14761
- paidFromAmount: z.number(),
14762
- paidToAmount: z.number(),
14763
- currency: z.string()
14764
- }),
14765
- z.object({
14766
- kind: z.literal("unavailable"),
14767
- currency: z.string()
14768
- }),
15235
+ freePriceDisplaySchema,
15236
+ exactPriceDisplaySchema,
15237
+ fromPriceDisplaySchema,
15238
+ rangePriceDisplaySchema,
15239
+ mixedPriceDisplaySchema,
15240
+ unavailablePriceDisplaySchema,
14769
15241
  z.object({
14770
15242
  kind: z.literal("external"),
14771
15243
  label: z.string()
@@ -14776,36 +15248,12 @@ z.discriminatedUnion("kind", [
14776
15248
  })
14777
15249
  ]);
14778
15250
  const publicEventTicketTypePriceDisplaySchema = z.union([
14779
- z.object({
14780
- kind: z.literal("free"),
14781
- currency: z.string()
14782
- }),
14783
- z.object({
14784
- kind: z.literal("exact"),
14785
- amount: z.number(),
14786
- currency: z.string()
14787
- }),
14788
- z.object({
14789
- kind: z.literal("from"),
14790
- amount: z.number(),
14791
- currency: z.string()
14792
- }),
14793
- z.object({
14794
- kind: z.literal("range"),
14795
- minAmount: z.number(),
14796
- maxAmount: z.number(),
14797
- currency: z.string()
14798
- }),
14799
- z.object({
14800
- kind: z.literal("mixed"),
14801
- paidFromAmount: z.number(),
14802
- paidToAmount: z.number(),
14803
- currency: z.string()
14804
- }),
14805
- z.object({
14806
- kind: z.literal("unavailable"),
14807
- currency: z.string()
14808
- })
15251
+ freePriceDisplaySchema,
15252
+ exactPriceDisplaySchema,
15253
+ fromPriceDisplaySchema,
15254
+ rangePriceDisplaySchema,
15255
+ mixedPriceDisplaySchema,
15256
+ unavailablePriceDisplaySchema
14809
15257
  ]);
14810
15258
  const publicEventAttendanceModeSchema = z.enum(["in_person", "online"]);
14811
15259
  const publicEventAttendanceModeAvailabilitySchema = z.object({
@@ -14919,6 +15367,22 @@ const publicTeamMemberSummarySchema = z.object({
14919
15367
  summary: z.string().nullable(),
14920
15368
  profilePath: z.string().nullable()
14921
15369
  });
15370
+ const publicEventBookingAvailabilitySchema = z.discriminatedUnion("kind", [z.object({ kind: z.literal("open") }), z.object({
15371
+ kind: z.literal("closed"),
15372
+ reason: z.enum([
15373
+ "occurrence_cancelled",
15374
+ "occurrence_completed",
15375
+ "series_draft",
15376
+ "series_cancelled",
15377
+ "series_completed",
15378
+ "series_archived",
15379
+ "parent_archived",
15380
+ "parent_inconsistent",
15381
+ "not_public",
15382
+ "already_started",
15383
+ "enrollment_closed"
15384
+ ])
15385
+ })]);
14922
15386
  /**
14923
15387
  * Zod schema for public event data
14924
15388
  */
@@ -14943,6 +15407,7 @@ const publicEventSchema = z.object({
14943
15407
  path: z.string().nullable(),
14944
15408
  destination: publicEventDestinationSchema,
14945
15409
  requiresRegistration: z.boolean(),
15410
+ bookingAvailability: publicEventBookingAvailabilitySchema,
14946
15411
  deliveryMode: z.enum([
14947
15412
  "in_person",
14948
15413
  "online",
@@ -14961,6 +15426,8 @@ const publicEventSchema = z.object({
14961
15426
  status: z.enum([
14962
15427
  "active",
14963
15428
  "draft",
15429
+ "cancelled",
15430
+ "completed",
14964
15431
  "archived"
14965
15432
  ]).optional(),
14966
15433
  timeZone: z.string(),
@@ -14973,7 +15440,7 @@ const publicEventSchema = z.object({
14973
15440
  acceptsMemberships: z.boolean().optional(),
14974
15441
  wholeSeries: z.object({
14975
15442
  eventSeriesId: z.string(),
14976
- pricing: coursePricingSchema,
15443
+ pricing: wholeSeriesPricingSchema,
14977
15444
  currency: z.string(),
14978
15445
  enrollmentOpen: z.boolean()
14979
15446
  }).nullable().optional()
@@ -14984,6 +15451,7 @@ const unsupportedEventRegistrationPageSurfaceSubjectSchema = z.object({
14984
15451
  reason: z.enum([
14985
15452
  "unsupportedSubject",
14986
15453
  "invalidEventSeriesId",
15454
+ "invalidEventSeriesBookingScope",
14987
15455
  "invalidEventOfferingId"
14988
15456
  ])
14989
15457
  });
@@ -15014,6 +15482,10 @@ function normalizeEventRegistrationPageSurfaceSubject(value) {
15014
15482
  kind: "unsupported",
15015
15483
  reason: "invalidEventSeriesId"
15016
15484
  };
15485
+ case "invalidEventSeriesBookingScope": return {
15486
+ kind: "unsupported",
15487
+ reason: "invalidEventSeriesBookingScope"
15488
+ };
15017
15489
  case "invalidEventOfferingId": return {
15018
15490
  kind: "unsupported",
15019
15491
  reason: "invalidEventOfferingId"
@@ -15126,8 +15598,8 @@ function normalizePublicEventLike(value) {
15126
15598
  }
15127
15599
  //#endregion
15128
15600
  //#region ../blocks/src/system/runtime/nodes/event-registration/event-registration.headless.planning.ts
15129
- function getRegistrableStatuses(isPreview) {
15130
- return isPreview ? ["active", "draft"] : ["active"];
15601
+ function isEventRegistrationAvailable(event) {
15602
+ return event.bookingAvailability.kind === "open";
15131
15603
  }
15132
15604
  function normalizeEventRegistrationMaxTickets(value) {
15133
15605
  if (typeof value === "number" && Number.isFinite(value) && value > 0) return Math.floor(value);
@@ -15283,8 +15755,7 @@ function resolveHeadlessEventRegistrationView(wizard) {
15283
15755
  kind: "empty",
15284
15756
  message: "No events available for registration."
15285
15757
  };
15286
- const allowedStatuses = getRegistrableStatuses(wizard.api.config.isPreview);
15287
- if (!wizard.scopedEvents.some((event) => !event.status || allowedStatuses.includes(event.status)) && !wizard.occurrenceContext) return {
15758
+ if (!wizard.scopedEvents.some(isEventRegistrationAvailable) && !wizard.occurrenceContext) return {
15288
15759
  kind: "unavailable",
15289
15760
  message: "Registration is not currently available for this event."
15290
15761
  };
@@ -15499,7 +15970,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
15499
15970
  const [registrationResult, setRegistrationResult] = useState(null);
15500
15971
  const [errorMessage, setErrorMessage] = useState("");
15501
15972
  const [altchaSolution, setAltchaSolution] = useState(null);
15502
- const { authState: portalAuthState, profile: portalProfile } = deps.usePortalAuth();
15973
+ const { authState: portalAuthState, profile: portalProfile, creditState: portalCreditState } = deps.usePortalAuth();
15503
15974
  const waitlistClaim = deps.useWaitlistClaim();
15504
15975
  const [showMagicLinkModal, setShowMagicLinkModal] = useState(false);
15505
15976
  const [pendingAttendeeId, setPendingAttendeeId] = useState(null);
@@ -16052,6 +16523,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
16052
16523
  setAltchaSolution,
16053
16524
  portalAuthState,
16054
16525
  portalProfile,
16526
+ portalCreditState,
16055
16527
  showMagicLinkModal,
16056
16528
  setShowMagicLinkModal,
16057
16529
  handleLogout,
@@ -16106,7 +16578,7 @@ function buildEventRegistrationPaymentOptionsViewModel(input) {
16106
16578
  return {
16107
16579
  mode: selection.mode,
16108
16580
  sectionTitle: selection.sectionTitle,
16109
- options: selection.options.map((option) => toEventDirectPaymentOption(option, selection.mode))
16581
+ options: selection.options.map((option, index) => toEventDirectPaymentOption(option, supportedOptions[index] ?? DEFAULT_EVENT_DIRECT_PAYMENT_OPTION, selection.mode, input.totalPriceCents))
16110
16582
  };
16111
16583
  }
16112
16584
  function selectSupportedEventDirectPaymentOptions(paymentTerms) {
@@ -16116,17 +16588,24 @@ function selectSupportedEventDirectPaymentOptions(paymentTerms) {
16116
16588
  function isSupportedEventDirectPaymentOption(option) {
16117
16589
  return option.kind === "upfront" || option.kind === "flexible_balance";
16118
16590
  }
16119
- function toEventDirectPaymentOption(option, mode) {
16591
+ function toEventDirectPaymentOption(option, sourceOption, mode, totalCents) {
16120
16592
  switch (option.kind) {
16121
16593
  case "upfront": return {
16122
16594
  ...option,
16123
16595
  kind: "upfront",
16124
- label: mode === "choice_required" ? "Pay in full now" : "Pay by card"
16596
+ label: mode === "choice_required" ? "Pay in full now" : "Pay by card",
16597
+ totalCents,
16598
+ configuredPaymentDueNowCents: totalCents
16125
16599
  };
16126
16600
  case "flexible_balance": return {
16127
16601
  ...option,
16128
16602
  kind: "flexible_balance",
16129
- label: "Pay deposit now"
16603
+ label: "Pay deposit now",
16604
+ totalCents,
16605
+ configuredPaymentDueNowCents: sourceOption.kind === "flexible_balance" ? resolveFlexibleBalanceInitialPaymentCents({
16606
+ totalAmountCents: totalCents,
16607
+ config: sourceOption.config
16608
+ }) : totalCents
16130
16609
  };
16131
16610
  case "deferred_manual":
16132
16611
  case "instalment_plan": throw new Error(`Unsupported event registration payment option: ${option.kind}`);
@@ -16459,13 +16938,13 @@ function resolveHeadlessDirectPaymentOptions(wizard) {
16459
16938
  }).options;
16460
16939
  }
16461
16940
  //#endregion
16462
- //#region ../blocks/src/system/runtime/nodes/course-registration/utils.ts
16941
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/utils.ts
16463
16942
  /**
16464
16943
  * Anchor ID for the registration block, used for scroll targeting.
16465
16944
  */
16466
- const COURSE_REGISTRATION_ANCHOR_ID = "course-registration";
16945
+ const WHOLE_SERIES_REGISTRATION_ANCHOR_ID = "event-registration";
16467
16946
  //#endregion
16468
- //#region ../blocks/src/system/runtime/nodes/course-registration/pricing.ts
16947
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/pricing.ts
16469
16948
  function parseCurrencyInputToCents(value) {
16470
16949
  const trimmed = value.trim();
16471
16950
  if (!trimmed) return null;
@@ -16477,31 +16956,31 @@ function formatCentsAsCurrencyInput(amount) {
16477
16956
  const major = amount / 100;
16478
16957
  return Number.isInteger(major) ? String(major) : major.toFixed(2);
16479
16958
  }
16480
- function getMissingCoursePricingSelectionMessage(pricing) {
16959
+ function getMissingWholeSeriesPricingSelectionMessage(pricing) {
16481
16960
  if (pricing?.requiresSelection && !pricing.selectedOption) return pricing.slidingScale ? "Choose an amount to continue." : "Choose a pricing option to continue.";
16482
16961
  const selectedAmount = pricing?.selectedSlidingAmount;
16483
16962
  const scale = pricing?.slidingScale;
16484
16963
  if (scale && selectedAmount !== null && selectedAmount !== void 0 && (selectedAmount < scale.minAmount || selectedAmount > scale.maxAmount)) return "Choose an amount within the sliding scale.";
16485
16964
  return null;
16486
16965
  }
16487
- function buildCoursePricingOptionPayload(pricing) {
16966
+ function buildWholeSeriesPricingOptionPayload(pricing) {
16488
16967
  if (pricing?.selectedOption) return { pricingOptionId: pricing.selectedOption.id };
16489
16968
  if (pricing?.slidingScale && pricing.selectedSlidingAmount !== null) return { selectedSlidingAmount: pricing.selectedSlidingAmount };
16490
16969
  return {};
16491
16970
  }
16492
- function defaultCoursePricingSelection(pricing, previousOptionId) {
16971
+ function defaultWholeSeriesPricingSelection(pricing, previousOptionId) {
16493
16972
  return {
16494
16973
  pricingOptionId: previousOptionId && pricing.selectableOptions.some((option) => option.id === previousOptionId) ? previousOptionId : pricing.selectedOption?.id ?? null,
16495
16974
  slidingAmountInput: pricing.slidingScale?.suggestedAmount !== null && pricing.slidingScale?.suggestedAmount !== void 0 ? formatCentsAsCurrencyInput(pricing.slidingScale.suggestedAmount) : ""
16496
16975
  };
16497
16976
  }
16498
16977
  //#endregion
16499
- //#region ../blocks/src/system/runtime/nodes/course-registration/wizardSteps.ts
16978
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/wizardSteps.ts
16500
16979
  /**
16501
16980
  * Step labels for the wizard indicator
16502
16981
  */
16503
16982
  const STEP_LABELS = {
16504
- "select-course": "Course",
16983
+ "select-run": "Run",
16505
16984
  "enter-details": "Details",
16506
16985
  "booking-mode": "Method",
16507
16986
  "select-payment": "Payment",
@@ -16517,36 +16996,36 @@ const STEP_LABELS = {
16517
16996
  /**
16518
16997
  * Determine which wizard steps to show based on context and eligibility.
16519
16998
  *
16520
- * @param hasPreSelectedCourse - Whether course is pre-selected (skips course selection)
16521
- * @param requiresPayment - Whether the course requires payment
16999
+ * @param hasPreSelectedRun - Whether run is pre-selected (skips run selection)
17000
+ * @param requiresPayment - Whether the run requires payment
16522
17001
  * @param hasEligibleMemberships - Whether user has eligible memberships
16523
17002
  * @param bookingMode - Current booking mode selection
16524
17003
  * @param isMembershipFastTrack - Whether user qualifies for single-step membership flow
16525
17004
  * @returns Array of wizard steps to display
16526
17005
  */
16527
- function getWizardStepsForContext(hasPreSelectedCourse, requiresPayment, hasEligibleMemberships, bookingMode, isMembershipFastTrack) {
16528
- if (isMembershipFastTrack) return hasPreSelectedCourse ? ["enter-details"] : ["select-course", "enter-details"];
16529
- if (!requiresPayment) return hasPreSelectedCourse ? ["enter-details"] : ["select-course", "enter-details"];
17006
+ function getWizardStepsForContext(hasPreSelectedRun, requiresPayment, hasEligibleMemberships, bookingMode, isMembershipFastTrack) {
17007
+ if (isMembershipFastTrack) return hasPreSelectedRun ? ["enter-details"] : ["select-run", "enter-details"];
17008
+ if (!requiresPayment) return hasPreSelectedRun ? ["enter-details"] : ["select-run", "enter-details"];
16530
17009
  if (hasEligibleMemberships) {
16531
17010
  const skipPayment = bookingMode === "membership";
16532
- if (hasPreSelectedCourse) return skipPayment ? ["enter-details", "booking-mode"] : [
17011
+ if (hasPreSelectedRun) return skipPayment ? ["enter-details", "booking-mode"] : [
16533
17012
  "enter-details",
16534
17013
  "booking-mode",
16535
17014
  "select-payment"
16536
17015
  ];
16537
17016
  return skipPayment ? [
16538
- "select-course",
17017
+ "select-run",
16539
17018
  "enter-details",
16540
17019
  "booking-mode"
16541
17020
  ] : [
16542
- "select-course",
17021
+ "select-run",
16543
17022
  "enter-details",
16544
17023
  "booking-mode",
16545
17024
  "select-payment"
16546
17025
  ];
16547
17026
  }
16548
- return hasPreSelectedCourse ? ["enter-details", "select-payment"] : [
16549
- "select-course",
17027
+ return hasPreSelectedRun ? ["enter-details", "select-payment"] : [
17028
+ "select-run",
16550
17029
  "enter-details",
16551
17030
  "select-payment"
16552
17031
  ];
@@ -16558,21 +17037,21 @@ function getStepLabels(steps) {
16558
17037
  return steps.map((step) => STEP_LABELS[step] ?? step);
16559
17038
  }
16560
17039
  //#endregion
16561
- //#region ../blocks/src/system/runtime/nodes/course-registration/courseRegistrationViewState.ts
16562
- function deriveCourseRegistrationViewState(input) {
16563
- const hasCoursePayment = resolveCoursePaymentRequirement(input.pricing);
16564
- const canUseMembership = hasCoursePayment && input.selectedCourse?.acceptsMemberships === true && input.portalAuthState === "authenticated" && input.eligibleMembershipCount > 0;
16565
- const hasPreSelectedCourse = input.scopedCourses.length === 1;
17040
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/wholeSeriesRegistrationViewState.ts
17041
+ function deriveWholeSeriesRegistrationViewState(input) {
17042
+ const hasRunPayment = resolveWholeSeriesPaymentRequirement(input.pricing);
17043
+ const canUseMembership = hasRunPayment && input.selectedRun?.acceptsMemberships === true && input.portalAuthState === "authenticated" && input.eligibleMembershipCount > 0;
17044
+ const hasPreSelectedRun = input.scopedRuns.length === 1;
16566
17045
  const fastTrack = canUseMembership && input.eligibleMembershipCount === 1 && input.bookingMode === "membership";
16567
- const wizardSteps = getWizardStepsForContext(hasPreSelectedCourse, hasCoursePayment, canUseMembership, input.bookingMode, fastTrack);
17046
+ const wizardSteps = getWizardStepsForContext(hasPreSelectedRun, hasRunPayment, canUseMembership, input.bookingMode, fastTrack);
16568
17047
  const showPortalAuthSidebar = shouldShowPortalAuthSidebar({
16569
17048
  ...input,
16570
- hasCoursePayment
17049
+ hasRunPayment
16571
17050
  });
16572
17051
  return {
16573
- hasCoursePayment,
17052
+ hasRunPayment,
16574
17053
  canUseMembership,
16575
- hasPreSelectedCourse,
17054
+ hasPreSelectedRun,
16576
17055
  wizardSteps,
16577
17056
  currentStepNumber: getStepNumber(input.step, wizardSteps),
16578
17057
  totalSteps: wizardSteps.length,
@@ -16580,24 +17059,24 @@ function deriveCourseRegistrationViewState(input) {
16580
17059
  showPortalAuthSidebar
16581
17060
  };
16582
17061
  }
16583
- function resolveCoursePaymentRequirement(pricing) {
17062
+ function resolveWholeSeriesPaymentRequirement(pricing) {
16584
17063
  if (!pricing) return false;
16585
17064
  return pricing.selectedOption ? pricing.selectedRequiresPayment : pricing.hasPaidSelection;
16586
17065
  }
16587
17066
  function shouldShowPortalAuthSidebar(input) {
16588
17067
  if (input.portalAuthState !== "unauthenticated") return false;
16589
17068
  if (input.step === "success" || input.step === "waitlist" || input.step === "error") return false;
16590
- return input.waitlistRequiresPortalLogin || input.hasCoursePayment && input.selectedCourse?.acceptsMemberships === true && input.step !== "select-course";
17069
+ return input.waitlistRequiresPortalLogin || input.hasRunPayment && input.selectedRun?.acceptsMemberships === true && input.step !== "select-run";
16591
17070
  }
16592
17071
  //#endregion
16593
- //#region ../blocks/src/system/runtime/nodes/course-registration/useCourseEligibility.ts
17072
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesEligibility.ts
16594
17073
  function shouldFetchEligibility(input) {
16595
- if (!input.course || input.portalAuthState === "checking" || input.hasWaitlistClaimToken) return false;
16596
- const membershipCheck = input.portalAuthState === "authenticated" && input.hasPaidSelection && input.course.acceptsMemberships;
16597
- const capacityCheck = input.course.availableSpots !== null && input.course.availableSpots <= 0;
17074
+ if (!input.run || input.portalAuthState === "checking" || input.hasWaitlistClaimToken) return false;
17075
+ const membershipCheck = input.portalAuthState === "authenticated" && input.hasPaidSelection && input.run.acceptsMemberships;
17076
+ const capacityCheck = input.run.availableSpots !== null && input.run.availableSpots <= 0;
16598
17077
  return membershipCheck || capacityCheck;
16599
17078
  }
16600
- function useCourseEligibility(input) {
17079
+ function useWholeSeriesEligibility(input) {
16601
17080
  const [loading, setLoading] = useState(false);
16602
17081
  const [error, setError] = useState(null);
16603
17082
  const [eligibility, setEligibility] = useState(null);
@@ -16618,15 +17097,15 @@ function useCourseEligibility(input) {
16618
17097
  setError(null);
16619
17098
  setPaymentChoice("checkout");
16620
17099
  const eligibilityInput = {
16621
- course: input.selectedCourse,
17100
+ run: input.selectedRun,
16622
17101
  hasPaidSelection: input.hasPaidSelection,
16623
17102
  portalAuthState: input.portalAuthState,
16624
17103
  hasWaitlistClaimToken: input.waitlistClaimToken !== null
16625
17104
  };
16626
17105
  if (!shouldFetchEligibility(eligibilityInput)) return;
16627
- const course = eligibilityInput.course;
17106
+ const run = eligibilityInput.run;
16628
17107
  setLoading(true);
16629
- input.api.checkWholeSeriesEligibility({ eventSeriesId: course.eventSeriesId }).then((result) => {
17108
+ input.api.checkWholeSeriesEligibility({ eventSeriesId: run.eventSeriesId }).then((result) => {
16630
17109
  if (cancelled) return;
16631
17110
  const eligibleMemberships = result.eligibleMemberships ?? [];
16632
17111
  setEligibility(result);
@@ -16647,13 +17126,13 @@ function useCourseEligibility(input) {
16647
17126
  input.api,
16648
17127
  input.hasPaidSelection,
16649
17128
  input.portalAuthState,
16650
- input.selectedCourse,
17129
+ input.selectedRun,
16651
17130
  input.waitlistClaimToken
16652
17131
  ]);
16653
17132
  return {
16654
17133
  eligibilityLoading: loading,
16655
17134
  eligibilityError: error,
16656
- courseEligibility: eligibility,
17135
+ runEligibility: eligibility,
16657
17136
  eligibleMemberships: memberships,
16658
17137
  paymentChoice,
16659
17138
  choosePaymentChoice,
@@ -16662,149 +17141,12 @@ function useCourseEligibility(input) {
16662
17141
  };
16663
17142
  }
16664
17143
  //#endregion
16665
- //#region ../blocks/src/system/blocks/courses/shared/pricing.ts
16666
- function isSaleWindowOpen(option, now) {
16667
- if (!option.isActive) return false;
16668
- if (option.saleStartsAt && new Date(option.saleStartsAt) > now) return false;
16669
- if (option.saleEndsAt && new Date(option.saleEndsAt) < now) return false;
16670
- return true;
16671
- }
16672
- function toExactOrFreeDisplay(amount, currency) {
16673
- if (amount <= 0) return {
16674
- kind: "free",
16675
- currency
16676
- };
16677
- return {
16678
- kind: "exact",
16679
- amount,
16680
- currency
16681
- };
16682
- }
16683
- function getSelectableCoursePricingOptionsForNow(course, now) {
16684
- if (course.pricing.pricingStrategy !== "tiered") return [];
16685
- return [...course.pricing.options].filter((option) => isSaleWindowOpen(option, now)).sort((left, right) => {
16686
- if (left.sortOrder !== right.sortOrder) return left.sortOrder - right.sortOrder;
16687
- if (left.priceAmount !== right.priceAmount) return left.priceAmount - right.priceAmount;
16688
- return left.name.localeCompare(right.name);
16689
- });
16690
- }
16691
- function resolveCoursePricingState(course, selectedPricingOptionId, selectedSlidingAmountOrNowInput, nowInput = {}) {
16692
- const selectedSlidingAmount = typeof selectedSlidingAmountOrNowInput === "number" || selectedSlidingAmountOrNowInput === null ? selectedSlidingAmountOrNowInput : null;
16693
- const effectiveNowInput = typeof selectedSlidingAmountOrNowInput === "object" && selectedSlidingAmountOrNowInput !== null ? selectedSlidingAmountOrNowInput : nowInput;
16694
- const currency = course.pricing.currency;
16695
- switch (course.pricing.pricingStrategy) {
16696
- case "free": return {
16697
- currency,
16698
- display: {
16699
- kind: "free",
16700
- currency
16701
- },
16702
- selectableOptions: [],
16703
- requiresSelection: false,
16704
- selectedOption: null,
16705
- slidingScale: null,
16706
- selectedSlidingAmount: null,
16707
- selectedPriceAmount: 0,
16708
- selectedRequiresPayment: false,
16709
- hasPaidSelection: false,
16710
- hasFreeSelection: true
16711
- };
16712
- case "single": {
16713
- const amount = course.pricing.singlePriceAmount ?? 0;
16714
- return {
16715
- currency,
16716
- display: toExactOrFreeDisplay(amount, currency),
16717
- selectableOptions: [],
16718
- requiresSelection: false,
16719
- selectedOption: null,
16720
- slidingScale: null,
16721
- selectedSlidingAmount: null,
16722
- selectedPriceAmount: amount,
16723
- selectedRequiresPayment: amount > 0,
16724
- hasPaidSelection: amount > 0,
16725
- hasFreeSelection: amount <= 0
16726
- };
16727
- }
16728
- case "tiered": {
16729
- const selectableOptions = getSelectableCoursePricingOptionsForNow(course, resolvePlanningDateInput(effectiveNowInput));
16730
- const selectedOption = (selectedPricingOptionId ? selectableOptions.find((option) => option.id === selectedPricingOptionId) : null) ?? (selectableOptions.length === 1 ? selectableOptions[0] ?? null : null);
16731
- const lowestAmount = selectableOptions.reduce((lowest, option) => {
16732
- if (lowest === null || option.priceAmount < lowest) return option.priceAmount;
16733
- return lowest;
16734
- }, null);
16735
- return {
16736
- currency,
16737
- display: lowestAmount === null ? {
16738
- kind: "unavailable",
16739
- currency
16740
- } : selectableOptions.length > 1 && lowestAmount > 0 ? {
16741
- kind: "from",
16742
- amount: lowestAmount,
16743
- currency
16744
- } : toExactOrFreeDisplay(lowestAmount, currency),
16745
- selectableOptions,
16746
- requiresSelection: selectableOptions.length > 1,
16747
- selectedOption,
16748
- slidingScale: null,
16749
- selectedSlidingAmount: null,
16750
- selectedPriceAmount: selectedOption?.priceAmount ?? null,
16751
- selectedRequiresPayment: (selectedOption?.priceAmount ?? 0) > 0,
16752
- hasPaidSelection: selectableOptions.some((option) => option.priceAmount > 0),
16753
- hasFreeSelection: selectableOptions.some((option) => option.priceAmount === 0)
16754
- };
16755
- }
16756
- case "sliding_scale": {
16757
- const minAmount = course.pricing.slidingMinAmount ?? null;
16758
- const maxAmount = course.pricing.slidingMaxAmount ?? null;
16759
- if (minAmount === null || maxAmount === null || minAmount < 0 || maxAmount < minAmount) return {
16760
- currency,
16761
- display: {
16762
- kind: "unavailable",
16763
- currency
16764
- },
16765
- selectableOptions: [],
16766
- requiresSelection: true,
16767
- selectedOption: null,
16768
- slidingScale: null,
16769
- selectedSlidingAmount: null,
16770
- selectedPriceAmount: null,
16771
- selectedRequiresPayment: false,
16772
- hasPaidSelection: false,
16773
- hasFreeSelection: false
16774
- };
16775
- const normalizedSelectedAmount = typeof selectedSlidingAmount === "number" && Number.isFinite(selectedSlidingAmount) ? selectedSlidingAmount : null;
16776
- return {
16777
- currency,
16778
- display: {
16779
- kind: "range",
16780
- minAmount,
16781
- maxAmount,
16782
- currency
16783
- },
16784
- selectableOptions: [],
16785
- requiresSelection: normalizedSelectedAmount === null,
16786
- selectedOption: null,
16787
- slidingScale: {
16788
- minAmount,
16789
- maxAmount,
16790
- suggestedAmount: course.pricing.slidingSuggestedAmount ?? null
16791
- },
16792
- selectedSlidingAmount: normalizedSelectedAmount,
16793
- selectedPriceAmount: normalizedSelectedAmount,
16794
- selectedRequiresPayment: (normalizedSelectedAmount ?? 0) > 0,
16795
- hasPaidSelection: maxAmount > 0,
16796
- hasFreeSelection: minAmount === 0
16797
- };
16798
- }
16799
- }
16800
- }
16801
- //#endregion
16802
- //#region ../blocks/src/system/runtime/nodes/course-page-surface-scope.ts
17144
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/wholeSeriesPageSurfaceScope.ts
16803
17145
  /**
16804
- * Resolves native course-page ownership without falling back to entry or slug
17146
+ * Resolves native run-page ownership without falling back to entry or slug
16805
17147
  * coincidence when a page-surface subject is present but invalid.
16806
17148
  */
16807
- function resolveCoursePageSurfaceScope(courses, subjectValue) {
17149
+ function resolveWholeSeriesPageSurfaceScope(runs, subjectValue) {
16808
17150
  if (subjectValue === null || subjectValue === void 0) return { kind: "absent" };
16809
17151
  const parsed = parseEventPageSurfaceSubject(subjectValue);
16810
17152
  if (!parsed.ok) return {
@@ -16816,7 +17158,7 @@ function resolveCoursePageSurfaceScope(courses, subjectValue) {
16816
17158
  return {
16817
17159
  kind: "scoped",
16818
17160
  subject: parsed.value,
16819
- courses: courses.filter((course) => allowedSeriesIds.has(course.eventSeriesId))
17161
+ runs: runs.filter((run) => allowedSeriesIds.has(run.eventSeriesId))
16820
17162
  };
16821
17163
  }
16822
17164
  function eventSeriesIdsForSubject(subject) {
@@ -16827,33 +17169,43 @@ function eventSeriesIdsForSubject(subject) {
16827
17169
  }
16828
17170
  }
16829
17171
  //#endregion
16830
- //#region ../blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationSelection.ts
16831
- function selectScopedCourses(props) {
16832
- const surfaceScope = resolveCoursePageSurfaceScope(props.courses ?? [], props.subject);
17172
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationSelection.ts
17173
+ function selectScopedRuns(props) {
17174
+ const surfaceScope = resolveWholeSeriesPageSurfaceScope(props.runs ?? [], props.subject);
16833
17175
  if (surfaceScope.kind === "unsupported") return [];
16834
- if (surfaceScope.kind === "scoped") return surfaceScope.courses;
17176
+ if (surfaceScope.kind === "scoped") return surfaceScope.runs;
16835
17177
  return [];
16836
17178
  }
16837
- function getCourseCheckoutSessionId() {
16838
- const fromSearch = new URLSearchParams(window.location.search).get("session_id");
17179
+ function getWholeSeriesCheckoutSessionId(location = window.location) {
17180
+ const fromSearch = new URLSearchParams(location.search).get("session_id");
16839
17181
  if (fromSearch) return fromSearch;
16840
- return window.location.hash.match(/[?&]session_id=([^&]+)/)?.[1] ?? null;
17182
+ return location.hash.match(/[?&]session_id=([^&]+)/)?.[1] ?? null;
16841
17183
  }
16842
- function initialStep(courses) {
16843
- if (new URLSearchParams(window.location.search).get("enrollment") === "success" && getCourseCheckoutSessionId()) return "verifying-payment";
16844
- return courses.length === 1 ? "enter-details" : "select-course";
17184
+ function initialStep(runs, location) {
17185
+ if (new URLSearchParams(location.search).get("enrollment") === "success" && getWholeSeriesCheckoutSessionId(location)) return "verifying-payment";
17186
+ return runs.length === 1 ? "enter-details" : "select-run";
16845
17187
  }
16846
- function useCourseRegistrationSelection(props) {
16847
- const scopedCourses = useMemo(() => selectScopedCourses(props), [props.courses, props.subject]);
16848
- const [step, setStep] = useState(() => initialStep(scopedCourses));
16849
- const [selectedCourse, setSelectedCourse] = useState(scopedCourses.length === 1 ? scopedCourses[0] ?? null : null);
17188
+ function useWholeSeriesRegistrationSelection(props, location = window.location) {
17189
+ const scopeSnapshot = JSON.stringify({
17190
+ runs: props.runs ?? [],
17191
+ subject: props.subject ?? null
17192
+ });
17193
+ const stableScope = useRef(null);
17194
+ if (stableScope.current?.snapshot !== scopeSnapshot) stableScope.current = {
17195
+ snapshot: scopeSnapshot,
17196
+ runs: selectScopedRuns(props)
17197
+ };
17198
+ const scopedRuns = stableScope.current.runs;
17199
+ const [step, setStep] = useState(() => initialStep(scopedRuns, location));
17200
+ const [selectedRunId, setSelectedRunId] = useState(scopedRuns.length === 1 ? scopedRuns[0]?.eventSeriesId ?? null : null);
17201
+ const selectedRun = useMemo(() => scopedRuns.find((run) => run.eventSeriesId === selectedRunId) ?? (scopedRuns.length === 1 ? scopedRuns[0] ?? null : null), [scopedRuns, selectedRunId]);
16850
17202
  const [selectedPricingOptionId, setSelectedPricingOptionId] = useState(null);
16851
17203
  const [selectedSlidingAmountInput, setSelectedSlidingAmountInput] = useState("");
16852
17204
  const goToStep = useCallback((nextStep) => {
16853
17205
  setStep(nextStep);
16854
17206
  }, []);
16855
- const chooseCourse = useCallback((course) => {
16856
- setSelectedCourse(course);
17207
+ const chooseRun = useCallback((run) => {
17208
+ setSelectedRunId(run.eventSeriesId);
16857
17209
  }, []);
16858
17210
  const choosePricingOption = useCallback((pricingOptionId) => {
16859
17211
  setSelectedPricingOptionId(pricingOptionId);
@@ -16861,36 +17213,36 @@ function useCourseRegistrationSelection(props) {
16861
17213
  const changeSlidingAmount = useCallback((amount) => {
16862
17214
  setSelectedSlidingAmountInput(amount);
16863
17215
  }, []);
16864
- const selectedCoursePricing = useMemo(() => selectedCourse ? resolveCoursePricingState(selectedCourse, selectedPricingOptionId, parseCurrencyInputToCents(selectedSlidingAmountInput)) : null, [
16865
- selectedCourse,
17216
+ const selectedRunPricing = useMemo(() => selectedRun ? resolveWholeSeriesPricingState(selectedRun, selectedPricingOptionId, parseCurrencyInputToCents(selectedSlidingAmountInput)) : null, [
17217
+ selectedRun,
16866
17218
  selectedPricingOptionId,
16867
17219
  selectedSlidingAmountInput
16868
17220
  ]);
16869
17221
  useEffect(() => {
16870
- if (!selectedCourse) {
17222
+ if (!selectedRun) {
16871
17223
  setSelectedPricingOptionId(null);
16872
17224
  setSelectedSlidingAmountInput("");
16873
17225
  return;
16874
17226
  }
16875
- const selection = defaultCoursePricingSelection(resolveCoursePricingState(selectedCourse, null), selectedPricingOptionId);
17227
+ const selection = defaultWholeSeriesPricingSelection(resolveWholeSeriesPricingState(selectedRun, null), selectedPricingOptionId);
16876
17228
  setSelectedPricingOptionId(selection.pricingOptionId);
16877
17229
  setSelectedSlidingAmountInput(selection.slidingAmountInput);
16878
- }, [selectedCourse]);
17230
+ }, [selectedRun?.eventSeriesId]);
16879
17231
  return {
16880
- scopedCourses,
17232
+ scopedRuns,
16881
17233
  step,
16882
17234
  goToStep,
16883
- selectedCourse,
16884
- chooseCourse,
17235
+ selectedRun,
17236
+ chooseRun,
16885
17237
  selectedPricingOptionId,
16886
17238
  choosePricingOption,
16887
17239
  selectedSlidingAmountInput,
16888
17240
  changeSlidingAmount,
16889
- selectedCoursePricing
17241
+ selectedRunPricing
16890
17242
  };
16891
17243
  }
16892
17244
  //#endregion
16893
- //#region ../blocks/src/system/runtime/nodes/course-registration/useCoursePaymentVerification.ts
17245
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesPaymentVerification.ts
16894
17246
  function applyTerminalStatus(status, setters) {
16895
17247
  if (status === "enrolled" || status === "completed") {
16896
17248
  setters.setEnrollmentResult({
@@ -16912,7 +17264,7 @@ function applyTerminalStatus(status, setters) {
16912
17264
  setters.setStep("error");
16913
17265
  return true;
16914
17266
  }
16915
- async function pollCourseRegistrationStatus(api, sessionId, setters, isCancelled) {
17267
+ async function pollWholeSeriesRegistrationStatus(api, sessionId, setters, isCancelled) {
16916
17268
  const startedAt = Date.now();
16917
17269
  while (!isCancelled()) {
16918
17270
  try {
@@ -16933,21 +17285,21 @@ async function pollCourseRegistrationStatus(api, sessionId, setters, isCancelled
16933
17285
  await new Promise((resolve) => setTimeout(resolve, 1500));
16934
17286
  }
16935
17287
  }
16936
- function useCoursePaymentVerification(api, setters) {
17288
+ function useWholeSeriesPaymentVerification(api, setters, anchorId = WHOLE_SERIES_REGISTRATION_ANCHOR_ID, location = window.location) {
16937
17289
  useEffect(() => {
16938
17290
  let cancelled = false;
16939
- const enrollment = new URLSearchParams(window.location.search).get("enrollment");
16940
- const sessionId = getCourseCheckoutSessionId();
17291
+ const enrollment = new URLSearchParams(location.search).get("enrollment");
17292
+ const sessionId = getWholeSeriesCheckoutSessionId(location);
16941
17293
  if (enrollment === "cancelled") {
16942
- scrollToBlock(COURSE_REGISTRATION_ANCHOR_ID);
17294
+ scrollToBlock(anchorId);
16943
17295
  setters.setErrorMessage("Payment was cancelled. You can try again.");
16944
17296
  setters.setStep("error");
16945
17297
  return;
16946
17298
  }
16947
17299
  if (enrollment !== "success" || !sessionId) return;
16948
- scrollToBlock(COURSE_REGISTRATION_ANCHOR_ID);
17300
+ scrollToBlock(anchorId);
16949
17301
  setters.setStep("verifying-payment");
16950
- pollCourseRegistrationStatus(api, sessionId, setters, () => cancelled);
17302
+ pollWholeSeriesRegistrationStatus(api, sessionId, setters, () => cancelled);
16951
17303
  return () => {
16952
17304
  cancelled = true;
16953
17305
  };
@@ -16955,11 +17307,13 @@ function useCoursePaymentVerification(api, setters) {
16955
17307
  api,
16956
17308
  setters.setEnrollmentResult,
16957
17309
  setters.setErrorMessage,
16958
- setters.setStep
17310
+ setters.setStep,
17311
+ anchorId,
17312
+ location
16959
17313
  ]);
16960
17314
  }
16961
17315
  //#endregion
16962
- //#region ../blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationActions.ts
17316
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationActions.ts
16963
17317
  function blocked(message, setters) {
16964
17318
  setters.setErrorMessage(message);
16965
17319
  setters.setStep("error");
@@ -16969,16 +17323,16 @@ function blocked(message, setters) {
16969
17323
  };
16970
17324
  }
16971
17325
  function validateSubmission(state, setters) {
16972
- if (!state.selectedCourse) return {
17326
+ if (!state.selectedRun) return {
16973
17327
  kind: "blocked",
16974
17328
  message: "Choose an available set of dates to continue."
16975
17329
  };
16976
17330
  const errors = validateFormData$1(state.formData);
16977
17331
  setters.setErrors(errors);
16978
17332
  if (Object.keys(errors).length > 0) return { kind: "validation-failed" };
16979
- const pricingMessage = getMissingCoursePricingSelectionMessage(state.pricing);
17333
+ const pricingMessage = getMissingWholeSeriesPricingSelectionMessage(state.pricing);
16980
17334
  if (pricingMessage) return blocked(pricingMessage, setters);
16981
- if (!state.hasClaim && state.eligibility?.isFull && !state.eligibility.canJoinWaitlist) return blocked(state.eligibility.reason ?? "This course is fully booked.", setters);
17335
+ if (!state.hasClaim && state.eligibility?.isFull && !state.eligibility.canJoinWaitlist) return blocked(state.eligibility.reason ?? "This run is fully booked.", setters);
16982
17336
  if (isSpamProtectionEnabled() && !state.altchaSolution) return blocked("Please complete the verification check.", setters);
16983
17337
  return null;
16984
17338
  }
@@ -16991,8 +17345,8 @@ function enrollmentPayload(state, payment) {
16991
17345
  }
16992
17346
  function registrantPayload(state) {
16993
17347
  return {
16994
- eventSeriesId: state.selectedCourse.eventSeriesId,
16995
- ...buildCoursePricingOptionPayload(state.pricing),
17348
+ eventSeriesId: state.selectedRun.eventSeriesId,
17349
+ ...buildWholeSeriesPricingOptionPayload(state.pricing),
16996
17350
  email: state.formData.email.trim().toLowerCase(),
16997
17351
  name: state.formData.name.trim(),
16998
17352
  phone: state.formData.phone.trim() || void 0,
@@ -17025,7 +17379,7 @@ async function enroll(state, setters, payment) {
17025
17379
  async function checkout(state, setters) {
17026
17380
  setters.setStep("submitting");
17027
17381
  try {
17028
- const urls = buildCheckoutReturnUrls("enrollment", COURSE_REGISTRATION_ANCHOR_ID);
17382
+ const urls = buildCheckoutReturnUrls("enrollment", state.options.anchorId ?? "event-registration");
17029
17383
  const result = await state.api.createWholeSeriesCheckout({
17030
17384
  ...registrantPayload(state),
17031
17385
  discountCode: state.discountCode.trim() || void 0,
@@ -17060,10 +17414,10 @@ async function checkout(state, setters) {
17060
17414
  }
17061
17415
  async function submitDetails(state, setters) {
17062
17416
  const invalid = validateSubmission(state, setters);
17063
- if (invalid || !state.selectedCourse) return invalid ?? { kind: "validation-failed" };
17417
+ if (invalid || !state.selectedRun) return invalid ?? { kind: "validation-failed" };
17064
17418
  if (state.eligibility?.canJoinWaitlist) return enroll(state, setters, { method: "free" });
17065
17419
  const requiresPayment = state.pricing?.selectedRequiresPayment ?? false;
17066
- const canUseMembership = requiresPayment && state.selectedCourse.acceptsMemberships && state.portalAuthState === "authenticated" && state.eligibleMemberships.length > 0;
17420
+ const canUseMembership = requiresPayment && state.selectedRun.acceptsMemberships && state.portalAuthState === "authenticated" && state.eligibleMemberships.length > 0;
17067
17421
  if (requiresPayment && canUseMembership) {
17068
17422
  setters.setStep("select-payment");
17069
17423
  return { kind: "state-updated" };
@@ -17073,7 +17427,7 @@ async function submitDetails(state, setters) {
17073
17427
  }
17074
17428
  async function continuePayment(state, setters) {
17075
17429
  const invalid = validateSubmission(state, setters);
17076
- if (invalid || !state.selectedCourse) return invalid ?? { kind: "validation-failed" };
17430
+ if (invalid || !state.selectedRun) return invalid ?? { kind: "validation-failed" };
17077
17431
  if (!state.pricing?.selectedRequiresPayment) {
17078
17432
  setters.setStep("enter-details");
17079
17433
  return { kind: "state-updated" };
@@ -17088,7 +17442,7 @@ async function continuePayment(state, setters) {
17088
17442
  }
17089
17443
  return checkout(selectedState, setters);
17090
17444
  }
17091
- function useCourseRegistrationActions(state, setStep) {
17445
+ function useWholeSeriesRegistrationActions(state, setStep) {
17092
17446
  const [errors, setErrors] = useState({});
17093
17447
  const [enrollmentResult, setEnrollmentResult] = useState(null);
17094
17448
  const [errorMessage, setErrorMessage] = useState("");
@@ -17115,14 +17469,14 @@ function useCourseRegistrationActions(state, setStep) {
17115
17469
  };
17116
17470
  }
17117
17471
  //#endregion
17118
- //#region ../blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationPortal.ts
17472
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationPortal.ts
17119
17473
  const EMPTY_FORM = {
17120
17474
  name: "",
17121
17475
  email: "",
17122
17476
  phone: "",
17123
17477
  notes: ""
17124
17478
  };
17125
- function useCourseRegistrationPortal(api) {
17479
+ function useWholeSeriesRegistrationPortal(api) {
17126
17480
  const [formData, setFormData] = useState(EMPTY_FORM);
17127
17481
  const [portalAuthState, setPortalAuthState] = useState("checking");
17128
17482
  const updateFormData = useCallback((updater) => {
@@ -17158,19 +17512,19 @@ function useCourseRegistrationPortal(api) {
17158
17512
  };
17159
17513
  }
17160
17514
  //#endregion
17161
- //#region ../blocks/src/system/runtime/nodes/course-registration/useCourseWaitlistSelection.ts
17162
- function useCourseWaitlistSelection(input) {
17515
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesWaitlistSelection.ts
17516
+ function useWholeSeriesWaitlistSelection(input) {
17163
17517
  useEffect(() => {
17164
17518
  const claim = input.waitlistClaim.claim;
17165
17519
  if (!claim || claim.subject.kind !== "whole_series") return;
17166
17520
  const eventSeriesId = claim.subject.eventSeriesId;
17167
- const course = input.scopedCourses.find((candidate) => candidate.eventSeriesId === eventSeriesId);
17168
- if (!course) {
17169
- input.reportError("This waitlist claim is for a different course.");
17521
+ const run = input.scopedRuns.find((candidate) => candidate.eventSeriesId === eventSeriesId);
17522
+ if (!run) {
17523
+ input.reportError("This waitlist claim is for a different run.");
17170
17524
  input.goToStep("error");
17171
17525
  return;
17172
17526
  }
17173
- input.chooseCourse(course);
17527
+ input.chooseRun(run);
17174
17528
  input.updateFormData((current) => ({
17175
17529
  ...current,
17176
17530
  email: claim.prefill.email,
@@ -17178,12 +17532,12 @@ function useCourseWaitlistSelection(input) {
17178
17532
  phone: claim.prefill.phone ?? "",
17179
17533
  notes: claim.prefill.notes ?? ""
17180
17534
  }));
17181
- if (input.step === "select-course") input.goToStep("enter-details");
17535
+ if (input.step === "select-run") input.goToStep("enter-details");
17182
17536
  }, [
17183
- input.chooseCourse,
17537
+ input.chooseRun,
17184
17538
  input.goToStep,
17185
17539
  input.reportError,
17186
- input.scopedCourses,
17540
+ input.scopedRuns,
17187
17541
  input.step,
17188
17542
  input.updateFormData,
17189
17543
  input.waitlistClaim.claim
@@ -17200,40 +17554,48 @@ function useCourseWaitlistSelection(input) {
17200
17554
  ]);
17201
17555
  }
17202
17556
  //#endregion
17203
- //#region ../blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.ts
17204
- function useCourseRegistrationWizard(props, options = {}) {
17557
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/useWholeSeriesRegistrationWizard.ts
17558
+ function useWholeSeriesRegistrationWizard(props, options = {}) {
17559
+ return useWholeSeriesRegistrationWizardWithDeps(wholeSeriesRegistrationWizardDeps, props, options);
17560
+ }
17561
+ const wholeSeriesRegistrationWizardDeps = { readLocation: () => ({
17562
+ search: window.location.search,
17563
+ hash: window.location.hash
17564
+ }) };
17565
+ function useWholeSeriesRegistrationWizardWithDeps(deps, props, options = {}) {
17205
17566
  const api = useBlockApi();
17206
- const selection = useCourseRegistrationSelection(props);
17207
- const portal = useCourseRegistrationPortal(api);
17208
- const waitlistClaim = useWaitlistClaim();
17567
+ const [location] = useState(deps.readLocation);
17568
+ const selection = useWholeSeriesRegistrationSelection(props, location);
17569
+ const portal = useWholeSeriesRegistrationPortal(api);
17570
+ const waitlistClaim = useWaitlistClaimForToken(new URLSearchParams(location.search).get("waitlist_claim")?.trim() || null);
17209
17571
  const [bookingMode, setBookingMode] = useState(null);
17210
17572
  const [altchaSolution, setAltchaSolution] = useState(null);
17211
- const eligibility = useCourseEligibility({
17573
+ const eligibility = useWholeSeriesEligibility({
17212
17574
  api,
17213
- selectedCourse: selection.selectedCourse,
17214
- hasPaidSelection: selection.selectedCoursePricing?.hasPaidSelection ?? false,
17575
+ selectedRun: selection.selectedRun,
17576
+ hasPaidSelection: selection.selectedRunPricing?.hasPaidSelection ?? false,
17215
17577
  portalAuthState: portal.portalAuthState,
17216
17578
  waitlistClaimToken: waitlistClaim.token
17217
17579
  });
17218
17580
  const discountUi = useDiscountCodeUi({
17219
17581
  api,
17220
- discountContext: useMemo(() => selection.selectedCourse && selection.selectedCoursePricing?.selectedRequiresPayment && eligibility.paymentChoice === "checkout" ? {
17582
+ discountContext: useMemo(() => selection.selectedRun && selection.selectedRunPricing?.selectedRequiresPayment && eligibility.paymentChoice === "checkout" ? {
17221
17583
  type: "whole_series",
17222
- eventSeriesId: selection.selectedCourse.eventSeriesId
17584
+ eventSeriesId: selection.selectedRun.eventSeriesId
17223
17585
  } : null, [
17224
17586
  eligibility.paymentChoice,
17225
- selection.selectedCourse,
17226
- selection.selectedCoursePricing?.selectedRequiresPayment
17587
+ selection.selectedRun,
17588
+ selection.selectedRunPricing?.selectedRequiresPayment
17227
17589
  ]),
17228
- subtotalCents: selection.selectedCoursePricing?.selectedPriceAmount ?? void 0
17590
+ subtotalCents: selection.selectedRunPricing?.selectedPriceAmount ?? void 0
17229
17591
  });
17230
- const actions = useCourseRegistrationActions({
17592
+ const actions = useWholeSeriesRegistrationActions({
17231
17593
  api,
17232
- selectedCourse: selection.selectedCourse,
17233
- pricing: selection.selectedCoursePricing,
17594
+ selectedRun: selection.selectedRun,
17595
+ pricing: selection.selectedRunPricing,
17234
17596
  formData: portal.formData,
17235
17597
  portalAuthState: portal.portalAuthState,
17236
- eligibility: eligibility.courseEligibility,
17598
+ eligibility: eligibility.runEligibility,
17237
17599
  eligibleMemberships: eligibility.eligibleMemberships,
17238
17600
  paymentChoice: eligibility.paymentChoice,
17239
17601
  selectedMembershipId: eligibility.selectedMembershipId,
@@ -17243,14 +17605,16 @@ function useCourseRegistrationWizard(props, options = {}) {
17243
17605
  discountCode: discountUi.discountCode,
17244
17606
  options
17245
17607
  }, selection.goToStep);
17246
- useCourseRegistrationEffects({
17608
+ useWholeSeriesRegistrationEffects({
17247
17609
  api,
17248
17610
  actions,
17249
17611
  portal,
17250
17612
  selection,
17251
- waitlistClaim
17613
+ waitlistClaim,
17614
+ anchorId: options.anchorId ?? "event-registration",
17615
+ location
17252
17616
  });
17253
- return buildCourseRegistrationWizardResult({
17617
+ return buildWholeSeriesRegistrationWizardResult({
17254
17618
  api,
17255
17619
  selection,
17256
17620
  portal,
@@ -17258,10 +17622,10 @@ function useCourseRegistrationWizard(props, options = {}) {
17258
17622
  actions,
17259
17623
  discountUi,
17260
17624
  waitlistClaim,
17261
- view: deriveCourseRegistrationViewState({
17262
- scopedCourses: selection.scopedCourses,
17263
- selectedCourse: selection.selectedCourse,
17264
- pricing: selection.selectedCoursePricing,
17625
+ view: deriveWholeSeriesRegistrationViewState({
17626
+ scopedRuns: selection.scopedRuns,
17627
+ selectedRun: selection.selectedRun,
17628
+ pricing: selection.selectedRunPricing,
17265
17629
  portalAuthState: portal.portalAuthState,
17266
17630
  eligibleMembershipCount: eligibility.eligibleMemberships.length,
17267
17631
  bookingMode,
@@ -17271,26 +17635,27 @@ function useCourseRegistrationWizard(props, options = {}) {
17271
17635
  bookingMode,
17272
17636
  setBookingMode,
17273
17637
  altchaSolution,
17274
- setAltchaSolution
17638
+ setAltchaSolution,
17639
+ anchorId: options.anchorId ?? "event-registration"
17275
17640
  });
17276
17641
  }
17277
- function useCourseRegistrationEffects(input) {
17278
- useCoursePaymentVerification(input.api, {
17642
+ function useWholeSeriesRegistrationEffects(input) {
17643
+ useWholeSeriesPaymentVerification(input.api, {
17279
17644
  setStep: input.selection.goToStep,
17280
17645
  setErrorMessage: input.actions.reportError,
17281
17646
  setEnrollmentResult: input.actions.recordEnrollmentResult
17282
- });
17283
- useCourseWaitlistSelection({
17647
+ }, input.anchorId, input.location);
17648
+ useWholeSeriesWaitlistSelection({
17284
17649
  waitlistClaim: input.waitlistClaim,
17285
- scopedCourses: input.selection.scopedCourses,
17650
+ scopedRuns: input.selection.scopedRuns,
17286
17651
  step: input.selection.step,
17287
17652
  goToStep: input.selection.goToStep,
17288
- chooseCourse: input.selection.chooseCourse,
17653
+ chooseRun: input.selection.chooseRun,
17289
17654
  updateFormData: input.portal.updateFormData,
17290
17655
  reportError: input.actions.reportError
17291
17656
  });
17292
17657
  }
17293
- function buildCourseRegistrationWizardResult(parts) {
17658
+ function buildWholeSeriesRegistrationWizardResult(parts) {
17294
17659
  const handleBookingModeChange = (mode) => {
17295
17660
  parts.setBookingMode(mode);
17296
17661
  parts.eligibility.choosePaymentChoice(mode === "membership" ? "membership" : "checkout");
@@ -17314,30 +17679,30 @@ function buildCourseRegistrationWizardResult(parts) {
17314
17679
  manualCodeEntryAllowed: parts.discountUi.manualCodeEntryAllowed,
17315
17680
  discountsAvailableLoading: parts.discountUi.discountsAvailableLoading,
17316
17681
  ...parts.view,
17317
- handleCourseSelect: (course) => {
17318
- parts.selection.chooseCourse(course);
17682
+ handleRunSelect: (run) => {
17683
+ parts.selection.chooseRun(run);
17319
17684
  parts.selection.goToStep("enter-details");
17320
17685
  },
17321
17686
  handleRetry: () => {
17322
- parts.selection.goToStep(parts.selection.scopedCourses.length === 1 ? "enter-details" : "select-course");
17687
+ parts.selection.goToStep(parts.selection.scopedRuns.length === 1 ? "enter-details" : "select-run");
17323
17688
  parts.actions.reportError("");
17324
17689
  },
17325
17690
  handleBookingModeChange,
17326
- handleLogout: parts.portal.portalAuthState === "authenticated" ? () => logoutPortal(COURSE_REGISTRATION_ANCHOR_ID) : void 0,
17327
- selectedCoursePricingPayload: buildCoursePricingOptionPayload(parts.selection.selectedCoursePricing)
17691
+ handleLogout: parts.portal.portalAuthState === "authenticated" ? () => logoutPortal(parts.anchorId) : void 0,
17692
+ selectedRunPricingPayload: buildWholeSeriesPricingOptionPayload(parts.selection.selectedRunPricing)
17328
17693
  };
17329
17694
  }
17330
17695
  //#endregion
17331
- //#region ../blocks/src/system/runtime/nodes/course-registration/whole-series-registration.headless.planning.ts
17696
+ //#region ../blocks/src/system/runtime/nodes/event-registration/whole-series/whole-series-registration.headless.planning.ts
17332
17697
  const STEP_IDS = {
17333
- "select-course": "select-run",
17698
+ "select-run": "select-run",
17334
17699
  "enter-details": "enter-details",
17335
17700
  "booking-mode": "select-booking-method",
17336
17701
  "select-payment": "select-payment"
17337
17702
  };
17338
17703
  function toPublicStepId(step) {
17339
17704
  switch (step) {
17340
- case "select-course":
17705
+ case "select-run":
17341
17706
  case "enter-details":
17342
17707
  case "booking-mode":
17343
17708
  case "select-payment": return STEP_IDS[step];
@@ -17397,7 +17762,7 @@ function resolveWholeSeriesRegistrationStatus(wizard) {
17397
17762
  tag: "error",
17398
17763
  message: wizard.errorMessage
17399
17764
  };
17400
- case "select-course":
17765
+ case "select-run":
17401
17766
  case "enter-details":
17402
17767
  case "booking-mode":
17403
17768
  case "select-payment": return { tag: "ready" };
@@ -17431,7 +17796,7 @@ function resolveWholeSeriesRegistrationView(wizard) {
17431
17796
  kind: "error",
17432
17797
  message: "Waitlist registration completed without a result."
17433
17798
  };
17434
- case "select-course":
17799
+ case "select-run":
17435
17800
  case "enter-details":
17436
17801
  case "booking-mode":
17437
17802
  case "select-payment":
@@ -17468,7 +17833,7 @@ function resolveWholeSeriesPaymentSelection(input) {
17468
17833
  }
17469
17834
  //#endregion
17470
17835
  //#region ../blocks/src/system/runtime/hooks/useHeadlessWholeSeriesRegistrationFlow.ts
17471
- const wholeSeriesRegistrationControllerDeps = { useCourseRegistrationWizard };
17836
+ const wholeSeriesRegistrationControllerDeps = { useWholeSeriesRegistrationWizard };
17472
17837
  function createWholeSeriesRegistrationBlockApiConfig(input) {
17473
17838
  return {
17474
17839
  baseUrl: input.apiBaseUrl,
@@ -17494,8 +17859,8 @@ function useHeadlessWholeSeriesRegistrationFlow(options) {
17494
17859
  return useWholeSeriesRegistrationControllerWithDeps(options, wholeSeriesRegistrationControllerDeps);
17495
17860
  }
17496
17861
  function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17497
- const wizard = deps.useCourseRegistrationWizard({
17498
- courses: (options.runs ?? []).map(toPublicCourse),
17862
+ const wizard = deps.useWholeSeriesRegistrationWizard({
17863
+ runs: (options.runs ?? []).map(toPublicWholeSeriesOffering),
17499
17864
  subject: options.subject ?? null
17500
17865
  }, { onCheckoutRedirect: () => {} });
17501
17866
  const steps = useMemo(() => deriveWholeSeriesRegistrationSteps({
@@ -17503,11 +17868,11 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17503
17868
  step: wizard.step
17504
17869
  }), [wizard.step, wizard.wizardSteps]);
17505
17870
  const currentStep = steps.find((step) => step.state === "active") ?? null;
17506
- const pricingSelection = resolveWholeSeriesPricingSelection(wizard.selectedCoursePricing);
17871
+ const pricingSelection = resolveWholeSeriesPricingSelection(wizard.selectedRunPricing);
17507
17872
  const paymentSelection = resolveWholeSeriesPaymentSelection({
17508
17873
  paymentChoice: wizard.paymentChoice,
17509
17874
  selectedMembershipId: wizard.selectedMembershipId,
17510
- required: wizard.selectedCoursePricing?.selectedRequiresPayment ?? false
17875
+ required: wizard.selectedRunPricing?.selectedRequiresPayment ?? false
17511
17876
  });
17512
17877
  const updateRegistrant = useCallback((values) => wizard.updateFormData(values), [wizard]);
17513
17878
  const setSlidingAmountCents = useCallback((amount) => {
@@ -17533,8 +17898,8 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17533
17898
  const blocked = resolveActionBlocker(wizard);
17534
17899
  if (blocked) return blocked;
17535
17900
  switch (wizard.step) {
17536
- case "select-course":
17537
- if (!wizard.selectedCourse) return {
17901
+ case "select-run":
17902
+ if (!wizard.selectedRun) return {
17538
17903
  ok: false,
17539
17904
  reason: "blocked",
17540
17905
  message: "Choose an available set of dates to continue."
@@ -17564,7 +17929,7 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17564
17929
  const back = useCallback(() => {
17565
17930
  switch (wizard.step) {
17566
17931
  case "enter-details":
17567
- if (!wizard.hasPreSelectedCourse) wizard.goToStep("select-course");
17932
+ if (!wizard.hasPreSelectedRun) wizard.goToStep("select-run");
17568
17933
  return;
17569
17934
  case "booking-mode":
17570
17935
  wizard.goToStep("enter-details");
@@ -17572,7 +17937,7 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17572
17937
  case "select-payment":
17573
17938
  wizard.goToStep(wizard.canUseMembership ? "booking-mode" : "enter-details");
17574
17939
  return;
17575
- case "select-course":
17940
+ case "select-run":
17576
17941
  case "submitting":
17577
17942
  case "redirecting":
17578
17943
  case "verifying-payment":
@@ -17584,7 +17949,7 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17584
17949
  }
17585
17950
  }, [wizard]);
17586
17951
  const payment = {
17587
- required: wizard.selectedCoursePricing?.selectedRequiresPayment ?? false,
17952
+ required: wizard.selectedRunPricing?.selectedRequiresPayment ?? false,
17588
17953
  selection: paymentSelection,
17589
17954
  canUseMembership: wizard.canUseMembership,
17590
17955
  eligibleMemberships: wizard.eligibleMemberships.map((membership) => ({
@@ -17594,7 +17959,7 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17594
17959
  eligibility: wizard.eligibilityLoading ? { tag: "loading" } : wizard.eligibilityError ? {
17595
17960
  tag: "error",
17596
17961
  message: wizard.eligibilityError
17597
- } : wizard.courseEligibility || wizard.portalAuthState !== "checking" ? { tag: "loaded" } : { tag: "idle" }
17962
+ } : wizard.runEligibility || wizard.portalAuthState !== "checking" ? { tag: "loaded" } : { tag: "idle" }
17598
17963
  };
17599
17964
  const spamProtection = wizard.showSpamProtection ? {
17600
17965
  enabled: true,
@@ -17605,13 +17970,13 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17605
17970
  },
17606
17971
  solution: wizard.altchaSolution
17607
17972
  } : { enabled: false };
17608
- const selectedRun = wizard.selectedCourse;
17609
- const isFull = wizard.courseEligibility?.isFull ?? (selectedRun?.availableSpots !== null && selectedRun?.availableSpots !== void 0 ? selectedRun.availableSpots <= 0 : false);
17973
+ const selectedRun = wizard.selectedRun;
17974
+ const isFull = wizard.runEligibility?.isFull ?? (selectedRun?.availableSpots !== null && selectedRun?.availableSpots !== void 0 ? selectedRun.availableSpots <= 0 : false);
17610
17975
  return {
17611
17976
  status: resolveWholeSeriesRegistrationStatus(wizard),
17612
17977
  view: resolveWholeSeriesRegistrationView({
17613
17978
  step: wizard.step,
17614
- scopedRunsCount: wizard.scopedCourses.length,
17979
+ scopedRunsCount: wizard.scopedRuns.length,
17615
17980
  selectedRun,
17616
17981
  enrollmentResult: wizard.enrollmentResult,
17617
17982
  errorMessage: wizard.errorMessage
@@ -17619,10 +17984,10 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17619
17984
  steps,
17620
17985
  currentStep,
17621
17986
  runs: {
17622
- items: (options.runs ?? []).map((run) => toWholeSeriesRegistrationRun(toPublicCourse(run))),
17623
- scoped: wizard.scopedCourses.map(toWholeSeriesRegistrationRun),
17987
+ items: (options.runs ?? []).map((run) => toWholeSeriesRegistrationRun(toPublicWholeSeriesOffering(run))),
17988
+ scoped: wizard.scopedRuns.map(toWholeSeriesRegistrationRun),
17624
17989
  selected: selectedRun ? toWholeSeriesRegistrationRun(selectedRun) : null,
17625
- hasPreSelectedRun: wizard.hasPreSelectedCourse,
17990
+ hasPreSelectedRun: wizard.hasPreSelectedRun,
17626
17991
  subject: options.subject ?? null
17627
17992
  },
17628
17993
  registrant: {
@@ -17630,7 +17995,7 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17630
17995
  errors: wizard.errors
17631
17996
  },
17632
17997
  pricing: {
17633
- ...toWholeSeriesRegistrationPricing(wizard.selectedCoursePricing),
17998
+ ...toWholeSeriesRegistrationPricing(wizard.selectedRunPricing),
17634
17999
  selectedOptionId: wizard.selectedPricingOptionId,
17635
18000
  selection: pricingSelection
17636
18001
  },
@@ -17646,8 +18011,8 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17646
18011
  enrollmentOpen: selectedRun?.enrollmentOpen ?? false,
17647
18012
  availableSpots: selectedRun?.availableSpots ?? null,
17648
18013
  isFull,
17649
- canJoinWaitlist: wizard.courseEligibility?.canJoinWaitlist ?? false,
17650
- message: wizard.courseEligibility?.reason ?? null
18014
+ canJoinWaitlist: wizard.runEligibility?.canJoinWaitlist ?? false,
18015
+ message: wizard.runEligibility?.reason ?? null
17651
18016
  },
17652
18017
  portalAuth: {
17653
18018
  state: wizard.portalAuthState,
@@ -17661,8 +18026,8 @@ function useWholeSeriesRegistrationControllerWithDeps(options, deps) {
17661
18026
  },
17662
18027
  actions: {
17663
18028
  selectRun: (runId) => {
17664
- const run = wizard.scopedCourses.find((candidate) => candidate.eventSeriesId === runId) ?? null;
17665
- if (run) wizard.handleCourseSelect(run);
18029
+ const run = wizard.scopedRuns.find((candidate) => candidate.eventSeriesId === runId) ?? null;
18030
+ if (run) wizard.handleRunSelect(run);
17666
18031
  },
17667
18032
  updateRegistrant,
17668
18033
  selectPricingOption: wizard.choosePricingOption,
@@ -17706,8 +18071,8 @@ function toHeadlessActionResult(result) {
17706
18071
  };
17707
18072
  }
17708
18073
  }
17709
- function toPublicCourse(run) {
17710
- const pricing = toCoursePricing(run.pricing);
18074
+ function toPublicWholeSeriesOffering(run) {
18075
+ const pricing = toWholeSeriesPricing(run.pricing);
17711
18076
  return {
17712
18077
  eventSeriesId: run.registrationTarget.eventSeriesId,
17713
18078
  eventOfferingId: run.eventOfferingId,
@@ -17732,7 +18097,7 @@ function toPublicCourse(run) {
17732
18097
  venue: run.venue
17733
18098
  };
17734
18099
  }
17735
- function toCoursePricing(pricing) {
18100
+ function toWholeSeriesPricing(pricing) {
17736
18101
  const common = {
17737
18102
  bookingRequirement: pricing.bookingRequirement,
17738
18103
  pricingStrategy: pricing.pricingStrategy,
@@ -17859,8 +18224,8 @@ function resolveWaitlistClaim(wizard) {
17859
18224
  return { tag: "none" };
17860
18225
  }
17861
18226
  function resolveActionBlocker(wizard) {
17862
- if (!wizard.selectedCourse) return null;
17863
- if (!wizard.selectedCourse.enrollmentOpen) return {
18227
+ if (!wizard.selectedRun) return null;
18228
+ if (!wizard.selectedRun.enrollmentOpen) return {
17864
18229
  ok: false,
17865
18230
  reason: "blocked",
17866
18231
  message: "Sign-up is closed."
@@ -17870,10 +18235,10 @@ function resolveActionBlocker(wizard) {
17870
18235
  reason: "blocked",
17871
18236
  message: "Availability is still being checked."
17872
18237
  };
17873
- if (wizard.courseEligibility?.isFull && !wizard.courseEligibility.canJoinWaitlist) return {
18238
+ if (wizard.runEligibility?.isFull && !wizard.runEligibility.canJoinWaitlist) return {
17874
18239
  ok: false,
17875
18240
  reason: "blocked",
17876
- message: wizard.courseEligibility.reason ?? "There are no places available."
18241
+ message: wizard.runEligibility.reason ?? "There are no places available."
17877
18242
  };
17878
18243
  return null;
17879
18244
  }