@riverbankcms/sdk 0.146.0 → 0.147.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 (195) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/{PreviewEditorSidebar-kg2r2Fyi.mjs → PreviewEditorSidebar-DtpB3_sS.mjs} +51 -33
  3. package/dist/{PreviewEditorUI-sWMLp5dT.mjs → PreviewEditorUI-DxTLgaHo.mjs} +3 -3
  4. package/dist/{PreviewQueryProvider-Cg51xq1w.mjs → PreviewQueryProvider-Dd4dxOiU.mjs} +1 -1
  5. package/dist/{SdkPreviewModeRuntime-h2ti3Hch.mjs → SdkPreviewModeRuntime-DMMNCngt.mjs} +39 -12
  6. package/dist/{SiteChromeCustomizeContext-DEACFH9m.mjs → SiteChromeCustomizeContext-DQXZXiqS.mjs} +2499 -1682
  7. package/dist/_dts/ai/src/contracts/proposals.d.ts +198 -0
  8. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +18 -0
  9. package/dist/_dts/api/src/accountApi.d.ts +5 -5
  10. package/dist/_dts/api/src/bookingConfig.d.ts +16 -0
  11. package/dist/_dts/api/src/bookingManagementEndpoints.d.ts +4 -13
  12. package/dist/_dts/api/src/bookingOperations.d.ts +2 -44
  13. package/dist/_dts/api/src/bookingPeople.d.ts +92 -0
  14. package/dist/_dts/api/src/bookingPeopleEndpointDefinitions.d.ts +38 -0
  15. package/dist/_dts/api/src/bookingRecords.d.ts +11 -49
  16. package/dist/_dts/api/src/bookingSettingsSections.d.ts +1 -1
  17. package/dist/_dts/api/src/bookings.d.ts +1 -0
  18. package/dist/_dts/api/src/endpoints.d.ts +587 -561
  19. package/dist/_dts/api/src/eventManagementContracts.d.ts +23 -8
  20. package/dist/_dts/api/src/eventManagementEndpointDefinitions.d.ts +1 -1
  21. package/dist/_dts/api/src/index.d.ts +3 -2
  22. package/dist/_dts/api/src/indexCoreTypes.d.ts +1 -1
  23. package/dist/_dts/api/src/launchReadiness.d.ts +1 -6
  24. package/dist/_dts/api/src/mailingListIntegration.d.ts +6 -0
  25. package/dist/_dts/api/src/navigation/dashboardBookingsNav.d.ts +1 -1
  26. package/dist/_dts/api/src/newsletterEndpointDefinitions.d.ts +15 -0
  27. package/dist/_dts/api/src/occurrenceScheduling.d.ts +19 -0
  28. package/dist/_dts/api/src/publicAppointmentBookingContracts.d.ts +48 -0
  29. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +7 -0
  30. package/dist/_dts/api/src/sdk-event-upsert.d.ts +15 -0
  31. package/dist/_dts/api/src/sdkCourseBooking.d.ts +4 -4
  32. package/dist/_dts/api/src/siteLifecycleEndpoints.d.ts +61 -0
  33. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -18
  34. package/dist/_dts/api/src/siteOnboarding.d.ts +2 -14
  35. package/dist/_dts/blocks/src/PageRenderer.d.ts +3 -4
  36. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +8 -0
  37. package/dist/_dts/blocks/src/index.d.ts +1 -1
  38. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +22 -4
  39. package/dist/_dts/blocks/src/pageRendererContracts.d.ts +2 -0
  40. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +4 -1
  41. package/dist/_dts/blocks/src/system/runtime/api/types/appointments.d.ts +4 -0
  42. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +12 -0
  43. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +12 -0
  44. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +6 -0
  45. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessBookingFlow.d.ts +8 -0
  46. package/dist/_dts/blocks/src/system/runtime/hooks/useHeadlessEventRegistrationFlow.d.ts +2 -0
  47. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.completion.d.ts +9 -0
  48. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.headless.state.d.ts +9 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.interactive.d.ts +19 -0
  50. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.mailing-list-choice.d.ts +5 -0
  51. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.mailing-list-note.d.ts +3 -0
  52. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.mailing-list-state.d.ts +9 -0
  53. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.reserved-fields.d.ts +1 -1
  54. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.server.d.ts +1 -1
  55. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.state.d.ts +2 -0
  56. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-handler.d.ts +8 -0
  57. package/dist/_dts/blocks/src/system/runtime/nodes/booking-form.submit-success.d.ts +9 -0
  58. package/dist/_dts/blocks/src/system/runtime/nodes/booking-runtime-sources.d.ts +3 -0
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/AttendeeDetailsStep.d.ts +3 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/SuccessStep.d.ts +3 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +3 -0
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/sessionStorage.d.ts +2 -0
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +6 -0
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.d.ts +3 -0
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +8 -0
  66. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +9 -0
  67. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.block-submission.d.ts +2 -4
  68. package/dist/_dts/blocks/src/system/runtime/resolver.d.ts +2 -0
  69. package/dist/_dts/blocks/src/system/runtime/shared/components/BookingMailingListNote.d.ts +6 -0
  70. package/dist/_dts/blocks/src/system/runtime/shared/mailingListSignupCopy.d.ts +6 -0
  71. package/dist/_dts/blocks/src/system/runtime/shared/types.d.ts +1 -0
  72. package/dist/_dts/blocks/src/system/transforms/registry/_utils/surfaceForegroundStyles.d.ts +3 -2
  73. package/dist/_dts/blocks/src/system/transforms/registry/core.d.ts +2 -0
  74. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +1 -3
  75. package/dist/_dts/core/src/index.d.ts +1 -1
  76. package/dist/_dts/core/src/mailing-list-runtime.d.ts +15 -0
  77. package/dist/_dts/core/src/mailing-list-setup.d.ts +2 -0
  78. package/dist/_dts/core/src/mailing-list-submission.d.ts +6 -0
  79. package/dist/_dts/core/src/navigation-portal-labels.d.ts +9 -0
  80. package/dist/_dts/core/src/participants.d.ts +0 -38
  81. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +102 -22
  82. package/dist/_dts/editor-blocks/src/block-editor/actionPresentation.d.ts +1 -0
  83. package/dist/_dts/preview-next/src/client/blocks/EditablePageRenderer.d.ts +7 -1
  84. package/dist/_dts/preview-next/src/client/blocks/composer/types.d.ts +4 -3
  85. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +1 -0
  86. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +1 -0
  87. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +1 -1
  88. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +2 -2
  89. package/dist/_dts/sdk/src/version.d.ts +1 -1
  90. package/dist/_dts/theme-core/src/buttons/effects/types.d.ts +1 -1
  91. package/dist/_dts/theme-core/src/footer/effectiveNavLinkStyle.d.ts +13 -0
  92. package/dist/_dts/theme-core/src/footer/index.d.ts +1 -0
  93. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  94. package/dist/_dts/theme-core/src/header/effectiveNavLinkStyle.d.ts +17 -0
  95. package/dist/_dts/theme-core/src/header/generateHeaderLogoStyles.d.ts +15 -0
  96. package/dist/_dts/theme-core/src/header/generateHeaderNavLinkStyles.d.ts +4 -0
  97. package/dist/_dts/theme-core/src/header/index.d.ts +3 -0
  98. package/dist/_dts/theme-core/src/header/legacyNavLinkStyle.d.ts +1 -1
  99. package/dist/_dts/theme-core/src/header/openingForegroundProjection.d.ts +7 -0
  100. package/dist/_dts/theme-core/src/header/rootPaint.d.ts +4 -0
  101. package/dist/_dts/theme-core/src/navigation/effectPolicy.d.ts +38 -0
  102. package/dist/_dts/theme-core/src/navigation/generateNavLinkCSS.d.ts +4 -0
  103. package/dist/_dts/theme-core/src/navigation/types.d.ts +4 -0
  104. package/dist/_dts/theme-core/src/site-styles/accessibleSurfaces.d.ts +1 -1
  105. package/dist/_dts/theme-core/src/surfaces/foregroundContract.d.ts +7 -0
  106. package/dist/_dts/theme-core/src/surfaces/foregroundInteraction.d.ts +29 -22
  107. package/dist/_dts/theme-core/src/surfaces/foregroundRoles.d.ts +10 -2
  108. package/dist/_dts/theme-core/src/surfaces/resolveSurfaceForeground.d.ts +9 -0
  109. package/dist/_dts/theme-core/src/utils/cssDeclarations.d.ts +2 -0
  110. package/dist/_dts/ui/src/badge.d.ts +2 -1
  111. package/dist/_dts/ui/src/button.d.ts +1 -1
  112. package/dist/_dts/ui/src/combobox-keys.d.ts +23 -0
  113. package/dist/_dts/ui/src/combobox-rows.d.ts +34 -0
  114. package/dist/_dts/ui/src/combobox.d.ts +26 -1
  115. package/dist/_dts/ui/src/date-picker.d.ts +5 -8
  116. package/dist/_dts/ui/src/editor-item-card.d.ts +1 -0
  117. package/dist/_dts/ui/src/field-trigger.d.ts +39 -0
  118. package/dist/_dts/ui/src/fieldControl.d.ts +27 -0
  119. package/dist/_dts/ui/src/index.d.ts +4 -1
  120. package/dist/_dts/ui/src/native-select.d.ts +8 -0
  121. package/dist/_dts/ui/src/popover.d.ts +7 -1
  122. package/dist/_dts/ui/src/segmented-control.d.ts +4 -0
  123. package/dist/_dts/ui/src/surface.d.ts +1 -1
  124. package/dist/client/{BookingConsentAgreement-BQKL045f.mjs → BookingMailingListNote-1n4Ch_u_.mjs} +15 -4
  125. package/dist/client/{CheckboxChoice--W2n6yKs.mjs → CheckboxChoice-B33MqoUo.mjs} +1 -1
  126. package/dist/client/{DiscountCodeDisclosure-CsOtjFY7.mjs → DiscountCodeDisclosure-CKJtz0mY.mjs} +1 -1
  127. package/dist/client/{EventCombined.client-BdRjVbhH.mjs → EventCombined.client-C0pgma9y.mjs} +7 -7
  128. package/dist/client/{EventListing.client-DBxC6xOU.mjs → EventListing.client-4fhLOvHP.mjs} +2 -2
  129. package/dist/client/{LeafletStaticMap-mHEJKrTs.mjs → LeafletStaticMap-DScC4F3w.mjs} +1 -1
  130. package/dist/client/{scrollToBlock-BNgaEUpo.mjs → TerminalPanel-B5ZUsYhe.mjs} +77 -77
  131. package/dist/client/{ThemedButton-CE5KYT6z.mjs → ThemedButton-DoVIV1Ao.mjs} +2 -2
  132. package/dist/client/{accordion-BEQNSptH.mjs → accordion-CoT5g7zo.mjs} +1 -1
  133. package/dist/client/{bookingForm-AMr-s5vw.mjs → bookingForm-BWxB46xD.mjs} +226 -106
  134. package/dist/client/bookings.mjs +367 -188
  135. package/dist/client/{carousel-Bbt_QgJy.mjs → carousel-DtNYWFd3.mjs} +2 -2
  136. package/dist/client/{carousel.client-jahpU9Vz.mjs → carousel.client-A2lG-9od.mjs} +1 -1
  137. package/dist/client/{cart-CnWi30zJ.mjs → cart-z4qZih1Y.mjs} +3 -3
  138. package/dist/client/{checkout-f3nkWgd4.mjs → checkout-DpL7euFH.mjs} +3 -3
  139. package/dist/client/{checkoutUrls-CW3-78uu.mjs → checkoutUrls-BEfR7kVu.mjs} +1 -1
  140. package/dist/client/client.mjs +2125 -1420
  141. package/dist/client/{colorStyles-CuJBiS-1.mjs → colorStyles-j5U9v5JA.mjs} +5 -1
  142. package/dist/client/{context-Bc8T6pCe.mjs → context-C8TinPJc.mjs} +1 -1
  143. package/dist/client/{dates-DUsCEzLb.mjs → dates-vwwxTeB0.mjs} +2 -2
  144. package/dist/client/{eventCalendar-CKwgXui5.mjs → eventCalendar-DIbHfJXO.mjs} +10 -10
  145. package/dist/client/{eventCombined-CBAOSTGR.mjs → eventCombined-DoGMJ6cg.mjs} +4 -4
  146. package/dist/client/{eventDetails-Dh-_WiBD.mjs → eventDetails-BjN9v6a1.mjs} +4 -4
  147. package/dist/client/{eventListing-CA3frIH5.mjs → eventListing-DajjWgOv.mjs} +4 -4
  148. package/dist/client/{eventRegistration-BHtsgdcg.mjs → eventRegistration-DMq9gMA-.mjs} +109 -41
  149. package/dist/client/{form-C2h3YAcg.mjs → form-Qf6qTbos.mjs} +5 -5
  150. package/dist/client/{headerSection-lwMuMTH9.mjs → headerSection-D7qJrqFX.mjs} +3 -3
  151. package/dist/client/hooks.mjs +661 -116
  152. package/dist/client/{locationMap-DJ2bLODV.mjs → locationMap-CCF9-t_0.mjs} +4 -4
  153. package/dist/client/{FieldValidationMessage-AYanWFb-.mjs → mailingListSignupCopy-DZSHZrm6.mjs} +14 -1
  154. package/dist/client/{media-BtJ37tzS.mjs → media-CwBGetqC.mjs} +1 -1
  155. package/dist/client/{newsletterForm-8Pu5K32g.mjs → newsletterForm-DzCLSP4S.mjs} +6 -6
  156. package/dist/client/{pricing-HHx3IgBz.mjs → pricing-Cgxv2KLC.mjs} +1 -1
  157. package/dist/client/{productDetail-C_1odnAf.mjs → productDetail-ru9w5GHx.mjs} +3 -3
  158. package/dist/client/{productList-CtCv-Nmx.mjs → productList-zaapKSl-.mjs} +3 -3
  159. package/dist/client/{propsDecoder-Dcgsncxb.mjs → propsDecoder-CwvvNOHx.mjs} +52 -6
  160. package/dist/client/rendering/client.mjs +951 -369
  161. package/dist/client/rendering/islands.mjs +19 -19
  162. package/dist/client/rendering.mjs +2153 -1393
  163. package/dist/client/{routeIslandApiConfig-CWLP7wu3.mjs → routeIslandApiConfig-BwVFo0Y4.mjs} +1 -1
  164. package/dist/client/{shop-commerce-B88zmWWo.mjs → shop-commerce-De7gEnkA.mjs} +8 -8
  165. package/dist/client/{shop-commerce-store-DtSfkKuX.mjs → shop-commerce-store-B3MCxIBW.mjs} +1 -1
  166. package/dist/client/{shop-DQXrQ8kJ.mjs → shop-mktkXvbV.mjs} +7 -7
  167. package/dist/client/{shopShared-cuaONpkJ.mjs → shopShared-TqExh235.mjs} +5 -5
  168. package/dist/client/{useEventFilters-Bukew6Gb.mjs → useEventFilters-n_OjkIjX.mjs} +8 -8
  169. package/dist/preview-next/before-render.mjs +122 -50
  170. package/dist/preview-next/client/runtime.mjs +4 -4
  171. package/dist/preview-next/editor-base.css +53 -2
  172. package/dist/preview-next/editor-chrome.css +7 -4
  173. package/dist/preview-next/keepAlive.mjs +122 -50
  174. package/dist/preview-next/middleware.mjs +122 -50
  175. package/dist/{previewAuthStore-h5IgbSp4.mjs → previewAuthStore-C_EHQ5XA.mjs} +122 -50
  176. package/dist/{sdk-runtime-DTc1uIXn.mjs → sdk-runtime-BIkJg5y1.mjs} +2 -2
  177. package/dist/{separator-BpHS1KZK.mjs → separator-C9qDP95Z.mjs} +1 -1
  178. package/dist/server/components.mjs +25345 -24942
  179. package/dist/server/config-validation.mjs +711 -163
  180. package/dist/server/config.mjs +711 -163
  181. package/dist/server/data.mjs +709 -162
  182. package/dist/server/index.mjs +123 -51
  183. package/dist/server/navigation.mjs +13 -2
  184. package/dist/server/next.mjs +4538 -4169
  185. package/dist/server/page-converter.mjs +107 -64
  186. package/dist/server/prebuild.mjs +1 -1
  187. package/dist/server/rendering/server.mjs +2509 -2104
  188. package/dist/server/rendering.mjs +25526 -25104
  189. package/dist/server/routing.mjs +750 -289
  190. package/dist/server/server.mjs +671 -148
  191. package/dist/server/theme-bridge.mjs +66 -17
  192. package/dist/server/theme.mjs +5 -1
  193. package/dist/styles/index.css +32 -4
  194. package/package.json +1 -1
  195. package/dist/_dts/core/src/participant-identity.d.ts +0 -135
@@ -3162,6 +3162,12 @@ function layoutServicesByCategory(categories, services, options) {
3162
3162
  other
3163
3163
  };
3164
3164
  }
3165
+ //#endregion
3166
+ //#region ../core/src/mailing-list-runtime.ts
3167
+ function resolveBookingSignupOffer(context, siteName) {
3168
+ const name = siteName?.trim() ?? "";
3169
+ return context?.tag === "configured" && context.bookingSignup.tag === "offered" ? { siteName: name.length > 0 ? name : "this site" } : null;
3170
+ }
3165
3171
  function sessionStartMs(session) {
3166
3172
  return Date.parse(session.startsAt);
3167
3173
  }
@@ -9389,105 +9395,6 @@ function useBlockApi() {
9389
9395
  if (!client) throw new Error("useBlockApi must be used within a BlockApiProvider. Make sure your component is wrapped with <BlockApiProvider>.");
9390
9396
  return client;
9391
9397
  }
9392
- //#endregion
9393
- //#region ../blocks/src/system/runtime/shared/components/CheckIcon.tsx
9394
- function CheckIcon({ className, strokeWidth = 2 }) {
9395
- return /* @__PURE__ */ jsx("svg", {
9396
- fill: "none",
9397
- strokeLinecap: "round",
9398
- strokeLinejoin: "round",
9399
- strokeWidth,
9400
- viewBox: "0 0 24 24",
9401
- stroke: "currentColor",
9402
- className,
9403
- width: "1em",
9404
- height: "1em",
9405
- "aria-hidden": "true",
9406
- children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
9407
- });
9408
- }
9409
- //#endregion
9410
- //#region ../blocks/src/system/runtime/shared/components/StateIcon.tsx
9411
- /**
9412
- * Circular icon wrapper for terminal state screens (success, error, waitlist, etc.).
9413
- *
9414
- * Layout is provided by shared `rb-state-icon` CSS; color variants are
9415
- * block-scoped by the owning registration surface.
9416
- */
9417
- function StateIcon({ variant, children }) {
9418
- return /* @__PURE__ */ jsx("div", {
9419
- className: `rb-state-icon rb-state-icon--${variant}`,
9420
- "aria-hidden": "true",
9421
- children
9422
- });
9423
- }
9424
- //#endregion
9425
- //#region ../blocks/src/system/runtime/shared/components/TerminalPanel.tsx
9426
- function joinClasses$1(...parts) {
9427
- return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
9428
- }
9429
- function TerminalPanel({ tone, title, titleAs: Title = "h3", body, secondaryBody, icon, actions, className, titleClassName, bodyClassName, secondaryBodyClassName, iconClassName, actionsClassName, role, live }) {
9430
- const resolvedRole = role ?? (tone === "error" ? "alert" : "status");
9431
- const resolvedLive = live ?? (resolvedRole === "alert" ? "assertive" : "polite");
9432
- return /* @__PURE__ */ jsxs("div", {
9433
- className,
9434
- "data-terminal-panel": true,
9435
- "data-terminal-tone": tone,
9436
- role: resolvedRole,
9437
- "aria-live": resolvedLive === "off" ? void 0 : resolvedLive,
9438
- children: [
9439
- icon ? /* @__PURE__ */ jsx("div", {
9440
- className: joinClasses$1(iconClassName),
9441
- "data-terminal-icon": true,
9442
- children: icon
9443
- }) : null,
9444
- /* @__PURE__ */ jsx(Title, {
9445
- className: joinClasses$1(titleClassName),
9446
- "data-terminal-title": true,
9447
- children: title
9448
- }),
9449
- body ? /* @__PURE__ */ jsx("div", {
9450
- className: joinClasses$1(bodyClassName),
9451
- "data-terminal-body": true,
9452
- children: body
9453
- }) : null,
9454
- actions ? /* @__PURE__ */ jsx("div", {
9455
- className: joinClasses$1(actionsClassName),
9456
- "data-terminal-actions": true,
9457
- children: actions
9458
- }) : null,
9459
- secondaryBody ? /* @__PURE__ */ jsx("div", {
9460
- className: joinClasses$1(secondaryBodyClassName),
9461
- "data-terminal-secondary-body": true,
9462
- children: secondaryBody
9463
- }) : null
9464
- ]
9465
- });
9466
- }
9467
- //#endregion
9468
- //#region ../blocks/src/system/runtime/components/booking/SuccessMessage.tsx
9469
- const SuccessMessage = ({ message, resourceName, className }) => {
9470
- return /* @__PURE__ */ jsx(TerminalPanel, {
9471
- tone: "success",
9472
- title: "Booking confirmed",
9473
- icon: /* @__PURE__ */ jsx(StateIcon, {
9474
- variant: "success",
9475
- children: /* @__PURE__ */ jsx(CheckIcon, { strokeWidth: 3 })
9476
- }),
9477
- body: /* @__PURE__ */ jsx("p", {
9478
- className: "ab-text",
9479
- children: message
9480
- }),
9481
- secondaryBody: resourceName ? /* @__PURE__ */ jsxs("p", {
9482
- className: "ab-text rb-on-surface--muted",
9483
- children: ["Practitioner: ", resourceName]
9484
- }) : null,
9485
- className: ["ab-center", className ?? ""].join(" ").trim(),
9486
- titleClassName: "ab-terminal-title",
9487
- role: "alert",
9488
- live: "polite"
9489
- });
9490
- };
9491
9398
  new TextEncoder();
9492
9399
  //#endregion
9493
9400
  //#region ../altcha/src/index.ts
@@ -9571,7 +9478,8 @@ const BOOKING_FORM_DATA_RESERVED_KEY_VALUES = [
9571
9478
  "discountCode",
9572
9479
  "selectedSlidingAmountInput",
9573
9480
  "selectedCollectionOptionKind",
9574
- "selectedAppointmentPackageId"
9481
+ "selectedAppointmentPackageId",
9482
+ "mailingListOptIn"
9575
9483
  ];
9576
9484
  const BOOKING_FORM_DATA_RESERVED_KEYS = new Set(BOOKING_FORM_DATA_RESERVED_KEY_VALUES);
9577
9485
  //#endregion
@@ -9991,6 +9899,7 @@ function prepareBookingSubmission(input) {
9991
9899
  startAt: selectedSlot,
9992
9900
  endAt: endDate.toISOString(),
9993
9901
  customFields: collectBookingCustomFields(input.data),
9902
+ ...selectedMailingListOptIn(input.data),
9994
9903
  timezone: toBookingTimeZone(input.viewerTimeZone ?? null)
9995
9904
  };
9996
9905
  if (customerPassId) return {
@@ -10041,6 +9950,9 @@ function prepareBookingSubmission(input) {
10041
9950
  }
10042
9951
  };
10043
9952
  }
9953
+ function selectedMailingListOptIn(data) {
9954
+ return data.mailingListOptIn === true ? { mailingListOptIn: true } : {};
9955
+ }
10044
9956
  function formatBookingSubmissionPreparationError(error) {
10045
9957
  switch (error.tag) {
10046
9958
  case "missing-required-booking-information": return "Missing required booking information";
@@ -10621,6 +10533,7 @@ function useBookingSubmission(_siteId) {
10621
10533
  startAt: data.startAt,
10622
10534
  endAt: data.endAt,
10623
10535
  customFields: data.customFields,
10536
+ mailingListOptIn: data.mailingListOptIn,
10624
10537
  timezone: data.timezone,
10625
10538
  customerPassId: data.customerPassId
10626
10539
  }) : await api.submitBooking({
@@ -10630,6 +10543,7 @@ function useBookingSubmission(_siteId) {
10630
10543
  startAt: data.startAt,
10631
10544
  endAt: data.endAt,
10632
10545
  customFields: data.customFields,
10546
+ mailingListOptIn: data.mailingListOptIn,
10633
10547
  timezone: data.timezone,
10634
10548
  discountCode: data.discountCode,
10635
10549
  selectedSlidingAmount: data.selectedSlidingAmount,
@@ -10665,6 +10579,40 @@ function useBookingSubmission(_siteId) {
10665
10579
  };
10666
10580
  }
10667
10581
  //#endregion
10582
+ //#region ../blocks/src/system/runtime/nodes/booking-form.submit-success.ts
10583
+ function completeBookingSubmission(input) {
10584
+ const { data } = input;
10585
+ if (data.type === "checkout_redirect") {
10586
+ if (input.redirect === "auto" && typeof window !== "undefined") input.navigateToCheckout(data.checkoutUrl);
10587
+ return {
10588
+ ok: true,
10589
+ outcome: {
10590
+ kind: "checkout_redirect",
10591
+ checkoutUrl: data.checkoutUrl,
10592
+ sessionId: data.sessionId,
10593
+ ...data.mailingListSignupNote ? { mailingListSignupNote: data.mailingListSignupNote } : {}
10594
+ }
10595
+ };
10596
+ }
10597
+ input.dispatch({
10598
+ type: "feedback-set",
10599
+ feedback: {
10600
+ kind: "success",
10601
+ message: getBookingSuccessMessage(input.successMessage),
10602
+ resourceName: data.appointment.resourceName
10603
+ }
10604
+ });
10605
+ return {
10606
+ ok: true,
10607
+ outcome: {
10608
+ kind: "booked",
10609
+ appointmentId: data.appointment.id,
10610
+ resourceName: data.appointment.resourceName,
10611
+ ...data.mailingListSignupNote ? { mailingListSignupNote: data.mailingListSignupNote } : {}
10612
+ }
10613
+ };
10614
+ }
10615
+ //#endregion
10668
10616
  //#region ../blocks/src/system/runtime/api/types/discounts.ts
10669
10617
  function discountAvailabilityHasDiscounts(availability) {
10670
10618
  return availability.type !== "none";
@@ -11195,6 +11143,40 @@ function clearBookingFieldError(errors, fieldId) {
11195
11143
  };
11196
11144
  }
11197
11145
  //#endregion
11146
+ //#region ../blocks/src/system/runtime/nodes/booking-form.mailing-list-state.ts
11147
+ function bookingFormDataWithEligibleOptIn(data, eligible) {
11148
+ return {
11149
+ ...data,
11150
+ mailingListOptIn: eligible && data.mailingListOptIn === true
11151
+ };
11152
+ }
11153
+ function isBookingContactEvent(event) {
11154
+ return event.type === "field-updated" || event.type === "field-touched" || event.type === "mailing-list-opt-in-set";
11155
+ }
11156
+ function applyBookingContactEvent(state, event) {
11157
+ switch (event.type) {
11158
+ case "field-updated": return {
11159
+ ...state,
11160
+ fieldValues: {
11161
+ ...state.fieldValues,
11162
+ [event.fieldId]: event.value
11163
+ },
11164
+ validationErrors: clearBookingFieldError(clearBookingFormError(state.validationErrors), event.fieldId)
11165
+ };
11166
+ case "field-touched": return {
11167
+ ...state,
11168
+ touchedFields: {
11169
+ ...state.touchedFields,
11170
+ [event.fieldId]: true
11171
+ }
11172
+ };
11173
+ case "mailing-list-opt-in-set": return {
11174
+ ...state,
11175
+ mailingListOptIn: event.checked
11176
+ };
11177
+ }
11178
+ }
11179
+ //#endregion
11198
11180
  //#region ../blocks/src/system/runtime/nodes/booking-form.field-values.ts
11199
11181
  function collectInitialBookingFieldValues(initialData) {
11200
11182
  const values = {};
@@ -11220,6 +11202,7 @@ function createInitialBookingFlowReducerState(input) {
11220
11202
  selectedDate: toOptionalString(initialData.selectedDate),
11221
11203
  selectedSlot: null,
11222
11204
  fieldValues: collectInitialBookingFieldValues(initialData),
11205
+ mailingListOptIn: initialData.mailingListOptIn === true,
11223
11206
  touchedFields: {},
11224
11207
  attemptedStepIds: {},
11225
11208
  discountCode: toOptionalString(initialData.discountCode) ?? "",
@@ -11272,6 +11255,7 @@ function applyAvailabilitySelectionInvalidation(state, invalidation) {
11272
11255
  };
11273
11256
  }
11274
11257
  function bookingFlowReducer(state, event) {
11258
+ if (isBookingContactEvent(event)) return applyBookingContactEvent(state, event);
11275
11259
  switch (event.type) {
11276
11260
  case "service-selected": return applyBookingServiceSelection(state, event.serviceId);
11277
11261
  case "resource-selected": return {
@@ -11294,21 +11278,6 @@ function bookingFlowReducer(state, event) {
11294
11278
  feedback: clearAvailabilityFeedback(state.feedback),
11295
11279
  validationErrors: clearBookingFormError(state.validationErrors)
11296
11280
  };
11297
- case "field-updated": return {
11298
- ...state,
11299
- fieldValues: {
11300
- ...state.fieldValues,
11301
- [event.fieldId]: event.value
11302
- },
11303
- validationErrors: clearBookingFieldError(clearBookingFormError(state.validationErrors), event.fieldId)
11304
- };
11305
- case "field-touched": return {
11306
- ...state,
11307
- touchedFields: {
11308
- ...state.touchedFields,
11309
- [event.fieldId]: true
11310
- }
11311
- };
11312
11281
  case "step-advance-attempted": return state.attemptedStepIds[event.stepId] ? state : {
11313
11282
  ...state,
11314
11283
  attemptedStepIds: {
@@ -11446,6 +11415,7 @@ function deriveBookingSlotDisplayOptions(input) {
11446
11415
  function toBookingFormData(state) {
11447
11416
  return {
11448
11417
  ...state.fieldValues,
11418
+ mailingListOptIn: state.mailingListOptIn,
11449
11419
  serviceId: state.selectedServiceId,
11450
11420
  resourceId: state.selectedResourceId ?? state.selectedSlot?.resourceId,
11451
11421
  selectedDate: state.selectedDate,
@@ -11708,10 +11678,7 @@ function buildBookingSubmitPlan(input) {
11708
11678
  };
11709
11679
  const prepared = prepareBookingSubmission({
11710
11680
  formId: input.formId,
11711
- data: toBookingFormData({
11712
- ...input.state,
11713
- altchaSolution: input.altchaSolution ?? input.state.altchaSolution
11714
- }),
11681
+ data: bookingFormDataWithEligibleOptIn(toBookingFormData(input.state), Boolean(input.mailingListEligible)),
11715
11682
  services: input.services,
11716
11683
  defaultServiceId: input.defaultServiceId,
11717
11684
  defaultResourceId: input.defaultResourceId,
@@ -11966,6 +11933,8 @@ function useHeadlessBookingFlow(options) {
11966
11933
  const canLoadAppointmentPackages = Boolean(options.enableAppointmentPackages && hasPortalBearerAuth && selectedService && !selectedServiceSlidingScale && (selectedService.priceAmount ?? 0) > 0);
11967
11934
  const appointmentPackagesUnavailableReason = !options.enableAppointmentPackages ? "disabled" : !selectedService || selectedServiceSlidingScale || (selectedService.priceAmount ?? 0) <= 0 ? "missing-priced-service" : !hasPortalBearerAuth ? "missing-portal-auth" : null;
11968
11935
  const data = useMemo(() => toBookingFormData(state), [state]);
11936
+ const mailingList = resolveBookingSignupOffer(options.mailingList, options.siteName);
11937
+ const mailingListEligible = mailingList !== null;
11969
11938
  const availabilityDatesQuery = useMemo(() => buildBookingAvailabilityQuery({
11970
11939
  serviceId: selectedServiceId,
11971
11940
  resourceId: selectedResourceId,
@@ -12226,7 +12195,8 @@ function useHeadlessBookingFlow(options) {
12226
12195
  viewerTimeZone: latest.viewerTimeZone,
12227
12196
  redirect: submitOptions?.redirect ?? "manual",
12228
12197
  successUrl: submitOptions?.successUrl,
12229
- cancelUrl: submitOptions?.cancelUrl
12198
+ cancelUrl: submitOptions?.cancelUrl,
12199
+ mailingListEligible
12230
12200
  });
12231
12201
  if (!plan.ok) {
12232
12202
  dispatch({
@@ -12259,37 +12229,18 @@ function useHeadlessBookingFlow(options) {
12259
12229
  message: result.error
12260
12230
  };
12261
12231
  }
12262
- if (result.data.type === "checkout_redirect") {
12263
- if (plan.redirect === "auto" && typeof window !== "undefined") latest.navigateToCheckout(result.data.checkoutUrl);
12264
- return {
12265
- ok: true,
12266
- outcome: {
12267
- kind: "checkout_redirect",
12268
- checkoutUrl: result.data.checkoutUrl
12269
- }
12270
- };
12271
- }
12272
- dispatch({
12273
- type: "feedback-set",
12274
- feedback: {
12275
- kind: "success",
12276
- message: getBookingSuccessMessage(latest.successMessage),
12277
- resourceName: result.data.appointment.resourceName
12278
- }
12232
+ return completeBookingSubmission({
12233
+ data: result.data,
12234
+ redirect: plan.redirect,
12235
+ successMessage: latest.successMessage,
12236
+ navigateToCheckout: latest.navigateToCheckout,
12237
+ dispatch
12279
12238
  });
12280
- return {
12281
- ok: true,
12282
- outcome: {
12283
- kind: "booked",
12284
- appointmentId: result.data.appointment.id,
12285
- resourceName: result.data.appointment.resourceName
12286
- }
12287
- };
12288
12239
  } finally {
12289
12240
  submittingRef.current = false;
12290
12241
  dispatch({ type: "submission-finished" });
12291
12242
  }
12292
- }, [latestRef]);
12243
+ }, [latestRef, mailingListEligible]);
12293
12244
  const actions = useMemo(() => ({
12294
12245
  selectService: (serviceId) => dispatch({
12295
12246
  type: "service-selected",
@@ -12312,6 +12263,10 @@ function useHeadlessBookingFlow(options) {
12312
12263
  fieldId: unsafeAsBookingFieldId(fieldId),
12313
12264
  value
12314
12265
  }),
12266
+ setMailingListOptIn: (checked) => dispatch({
12267
+ type: "mailing-list-opt-in-set",
12268
+ checked
12269
+ }),
12315
12270
  markFieldTouched: (fieldId) => dispatch({
12316
12271
  type: "field-touched",
12317
12272
  fieldId: unsafeAsBookingFieldId(fieldId)
@@ -12470,6 +12425,8 @@ function useHeadlessBookingFlow(options) {
12470
12425
  appointmentPackages: appointmentPackagesModel
12471
12426
  };
12472
12427
  return {
12428
+ mailingList,
12429
+ mailingListOptIn: state.mailingListOptIn,
12473
12430
  status,
12474
12431
  view,
12475
12432
  steps: stepState.steps,
@@ -12934,7 +12891,7 @@ function ThemedButton({ variant, size, extraClassName, screenReaderSuffix, label
12934
12891
  }
12935
12892
  //#endregion
12936
12893
  //#region ../blocks/src/system/runtime/shared/components/FeedbackMessage.tsx
12937
- function joinClasses(...parts) {
12894
+ function joinClasses$1(...parts) {
12938
12895
  return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
12939
12896
  }
12940
12897
  /**
@@ -12953,17 +12910,17 @@ function FeedbackMessage({ tone, treatment = "panel", children, className, id, t
12953
12910
  const shouldWrapBody = Boolean(title || bodyClassName) || treatment === "field-note";
12954
12911
  return /* @__PURE__ */ jsxs("div", {
12955
12912
  id,
12956
- className: joinClasses(className, treatmentClass(treatment)) || void 0,
12913
+ className: joinClasses$1(className, treatmentClass(treatment)) || void 0,
12957
12914
  "data-feedback-tone": tone,
12958
12915
  "data-feedback-treatment": treatment,
12959
12916
  role,
12960
12917
  "aria-live": resolvedLive === "off" ? void 0 : resolvedLive,
12961
12918
  children: [title ? /* @__PURE__ */ jsx("p", {
12962
- className: joinClasses(titleClassName),
12919
+ className: joinClasses$1(titleClassName),
12963
12920
  "data-feedback-title": true,
12964
12921
  children: title
12965
12922
  }) : null, shouldWrapBody ? /* @__PURE__ */ jsx("div", {
12966
- className: joinClasses(bodyClassName),
12923
+ className: joinClasses$1(bodyClassName),
12967
12924
  "data-feedback-body": true,
12968
12925
  children
12969
12926
  }) : children]
@@ -13145,6 +13102,23 @@ const TimeSlotSelector = ({ value, onChange, slots, isLoading, timezone, require
13145
13102
  });
13146
13103
  };
13147
13104
  //#endregion
13105
+ //#region ../blocks/src/system/runtime/shared/components/CheckIcon.tsx
13106
+ function CheckIcon({ className, strokeWidth = 2 }) {
13107
+ return /* @__PURE__ */ jsx("svg", {
13108
+ fill: "none",
13109
+ strokeLinecap: "round",
13110
+ strokeLinejoin: "round",
13111
+ strokeWidth,
13112
+ viewBox: "0 0 24 24",
13113
+ stroke: "currentColor",
13114
+ className,
13115
+ width: "1em",
13116
+ height: "1em",
13117
+ "aria-hidden": "true",
13118
+ children: /* @__PURE__ */ jsx("path", { d: "M5 13l4 4L19 7" })
13119
+ });
13120
+ }
13121
+ //#endregion
13148
13122
  //#region ../blocks/src/system/runtime/shared/components/StepIndicator.tsx
13149
13123
  /**
13150
13124
  * Shared step indicator component for registration wizards.
@@ -14128,6 +14102,25 @@ function CheckboxChoice({ label, presentation = "row", className, ...inputProps
14128
14102
  });
14129
14103
  }
14130
14104
  //#endregion
14105
+ //#region ../blocks/src/system/runtime/nodes/booking-form.mailing-list-choice.tsx
14106
+ function BookingMailingListChoice({ booking }) {
14107
+ const id = React.useId();
14108
+ if (!booking.mailingList) return null;
14109
+ return /* @__PURE__ */ jsxs("div", {
14110
+ className: "rb-space-y-2",
14111
+ children: [/* @__PURE__ */ jsx(CheckboxChoice, {
14112
+ id,
14113
+ name: "mailingListOptIn",
14114
+ checked: booking.mailingListOptIn,
14115
+ onChange: (event) => booking.actions.setMailingListOptIn(event.target.checked),
14116
+ label: `Email me news and updates from ${booking.mailingList.siteName}.`
14117
+ }), /* @__PURE__ */ jsx("p", {
14118
+ className: "rb-caption status-muted",
14119
+ children: "Optional. You can unsubscribe at any time."
14120
+ })]
14121
+ });
14122
+ }
14123
+ //#endregion
14131
14124
  //#region ../blocks/src/system/runtime/nodes/booking-form.service-choices.tsx
14132
14125
  function optionCardClassName(isSelected) {
14133
14126
  return `rb-option-card${isSelected ? " rb-option-card--selected" : ""}`;
@@ -14607,12 +14600,17 @@ function PaymentOptionContent({ description, helperText, id, summaryRows, title
14607
14600
  });
14608
14601
  }
14609
14602
  function DefaultDynamicFields({ booking, fields }) {
14603
+ const lastContactIndex = fields.reduce((last, field, index) => [
14604
+ "name",
14605
+ "email",
14606
+ "phone"
14607
+ ].includes(field.id) ? index : last, -1);
14610
14608
  return /* @__PURE__ */ jsx("div", {
14611
14609
  className: "rb-space-y-6",
14612
- children: fields.map((field) => /* @__PURE__ */ jsx(DefaultDynamicField, {
14610
+ children: fields.map((field, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [/* @__PURE__ */ jsx(DefaultDynamicField, {
14613
14611
  booking,
14614
14612
  field
14615
- }, field.id))
14613
+ }), index === lastContactIndex && booking.mailingList ? /* @__PURE__ */ jsx(BookingMailingListChoice, { booking }) : null] }, field.id))
14616
14614
  });
14617
14615
  }
14618
14616
  function DefaultDynamicField({ booking, field }) {
@@ -14948,9 +14946,169 @@ function consumeSearchParams(paramNames) {
14948
14946
  return values;
14949
14947
  }
14950
14948
  //#endregion
14949
+ //#region ../blocks/src/system/runtime/shared/components/StateIcon.tsx
14950
+ /**
14951
+ * Circular icon wrapper for terminal state screens (success, error, waitlist, etc.).
14952
+ *
14953
+ * Layout is provided by shared `rb-state-icon` CSS; color variants are
14954
+ * block-scoped by the owning registration surface.
14955
+ */
14956
+ function StateIcon({ variant, children }) {
14957
+ return /* @__PURE__ */ jsx("div", {
14958
+ className: `rb-state-icon rb-state-icon--${variant}`,
14959
+ "aria-hidden": "true",
14960
+ children
14961
+ });
14962
+ }
14963
+ //#endregion
14964
+ //#region ../blocks/src/system/runtime/shared/components/TerminalPanel.tsx
14965
+ function joinClasses(...parts) {
14966
+ return parts.filter((part) => typeof part === "string" && part.length > 0).join(" ");
14967
+ }
14968
+ function TerminalPanel({ tone, title, titleAs: Title = "h3", body, secondaryBody, icon, actions, className, titleClassName, bodyClassName, secondaryBodyClassName, iconClassName, actionsClassName, role, live }) {
14969
+ const resolvedRole = role ?? (tone === "error" ? "alert" : "status");
14970
+ const resolvedLive = live ?? (resolvedRole === "alert" ? "assertive" : "polite");
14971
+ return /* @__PURE__ */ jsxs("div", {
14972
+ className,
14973
+ "data-terminal-panel": true,
14974
+ "data-terminal-tone": tone,
14975
+ role: resolvedRole,
14976
+ "aria-live": resolvedLive === "off" ? void 0 : resolvedLive,
14977
+ children: [
14978
+ icon ? /* @__PURE__ */ jsx("div", {
14979
+ className: joinClasses(iconClassName),
14980
+ "data-terminal-icon": true,
14981
+ children: icon
14982
+ }) : null,
14983
+ /* @__PURE__ */ jsx(Title, {
14984
+ className: joinClasses(titleClassName),
14985
+ "data-terminal-title": true,
14986
+ children: title
14987
+ }),
14988
+ body ? /* @__PURE__ */ jsx("div", {
14989
+ className: joinClasses(bodyClassName),
14990
+ "data-terminal-body": true,
14991
+ children: body
14992
+ }) : null,
14993
+ actions ? /* @__PURE__ */ jsx("div", {
14994
+ className: joinClasses(actionsClassName),
14995
+ "data-terminal-actions": true,
14996
+ children: actions
14997
+ }) : null,
14998
+ secondaryBody ? /* @__PURE__ */ jsx("div", {
14999
+ className: joinClasses(secondaryBodyClassName),
15000
+ "data-terminal-secondary-body": true,
15001
+ children: secondaryBody
15002
+ }) : null
15003
+ ]
15004
+ });
15005
+ }
15006
+ //#endregion
15007
+ //#region ../blocks/src/system/runtime/components/booking/SuccessMessage.tsx
15008
+ const SuccessMessage = ({ message, resourceName, className }) => {
15009
+ return /* @__PURE__ */ jsx(TerminalPanel, {
15010
+ tone: "success",
15011
+ title: "Booking confirmed",
15012
+ icon: /* @__PURE__ */ jsx(StateIcon, {
15013
+ variant: "success",
15014
+ children: /* @__PURE__ */ jsx(CheckIcon, { strokeWidth: 3 })
15015
+ }),
15016
+ body: /* @__PURE__ */ jsx("p", {
15017
+ className: "ab-text",
15018
+ children: message
15019
+ }),
15020
+ secondaryBody: resourceName ? /* @__PURE__ */ jsxs("p", {
15021
+ className: "ab-text rb-on-surface--muted",
15022
+ children: ["Practitioner: ", resourceName]
15023
+ }) : null,
15024
+ className: ["ab-center", className ?? ""].join(" ").trim(),
15025
+ titleClassName: "ab-terminal-title",
15026
+ role: "alert",
15027
+ live: "polite"
15028
+ });
15029
+ };
15030
+ //#endregion
15031
+ //#region ../blocks/src/system/runtime/shared/mailingListSignupCopy.ts
15032
+ const MAILING_LIST_CONFIRMATION_MESSAGE = "Please check your inbox to confirm your signup.";
15033
+ function getBookingMailingListNoteCopy(note, context) {
15034
+ if (note === "confirmation_required") return {
15035
+ title: MAILING_LIST_CONFIRMATION_MESSAGE,
15036
+ detail: context === "booking" ? "This is separate from your booking confirmation." : null
15037
+ };
15038
+ return {
15039
+ title: "We couldn’t confirm your mailing-list signup.",
15040
+ detail: context === "booking" ? "This does not affect your booking." : null
15041
+ };
15042
+ }
15043
+ //#endregion
15044
+ //#region ../blocks/src/system/runtime/shared/components/BookingMailingListNote.tsx
15045
+ function BookingMailingListNote(props) {
15046
+ const copy = getBookingMailingListNoteCopy(props.note, props.context);
15047
+ return /* @__PURE__ */ jsxs("div", {
15048
+ role: "status",
15049
+ className: props.className,
15050
+ children: [/* @__PURE__ */ jsx("p", { children: copy.title }), copy.detail ? /* @__PURE__ */ jsx("p", { children: copy.detail }) : null]
15051
+ });
15052
+ }
15053
+ //#endregion
15054
+ //#region ../blocks/src/system/runtime/nodes/booking-form.mailing-list-note.ts
15055
+ function storageKey(sessionId) {
15056
+ return `riverbank:booking:mailing-list:${sessionId}`;
15057
+ }
15058
+ function saveAppointmentMailingListNote(sessionId, note) {
15059
+ if (!note) return;
15060
+ try {
15061
+ window.sessionStorage.setItem(storageKey(sessionId), note);
15062
+ } catch {}
15063
+ }
15064
+ function readAppointmentMailingListNote(sessionId) {
15065
+ try {
15066
+ const stored = window.sessionStorage.getItem(storageKey(sessionId));
15067
+ return stored === "confirmation_required" || stored === "not_confirmed" ? stored : null;
15068
+ } catch {
15069
+ return null;
15070
+ }
15071
+ }
15072
+ //#endregion
15073
+ //#region ../blocks/src/system/runtime/nodes/booking-form.completion.tsx
15074
+ function BookingFormCompletion({ resourceName, successMessage, redirectState, localNote }) {
15075
+ const note = redirectState.kind === "success" ? readAppointmentMailingListNote(redirectState.sessionId) : localNote;
15076
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(SuccessMessage, {
15077
+ message: getBookingSuccessMessage(successMessage),
15078
+ resourceName
15079
+ }), note ? /* @__PURE__ */ jsx(BookingMailingListNote, {
15080
+ note,
15081
+ context: "booking",
15082
+ className: "rb-mt-4"
15083
+ }) : null] });
15084
+ }
15085
+ //#endregion
15086
+ //#region ../blocks/src/system/runtime/nodes/booking-form.submit-handler.ts
15087
+ function appendRebookFlag(url, enabled) {
15088
+ if (!enabled) return url;
15089
+ const nextUrl = new URL(url);
15090
+ nextUrl.searchParams.set("rebook", "1");
15091
+ return nextUrl.toString();
15092
+ }
15093
+ function createBookingFormSubmitHandler(input) {
15094
+ return async () => {
15095
+ const { successUrl, cancelUrl } = buildCheckoutReturnUrls("booking", input.bookingAnchorId);
15096
+ const result = await input.booking.actions.submit({
15097
+ redirect: "manual",
15098
+ successUrl: appendRebookFlag(successUrl, input.isPortalRebook),
15099
+ cancelUrl: appendRebookFlag(cancelUrl, input.isPortalRebook)
15100
+ });
15101
+ if (!result.ok) return;
15102
+ if (result.outcome.kind === "checkout_redirect") {
15103
+ saveAppointmentMailingListNote(result.outcome.sessionId, result.outcome.mailingListSignupNote);
15104
+ window.location.href = result.outcome.checkoutUrl;
15105
+ return;
15106
+ }
15107
+ input.setLocalMailingListNote(result.outcome.mailingListSignupNote ?? null);
15108
+ };
15109
+ }
15110
+ //#endregion
14951
15111
  //#region ../blocks/src/system/runtime/nodes/booking-form.client.tsx
14952
- const PORTAL_REBOOK_QUERY_PARAM = "rebook";
14953
- const PORTAL_REBOOK_QUERY_VALUE = "1";
14954
15112
  const REBOOK_COMPLETION_MODE_VERIFIED_CHECKOUT = "verified_checkout";
14955
15113
  const REBOOK_COMPLETION_MODE_BYPASSED = "bypassed";
14956
15114
  function getBookingRedirectLocationSnapshot() {
@@ -14963,12 +15121,6 @@ function getBookingRedirectLocationSnapshot() {
14963
15121
  hash: window.location.hash
14964
15122
  };
14965
15123
  }
14966
- function appendRebookFlag(url, enabled) {
14967
- if (!enabled) return url;
14968
- const nextUrl = new URL(url);
14969
- nextUrl.searchParams.set(PORTAL_REBOOK_QUERY_PARAM, PORTAL_REBOOK_QUERY_VALUE);
14970
- return nextUrl.toString();
14971
- }
14972
15124
  /**
14973
15125
  * Themed surface container for every booking view state (wizard, success,
14974
15126
  * verifying). Styled by the shared registration-surface layer.
@@ -14991,12 +15143,16 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
14991
15143
  const isPortalRebook = render.hydration.rebookContext?.kind === "portal_rebook";
14992
15144
  const hasLoggedRebookCompletionRef = useRef(false);
14993
15145
  const [redirectState] = useState(() => getBookingRedirectStateFromLocation(getBookingRedirectLocationSnapshot()));
15146
+ const [localMailingListNote, setLocalMailingListNote] = useState(null);
14994
15147
  const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
14995
15148
  const api = useBlockApi();
14996
15149
  const hasPortalAuth = api.config.auth.type === "bearer" || api.config.authOverrides?.portal?.type === "bearer";
15150
+ const formId = render.hydration.formId ?? form?.id ?? "booking-form";
14997
15151
  const booking = useHeadlessBookingFlow({
15152
+ mailingList: render.hydration.mailingList,
15153
+ siteName: render.hydration.siteName,
14998
15154
  siteId,
14999
- formId: render.hydration.formId ?? form?.id ?? "booking-form",
15155
+ formId,
15000
15156
  form,
15001
15157
  services,
15002
15158
  serviceCategories: render.hydration.serviceCategories,
@@ -15066,22 +15222,20 @@ const BookingFormClient$1 = ({ siteId: siteIdProp, render }) => {
15066
15222
  children: render.display.message ?? "Booking form not found. Please check your configuration."
15067
15223
  })
15068
15224
  });
15069
- const handleComplete = async () => {
15070
- const { successUrl, cancelUrl } = buildCheckoutReturnUrls("booking", bookingAnchorId);
15071
- const result = await booking.actions.submit({
15072
- redirect: "manual",
15073
- successUrl: appendRebookFlag(successUrl, isPortalRebook),
15074
- cancelUrl: appendRebookFlag(cancelUrl, isPortalRebook)
15075
- });
15076
- if (!result.ok) return;
15077
- if (result.outcome.kind === "checkout_redirect") window.location.href = result.outcome.checkoutUrl;
15078
- };
15225
+ const handleComplete = createBookingFormSubmitHandler({
15226
+ booking,
15227
+ bookingAnchorId,
15228
+ isPortalRebook,
15229
+ setLocalMailingListNote
15230
+ });
15079
15231
  if (viewState.kind === "success") return /* @__PURE__ */ jsx(BookingSurface, {
15080
15232
  id: bookingAnchorId,
15081
15233
  className: render.display.className,
15082
- children: /* @__PURE__ */ jsx(SuccessMessage, {
15083
- message: getBookingSuccessMessage(render.display.successMessage),
15084
- resourceName: viewState.resourceName
15234
+ children: /* @__PURE__ */ jsx(BookingFormCompletion, {
15235
+ successMessage: render.display.successMessage,
15236
+ resourceName: viewState.resourceName,
15237
+ redirectState,
15238
+ localNote: localMailingListNote
15085
15239
  })
15086
15240
  });
15087
15241
  if (viewState.kind === "verifying") return /* @__PURE__ */ jsx(BookingSurface, {
@@ -15190,7 +15344,8 @@ function createInitialRegistrationFormData() {
15190
15344
  email: "",
15191
15345
  phone: "",
15192
15346
  notes: "",
15193
- consentAccepted: false
15347
+ consentAccepted: false,
15348
+ mailingListOptIn: false
15194
15349
  };
15195
15350
  }
15196
15351
  function validateFormData(formData, requiresConsent = false) {
@@ -16314,7 +16469,10 @@ async function handleCheckoutReturn(options, deps, returnContextRef) {
16314
16469
  }
16315
16470
  const { checkoutAttemptId } = command;
16316
16471
  const pending = deps.getPendingRegistration(siteId, checkoutAttemptId);
16317
- returnContextRef.current = { checkoutAttemptId };
16472
+ returnContextRef.current = {
16473
+ checkoutAttemptId,
16474
+ mailingListSignupNote: pending?.mailingListSignupNote
16475
+ };
16318
16476
  if (pending) restorePendingPresentation(options, pending);
16319
16477
  options.setStep("verifying-payment");
16320
16478
  try {
@@ -16335,7 +16493,10 @@ function completeVerifiedRegistration(options, deps, returnContext) {
16335
16493
  const siteId = options.api.config.siteId;
16336
16494
  const checkoutAttemptId = returnContext?.checkoutAttemptId;
16337
16495
  if (siteId && checkoutAttemptId) deps.clearPendingRegistration(siteId, checkoutAttemptId);
16338
- options.setRegistrationResult({ status: "confirmed" });
16496
+ options.setRegistrationResult({
16497
+ status: "confirmed",
16498
+ mailingListSignupNote: returnContext?.mailingListSignupNote
16499
+ });
16339
16500
  options.setStep("success");
16340
16501
  }
16341
16502
  function useEventRegistrationStripeReturnWithDeps(options, deps) {
@@ -16408,6 +16569,9 @@ function registrationErrorPresentation(error) {
16408
16569
  }
16409
16570
  //#endregion
16410
16571
  //#region ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationSubmit.ts
16572
+ function wantsMailingListSignup(options) {
16573
+ return options.mailingListSignup !== null && options.formData.mailingListOptIn === true;
16574
+ }
16411
16575
  function createClientCommandId(cryptoSource = {
16412
16576
  randomUUID: globalThis.crypto.randomUUID?.bind(globalThis.crypto),
16413
16577
  getRandomValues: (bytes) => globalThis.crypto.getRandomValues(bytes)
@@ -16505,7 +16669,8 @@ async function completeRegistrationSubmission(options, deps, prepared, result, s
16505
16669
  case "paymentStatusRequired":
16506
16670
  options.setPaymentStatusRecovery({
16507
16671
  kind: "ready",
16508
- subject: result.subject
16672
+ subject: result.subject,
16673
+ mailingListSignupNote: result.mailingListSignupNote
16509
16674
  });
16510
16675
  options.setStep("payment-status");
16511
16676
  return {
@@ -16514,14 +16679,15 @@ async function completeRegistrationSubmission(options, deps, prepared, result, s
16514
16679
  };
16515
16680
  case "checkoutRequired":
16516
16681
  options.setPendingRegistrationReference(result.reference);
16517
- savePendingCheckout(options, deps, prepared, result.submissionId, result.reference);
16682
+ savePendingCheckout(options, deps, prepared, result.submissionId, result.reference, result.mailingListSignupNote);
16518
16683
  options.setStep("redirecting");
16519
16684
  return redirectToCheckout(result.checkoutUrl, submitOptions);
16520
16685
  case "waitlisted":
16521
16686
  options.setRegistrationResult({
16522
16687
  status: "waitlist",
16523
16688
  title: "Added to waitlist",
16524
- message: result.waitlist.message
16689
+ message: result.waitlist.message,
16690
+ mailingListSignupNote: result.mailingListSignupNote
16525
16691
  });
16526
16692
  break;
16527
16693
  case "bookingComplete":
@@ -16529,7 +16695,8 @@ async function completeRegistrationSubmission(options, deps, prepared, result, s
16529
16695
  options.setPendingRegistrationReference(result.reference);
16530
16696
  options.setRegistrationResult({
16531
16697
  status: "confirmed",
16532
- message: result.summary.paymentMethod === "pass" ? result.summary.message : void 0
16698
+ message: result.summary.paymentMethod === "pass" ? result.summary.message : void 0,
16699
+ mailingListSignupNote: result.mailingListSignupNote
16533
16700
  });
16534
16701
  break;
16535
16702
  }
@@ -16588,7 +16755,7 @@ function resolveSelectionSnapshot(method, passId, membershipId, bundleProductId,
16588
16755
  if (method === "free") return { method };
16589
16756
  throw new Error("Choose an available payment option.");
16590
16757
  }
16591
- function savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference) {
16758
+ function savePendingCheckout(options, deps, prepared, checkoutAttemptId, reference, mailingListSignupNote) {
16592
16759
  const siteId = options.api.config.siteId;
16593
16760
  if (!siteId) return;
16594
16761
  deps.savePendingRegistration(siteId, checkoutAttemptId, {
@@ -16597,7 +16764,8 @@ function savePendingCheckout(options, deps, prepared, checkoutAttemptId, referen
16597
16764
  ticketSelections: prepared.ticketSelections,
16598
16765
  selectedEventId: options.registrationTarget?.selectedEventId ?? null,
16599
16766
  selectedAttendanceMode: options.selectedAttendanceMode,
16600
- paymentSelection: prepared.selectionSnapshot
16767
+ paymentSelection: prepared.selectionSnapshot,
16768
+ mailingListSignupNote
16601
16769
  });
16602
16770
  }
16603
16771
  function redirectToCheckout(checkoutUrl, submitOptions) {
@@ -16611,7 +16779,7 @@ function redirectToCheckout(checkoutUrl, submitOptions) {
16611
16779
  };
16612
16780
  }
16613
16781
  function registrationRequestIntentKey(request) {
16614
- const { registrationCommandId: _command, altchaSolution: _proof, checkout, ...intent } = request;
16782
+ const { registrationCommandId: _command, altchaSolution: _proof, mailingListOptIn: _marketingConsent, checkout, ...intent } = request;
16615
16783
  return JSON.stringify({
16616
16784
  ...intent,
16617
16785
  checkout: checkout ? {
@@ -16636,6 +16804,7 @@ function buildRegistrationRequest(options, prepared, method, passId, membershipI
16636
16804
  phone: options.formData.phone.trim() || void 0,
16637
16805
  notes: options.formData.notes.trim() || void 0,
16638
16806
  consentAccepted: options.formData.consentAccepted,
16807
+ mailingListOptIn: wantsMailingListSignup(options),
16639
16808
  altchaSolution: options.altchaSolution,
16640
16809
  paymentMethod: method,
16641
16810
  customerPassId: method === "pass" ? passId : void 0,
@@ -17629,13 +17798,17 @@ function isCheckableRecovery(state) {
17629
17798
  function assistanceRequired(recovery) {
17630
17799
  return {
17631
17800
  kind: "assistanceRequired",
17632
- subject: recovery.subject
17801
+ subject: recovery.subject,
17802
+ mailingListSignupNote: recovery.mailingListSignupNote
17633
17803
  };
17634
17804
  }
17635
17805
  function applyStatusOutcome(outcome, recovery, setters, setRecovery) {
17636
17806
  if (outcome.kind === "resolved") {
17637
17807
  setters.setPendingRegistrationReference(outcome.reference);
17638
- setters.setRegistrationResult({ status: "confirmed" });
17808
+ setters.setRegistrationResult({
17809
+ status: "confirmed",
17810
+ mailingListSignupNote: recovery.mailingListSignupNote
17811
+ });
17639
17812
  setRecovery(null);
17640
17813
  setters.setStep("success");
17641
17814
  return;
@@ -17764,6 +17937,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
17764
17937
  const paymentSelection = flowState.paymentSelection;
17765
17938
  const [selectedEvent, setSelectedEvent] = useState(preSelectedEvent ?? null);
17766
17939
  const [formData, setFormData] = useState(createInitialRegistrationFormData);
17940
+ const mailingListSignup = resolveBookingSignupOffer(options.mailingList, options.siteName);
17767
17941
  const [errors, setErrors] = useState({});
17768
17942
  const [guests, setGuests] = useState([]);
17769
17943
  const [guestErrors, setGuestErrors] = useState({});
@@ -18210,6 +18384,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
18210
18384
  ticketSelections,
18211
18385
  selectedSlidingAmount,
18212
18386
  formData,
18387
+ mailingListSignup,
18213
18388
  altchaSolution,
18214
18389
  requireGuestDetails,
18215
18390
  guests,
@@ -18306,6 +18481,7 @@ function useEventRegistrationWizardWithDeps(options, deps) {
18306
18481
  hasValidTicketSelection,
18307
18482
  eventRequiresPayment,
18308
18483
  formData,
18484
+ mailingListSignup,
18309
18485
  setFormData,
18310
18486
  errors,
18311
18487
  guests,
@@ -18517,7 +18693,8 @@ function useEventRegistrationControllerWithDeps(options, deps) {
18517
18693
  },
18518
18694
  attendee: {
18519
18695
  values: wizard.formData,
18520
- errors: wizard.errors
18696
+ errors: wizard.errors,
18697
+ mailingListSignup: wizard.mailingListSignup
18521
18698
  },
18522
18699
  guests: {
18523
18700
  required: wizard.requireGuestDetails,
@@ -18615,7 +18792,9 @@ function useEventRegistrationWizardControllerWithDeps(options, deps) {
18615
18792
  occurrenceContext: options.occurrenceContext ?? null,
18616
18793
  subject: options.subject ?? null,
18617
18794
  events: [...options.events ?? []],
18618
- maxTicketsNum
18795
+ maxTicketsNum,
18796
+ mailingList: options.mailingList,
18797
+ siteName: options.siteName
18619
18798
  }) };
18620
18799
  }
18621
18800
  function resolveExistingRegistrationState(wizard) {