@riverbankcms/sdk 0.88.0 → 0.90.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 (198) hide show
  1. package/README.md +27 -4
  2. package/dist/{PreviewEditorSidebar-EVRS3C7T.mjs → PreviewEditorSidebar-KVXNF3VW.mjs} +3 -3
  3. package/dist/{PreviewEditorUI-54WD4IGE.mjs → PreviewEditorUI-J3JN5Z7T.mjs} +3 -3
  4. package/dist/SdkPreviewModeRuntime-UBL6MSNP.mjs +8 -0
  5. package/dist/_dts/ai/src/contracts/proposals.d.ts +216 -0
  6. package/dist/_dts/altcha/src/AltchaWidget.d.ts +1 -1
  7. package/dist/_dts/api/src/accessAdmin.d.ts +7 -0
  8. package/dist/_dts/api/src/bookingOperations.d.ts +2 -0
  9. package/dist/_dts/api/src/bookingRecords.d.ts +4 -2
  10. package/dist/_dts/api/src/bookings.d.ts +3 -1
  11. package/dist/_dts/api/src/endpoints.d.ts +8 -0
  12. package/dist/_dts/api/src/index.d.ts +7 -6
  13. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +15 -5
  14. package/dist/_dts/api/src/request.d.ts +21 -0
  15. package/dist/_dts/api/src/sdk-event-upsert.d.ts +3 -1
  16. package/dist/_dts/api/src/sdkContracts.d.ts +2 -0
  17. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  18. package/dist/_dts/api/src/siteMembers.d.ts +6 -1
  19. package/dist/_dts/api/src/types.d.ts +4 -2
  20. package/dist/_dts/api/src/url.d.ts +6 -3
  21. package/dist/_dts/block-form/src/utils/visibleWhen.d.ts +1 -0
  22. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailCard.d.ts +5 -1
  23. package/dist/_dts/block-form/src/widgets/RepeaterField/components/RepeaterThumbnailGrid.d.ts +9 -1
  24. package/dist/_dts/block-form/src/widgets/RepeaterField/components/index.d.ts +1 -0
  25. package/dist/_dts/blocks/src/contracts/non-block-islands.d.ts +7 -11
  26. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +6 -0
  27. package/dist/_dts/blocks/src/index.d.ts +2 -1
  28. package/dist/_dts/blocks/src/system/blocks/events/event-calendar.d.ts +14 -6
  29. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -4
  30. package/dist/_dts/blocks/src/system/blocks/hero.d.ts +0 -2
  31. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +3 -3
  32. package/dist/_dts/blocks/src/system/blocks/shop.shared.d.ts +8 -0
  33. package/dist/_dts/blocks/src/system/constants/events.d.ts +4 -1
  34. package/dist/_dts/blocks/src/system/icons/cta.d.ts +3 -3
  35. package/dist/_dts/blocks/src/system/icons/index.d.ts +1 -0
  36. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -2
  37. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +3 -3
  38. package/dist/_dts/blocks/src/system/icons/svg.d.ts +72 -0
  39. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +3 -1
  40. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -0
  41. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +18 -5
  42. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +51 -6
  43. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -0
  44. package/dist/_dts/blocks/src/system/runtime/hooks/loadStateError.d.ts +1 -0
  45. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.d.ts +1 -1
  46. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.state.d.ts +55 -0
  47. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableSlots.state.d.ts +39 -0
  48. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.d.ts +4 -27
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.state.d.ts +40 -0
  50. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +20 -0
  51. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.state.d.ts +31 -0
  52. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +3 -3
  53. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.state.d.ts +39 -0
  54. package/dist/_dts/blocks/src/system/runtime/nodes/course-registration/useCourseRegistrationWizard.d.ts +2 -2
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-details/logic.d.ts +1 -17
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.client.d.ts +5 -9
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-details.server.d.ts +5 -9
  58. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/event-registration.headless.contract.d.ts +2 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/eventPaymentOptions.d.ts +24 -0
  60. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +5 -0
  61. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.d.ts +4 -4
  62. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.d.ts +50 -0
  63. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.d.ts +2 -2
  64. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +21 -0
  65. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +1 -1
  66. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +11 -1
  67. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +2 -1
  68. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +11 -1
  69. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventPaginatedListView.client.d.ts +1 -1
  70. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/calendarViewOptions.d.ts +10 -0
  71. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventProductEligibility.d.ts +24 -0
  72. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.client.state.d.ts +24 -2
  73. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +24 -0
  74. package/dist/_dts/blocks/src/system/runtime/nodes/shared/contract-schemas.d.ts +5 -2
  75. package/dist/_dts/blocks/src/system/runtime/nodes/shop-checkout-form.d.ts +2 -2
  76. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +35 -0
  77. package/dist/_dts/content-model/src/entry-slots/index.d.ts +1 -0
  78. package/dist/_dts/content-model/src/entry-slots/sdkBlocks.d.ts +21 -0
  79. package/dist/_dts/content-model/src/entry-slots/types.d.ts +61 -0
  80. package/dist/_dts/core/src/branded.d.ts +7 -0
  81. package/dist/_dts/core/src/index.d.ts +1 -0
  82. package/dist/_dts/core/src/money-input.d.ts +18 -0
  83. package/dist/_dts/core/src/site-route-target.d.ts +40 -0
  84. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +209 -2
  85. package/dist/_dts/media-core/src/fileDomain.d.ts +4 -0
  86. package/dist/_dts/media-editor/src/MediaEditor.d.ts +2 -1
  87. package/dist/_dts/media-editor/src/fieldUi.d.ts +6 -0
  88. package/dist/_dts/media-editor/src/index.d.ts +1 -1
  89. package/dist/_dts/preview-next/src/client/index.d.ts +1 -0
  90. package/dist/_dts/preview-next/src/client/preview/PreviewShell.d.ts +3 -2
  91. package/dist/_dts/preview-next/src/client/preview/PreviewShellLayout.d.ts +3 -2
  92. package/dist/_dts/preview-next/src/client/preview/PreviewThemedSiteDocument.d.ts +3 -2
  93. package/dist/_dts/preview-next/src/client/preview/SiteChromeEditableSurface.d.ts +2 -2
  94. package/dist/_dts/preview-next/src/client/preview/themeRuntime.d.ts +6 -0
  95. package/dist/_dts/preview-next/src/client/sdk/SdkPreviewMode.d.ts +2 -1
  96. package/dist/_dts/sdk/src/cli/commands/pull-dated-offering-scope.d.ts +10 -0
  97. package/dist/_dts/sdk/src/cli/content/reader.d.ts +12 -5
  98. package/dist/_dts/sdk/src/client/management/types.d.ts +6 -55
  99. package/dist/_dts/sdk/src/client/runtimeCachePolicy.d.ts +160 -0
  100. package/dist/_dts/sdk/src/client/types.d.ts +26 -1
  101. package/dist/_dts/sdk/src/components.d.ts +1 -0
  102. package/dist/_dts/sdk/src/config/field-definitions.d.ts +3 -1
  103. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +3 -1
  104. package/dist/_dts/sdk/src/index.d.ts +3 -1
  105. package/dist/_dts/sdk/src/next/types.d.ts +8 -11
  106. package/dist/_dts/sdk/src/preview-next/client/index.d.ts +1 -1
  107. package/dist/_dts/sdk/src/rendering/blocks-theme-scope.d.ts +2 -1
  108. package/dist/_dts/sdk/src/rendering/components/Layout.d.ts +8 -7
  109. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +5 -6
  110. package/dist/_dts/sdk/src/rendering/index.d.ts +1 -0
  111. package/dist/_dts/sdk/src/rendering/server.d.ts +1 -0
  112. package/dist/_dts/sdk/src/rendering/themeRuntime.d.ts +26 -0
  113. package/dist/_dts/sdk/src/version.d.ts +1 -1
  114. package/dist/_dts/site-commands/src/commands.d.ts +18 -0
  115. package/dist/_dts/theme-core/src/ResponsiveScope.d.ts +12 -0
  116. package/dist/_dts/theme-core/src/accordions/types.d.ts +1 -1
  117. package/dist/_dts/theme-core/src/buttons/personalities/types.d.ts +2 -2
  118. package/dist/_dts/theme-core/src/buttons/types.d.ts +5 -5
  119. package/dist/_dts/theme-core/src/cards/types.d.ts +2 -2
  120. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  121. package/dist/_dts/theme-core/src/index.d.ts +2 -0
  122. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +21 -21
  123. package/dist/_dts/theme-core/src/schema.d.ts +18 -18
  124. package/dist/_dts/theme-core/src/site-styles/designState.d.ts +2 -2
  125. package/dist/_dts/theme-core/src/site-styles/generatedSchemas.d.ts +2 -2
  126. package/dist/_dts/theme-core/src/site-styles/logoBranding.d.ts +4 -4
  127. package/dist/_dts/theme-core/src/themeRuntime.d.ts +11 -0
  128. package/dist/{chunk-ER4UIW4X.mjs → chunk-AEOYWPE4.mjs} +91 -55
  129. package/dist/{chunk-O4LVYUVH.mjs → chunk-BOQXMCSP.mjs} +147 -101
  130. package/dist/{chunk-HVOBXA3Y.mjs → chunk-GSPFFUVB.mjs} +2 -2
  131. package/dist/{chunk-7KOO7RPP.mjs → chunk-PMBB6MQ7.mjs} +2273 -1113
  132. package/dist/{chunk-K3JWH6HE.mjs → chunk-RQ3XZ4SJ.mjs} +9 -1
  133. package/dist/{chunk-YDMBIIS5.mjs → chunk-UG7I7S7W.mjs} +1 -1
  134. package/dist/cli/index.mjs +1564 -546
  135. package/dist/cli/init-docs/content/cli-reference.md +6 -1
  136. package/dist/cli/init-docs/content/content-management.md +27 -0
  137. package/dist/client/{accordion-PT5CGW5N.mjs → accordion-GXQNWQ6O.mjs} +2 -2
  138. package/dist/client/{bookingForm-2HLRTEYS.mjs → bookingForm-STLUJ36H.mjs} +206 -335
  139. package/dist/client/bookings.mjs +821 -413
  140. package/dist/client/{carousel-Z2LKYSWA.mjs → carousel-CVRN6EPP.mjs} +4 -3
  141. package/dist/client/{cart-ND5IK4A6.mjs → cart-IYIBA5CL.mjs} +8 -8
  142. package/dist/client/{checkout-EYUSGAY7.mjs → checkout-O3BGM4GS.mjs} +8 -8
  143. package/dist/client/chunk-4RTFGHZN.mjs +433 -0
  144. package/dist/client/{chunk-DIRW2LNG.mjs → chunk-6DPXDOIL.mjs} +336 -225
  145. package/dist/client/chunk-6N7YRNYU.mjs +183 -0
  146. package/dist/client/{chunk-O5JNI3E4.mjs → chunk-7DH35FGA.mjs} +2 -2
  147. package/dist/client/{chunk-S4G65LGR.mjs → chunk-D3ETC2SU.mjs} +1 -1
  148. package/dist/client/{chunk-BAWHZ5GM.mjs → chunk-DAS5CIER.mjs} +460 -157
  149. package/dist/client/{chunk-6DVPO44G.mjs → chunk-FHU6PFPM.mjs} +1 -1
  150. package/dist/client/{chunk-SDIYSQAY.mjs → chunk-HIHOQGIP.mjs} +2 -3
  151. package/dist/client/{chunk-BL66UWGD.mjs → chunk-MFPKS6QS.mjs} +13 -16
  152. package/dist/client/{chunk-X7GVFB7Y.mjs → chunk-NBFRJ5NB.mjs} +157 -5
  153. package/dist/client/{chunk-WCVK4MBJ.mjs → chunk-VFHZLZAC.mjs} +1 -1
  154. package/dist/client/{chunk-GOFO7HRH.mjs → chunk-WHZQDPBZ.mjs} +19 -1
  155. package/dist/client/{chunk-MHBEWDT7.mjs → chunk-Z62JYS5O.mjs} +122 -50
  156. package/dist/client/client.mjs +5979 -5198
  157. package/dist/client/{courseRegistration-H3AZBUEG.mjs → courseRegistration-2D3ACMJR.mjs} +20 -58
  158. package/dist/client/{eventCalendar-FPKJGLGS.mjs → eventCalendar-QY4UZUFF.mjs} +11 -11
  159. package/dist/client/{eventCombined-QCGIZBUY.mjs → eventCombined-RRCDKJC2.mjs} +11 -11
  160. package/dist/client/{eventDetails-HIT3BJWU.mjs → eventDetails-YO335BUT.mjs} +11 -11
  161. package/dist/client/{eventListing-R4HNWJDN.mjs → eventListing-PXA6GFQ3.mjs} +11 -11
  162. package/dist/client/{eventRegistration-Q7BYY5HF.mjs → eventRegistration-2ZHEDDXO.mjs} +11 -11
  163. package/dist/client/{form-NI6YOG6S.mjs → form-ZS6KX4U2.mjs} +7 -7
  164. package/dist/client/{headerSection-SDYGII36.mjs → headerSection-QK5SLIIB.mjs} +3 -3
  165. package/dist/client/hooks.mjs +1102 -1029
  166. package/dist/client/{locationMap-BDETEUQD.mjs → locationMap-GFNIUD2X.mjs} +3 -3
  167. package/dist/client/{newsletterForm-EKYIU67X.mjs → newsletterForm-PGLTTCUG.mjs} +61 -25
  168. package/dist/client/{productDetail-5UTGNN76.mjs → productDetail-OPBE5ZPI.mjs} +8 -8
  169. package/dist/client/{productList-7YA5KXZQ.mjs → productList-NI72Q62Z.mjs} +8 -8
  170. package/dist/client/rendering/client.mjs +4390 -4245
  171. package/dist/client/rendering/islands.mjs +19 -19
  172. package/dist/client/rendering.mjs +3327 -3181
  173. package/dist/client/{shop-AIMUMZYC.mjs → shop-3ZQPEWYI.mjs} +8 -8
  174. package/dist/client/spam-protection.mjs +4 -5
  175. package/dist/preview-next/before-render.mjs +20 -2
  176. package/dist/preview-next/client/runtime.mjs +5 -5
  177. package/dist/preview-next/middleware.mjs +18 -0
  178. package/dist/{sdk-runtime-NW472WNT.mjs → sdk-runtime-FSHXCWDS.mjs} +6 -6
  179. package/dist/server/components.mjs +2580 -2783
  180. package/dist/server/config-validation.mjs +1334 -1261
  181. package/dist/server/config.mjs +1334 -1261
  182. package/dist/server/data.mjs +1102 -1029
  183. package/dist/server/index.mjs +1097 -476
  184. package/dist/server/navigation.mjs +20 -30
  185. package/dist/server/next.mjs +3282 -2847
  186. package/dist/server/page-converter.mjs +1009 -946
  187. package/dist/server/prebuild.mjs +1 -1
  188. package/dist/server/rendering/server.mjs +2580 -2783
  189. package/dist/server/rendering.mjs +2586 -2789
  190. package/dist/server/routing.mjs +1440 -1053
  191. package/dist/server/server.mjs +1886 -1153
  192. package/dist/server/theme-bridge.mjs +34 -5
  193. package/dist/styles/index.css +26 -0
  194. package/package.json +3 -2
  195. package/dist/SdkPreviewModeRuntime-ZALZDJEK.mjs +0 -8
  196. package/dist/client/chunk-H4MHEXYS.mjs +0 -184
  197. package/dist/client/chunk-ZFHRN6W2.mjs +0 -66
  198. /package/dist/client/{chunk-LI2C6M5O.mjs → chunk-25W2EQUN.mjs} +0 -0
@@ -3931,6 +3931,24 @@ function useBlockApi() {
3931
3931
  return client;
3932
3932
  }
3933
3933
 
3934
+ // ../blocks/src/system/runtime/api/types.ts
3935
+ function discountAvailabilityHasDiscounts(availability) {
3936
+ return availability.type !== "none";
3937
+ }
3938
+ function discountAvailabilityAllowsManualEntry(availability) {
3939
+ return "manualCodeEntryAllowed" in availability && availability.manualCodeEntryAllowed;
3940
+ }
3941
+ function getAutoAppliedDiscountPreview(availability) {
3942
+ switch (availability.type) {
3943
+ case "none":
3944
+ case "manual":
3945
+ return null;
3946
+ case "auto":
3947
+ case "auto_and_manual":
3948
+ return availability.autoAppliedDiscount;
3949
+ }
3950
+ }
3951
+
3934
3952
  // ../../node_modules/.pnpm/clsx@2.1.1/node_modules/clsx/dist/clsx.mjs
3935
3953
  function r(e) {
3936
3954
  var t, f, n = "";
@@ -5861,8 +5879,8 @@ function SpinnerNode({
5861
5879
  }
5862
5880
 
5863
5881
  // ../frontend-state/dist/index.mjs
5864
- var IDLE_FEEDBACK = idleFeedback();
5865
- function idleFeedback() {
5882
+ var IDLE_FEEDBACK$2 = idleFeedback$3();
5883
+ function idleFeedback$3() {
5866
5884
  return { tag: "idle" };
5867
5885
  }
5868
5886
  function clearWorkflowFeedback(state) {
@@ -5887,18 +5905,30 @@ function idleSubmissionFeedback() {
5887
5905
  return { tag: "idle" };
5888
5906
  }
5889
5907
  function errorSubmissionFeedback(message) {
5890
- return { tag: "error", message };
5908
+ return {
5909
+ tag: "error",
5910
+ message
5911
+ };
5891
5912
  }
5892
5913
  function successSubmissionFeedback(message) {
5893
- return { tag: "success", message };
5914
+ return {
5915
+ tag: "success",
5916
+ message
5917
+ };
5894
5918
  }
5895
- function okWith2(data) {
5896
- return { ok: true, data };
5919
+ function okWith(data) {
5920
+ return {
5921
+ ok: true,
5922
+ data
5923
+ };
5897
5924
  }
5898
5925
  function err2(error) {
5899
- return { ok: false, error };
5926
+ return {
5927
+ ok: false,
5928
+ error
5929
+ };
5900
5930
  }
5901
- function assertNever11(value, message) {
5931
+ function assertNever4(value, message) {
5902
5932
  throw new Error(message ?? `Unexpected value: ${String(value)}`);
5903
5933
  }
5904
5934
 
@@ -6053,7 +6083,7 @@ function deriveBookingFormViewState(input) {
6053
6083
  resourceName: input.verificationState.resourceName
6054
6084
  };
6055
6085
  default:
6056
- return assertNever11(input.verificationState);
6086
+ return assertNever4(input.verificationState);
6057
6087
  }
6058
6088
  }
6059
6089
  function resolveBookingSiteId(siteId, form) {
@@ -6223,7 +6253,7 @@ function getBookingServicePaymentSelectionMode(service) {
6223
6253
  case "flexible_balance":
6224
6254
  return "implicit_flexible_balance";
6225
6255
  default:
6226
- return assertNever11(onlyKind);
6256
+ return assertNever4(onlyKind);
6227
6257
  }
6228
6258
  }
6229
6259
  if (allowedKinds.length === 2 && allowedKinds.includes("upfront") && (allowedKinds.includes("deferred_manual") || allowedKinds.includes("instalment_plan") || allowedKinds.includes("flexible_balance"))) {
@@ -6425,7 +6455,7 @@ function formatBookingSubmissionPreparationError(error) {
6425
6455
  case "service-missing-duration":
6426
6456
  return `Service "${error.serviceTitle}" is missing duration. Please update the service in the dashboard to include a duration (e.g., 30 minutes).`;
6427
6457
  default:
6428
- return assertNever11(error);
6458
+ return assertNever4(error);
6429
6459
  }
6430
6460
  }
6431
6461
  function getBookingSuccessMessage(successMessage) {
@@ -11844,7 +11874,7 @@ function findEventByOccurrenceId(events, occurrenceId) {
11844
11874
  function findPreSelectedEvent(input) {
11845
11875
  const occurrenceContext = input.occurrenceContext;
11846
11876
  if (!occurrenceContext) {
11847
- return null;
11877
+ return input.scopedEvents.length === 1 ? input.scopedEvents[0] ?? null : null;
11848
11878
  }
11849
11879
  const contextDate = getBookingLocalDateKey(toScheduledBookingDateTime({
11850
11880
  startsAt: occurrenceContext.startsAt,
@@ -11950,11 +11980,10 @@ function FeedbackMessage({
11950
11980
  }
11951
11981
 
11952
11982
  // ../blocks/src/system/runtime/nodes/booking-form.client.tsx
11953
- import React3, { useRef as useRef7, useState as useState5 } from "react";
11983
+ import React3, { useRef as useRef8, useState as useState2 } from "react";
11954
11984
 
11955
11985
  // ../altcha/src/AltchaWidget.tsx
11956
- import { useEffect, useRef } from "react";
11957
- import { jsx as jsx4 } from "react/jsx-runtime";
11986
+ import { createElement, useEffect, useRef } from "react";
11958
11987
  function AltchaWidget({
11959
11988
  challengeUrl,
11960
11989
  onSolutionChange,
@@ -11998,7 +12027,7 @@ function AltchaWidget({
11998
12027
  }
11999
12028
  };
12000
12029
  }, [challengeUrl, auto, hidelogo, className, onSolutionChange]);
12001
- return /* @__PURE__ */ jsx4("div", { ref: containerRef });
12030
+ return createElement("div", { ref: containerRef });
12002
12031
  }
12003
12032
 
12004
12033
  // ../altcha/src/client.ts
@@ -12007,13 +12036,13 @@ function isSpamProtectionEnabled() {
12007
12036
  }
12008
12037
 
12009
12038
  // ../blocks/src/system/runtime/components/booking/SuccessMessage.tsx
12010
- import { Fragment, jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
12039
+ import { Fragment, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
12011
12040
  var SuccessMessage = ({
12012
12041
  message,
12013
12042
  resourceName,
12014
12043
  className
12015
12044
  }) => {
12016
- return /* @__PURE__ */ jsx5(
12045
+ return /* @__PURE__ */ jsx4(
12017
12046
  FeedbackMessage,
12018
12047
  {
12019
12048
  tone: "success",
@@ -12021,7 +12050,7 @@ var SuccessMessage = ({
12021
12050
  role: "alert",
12022
12051
  live: "polite",
12023
12052
  children: /* @__PURE__ */ jsxs3(Fragment, { children: [
12024
- /* @__PURE__ */ jsx5("p", { className: "ab-text", children: message }),
12053
+ /* @__PURE__ */ jsx4("p", { className: "ab-text", children: message }),
12025
12054
  resourceName ? /* @__PURE__ */ jsxs3("p", { className: "ab-text ab-text--muted", children: [
12026
12055
  "Practitioner: ",
12027
12056
  resourceName
@@ -12037,9 +12066,9 @@ import React2, {
12037
12066
  useEffect as useEffect6,
12038
12067
  useLayoutEffect,
12039
12068
  useMemo as useMemo2,
12040
- useReducer as useReducer2,
12041
- useRef as useRef5,
12042
- useState as useState4
12069
+ useReducer as useReducer5,
12070
+ useRef as useRef6,
12071
+ useState
12043
12072
  } from "react";
12044
12073
 
12045
12074
  // ../../node_modules/.pnpm/altcha-lib@1.4.1/node_modules/altcha-lib/dist/helpers.js
@@ -12066,7 +12095,7 @@ function getChallengeUrl() {
12066
12095
  }
12067
12096
 
12068
12097
  // ../blocks/src/system/runtime/hooks/useAvailableDates.ts
12069
- import { useState, useEffect as useEffect3, useCallback, useRef as useRef3 } from "react";
12098
+ import { useEffect as useEffect3, useCallback, useReducer, useRef as useRef3 } from "react";
12070
12099
 
12071
12100
  // ../blocks/src/utils/date-formatting.ts
12072
12101
  var BOOKING_FETCH_CHUNK_DAYS = 14;
@@ -12175,6 +12204,75 @@ function useVisibleTabPolling({
12175
12204
  }, [enabled, intervalMs, jitterMs, minVisibleRefreshIntervalMs]);
12176
12205
  }
12177
12206
 
12207
+ // ../blocks/src/system/runtime/hooks/useAvailableDates.state.ts
12208
+ function createEmptyAvailableDatesData() {
12209
+ return {
12210
+ availableDates: /* @__PURE__ */ new Set(),
12211
+ hasMore: false,
12212
+ loadedRange: null,
12213
+ nextStartDate: null
12214
+ };
12215
+ }
12216
+ function createInitialAvailableDatesState() {
12217
+ return {
12218
+ tag: "idle",
12219
+ data: createEmptyAvailableDatesData()
12220
+ };
12221
+ }
12222
+ var initialAvailableDatesState = createInitialAvailableDatesState();
12223
+ function getAvailableDates(state) {
12224
+ return state.data.availableDates;
12225
+ }
12226
+ function getAvailableDatesLoadedRange(state) {
12227
+ return state.data.loadedRange;
12228
+ }
12229
+ function getAvailableDatesNextStartDate(state) {
12230
+ return state.data.nextStartDate;
12231
+ }
12232
+ function hasMoreAvailableDates(state) {
12233
+ return state.data.hasMore;
12234
+ }
12235
+ function isLoadingAvailableDates(state) {
12236
+ return state.tag === "loading";
12237
+ }
12238
+ function isRefreshingAvailableDates(state) {
12239
+ return state.tag === "refreshing";
12240
+ }
12241
+ function getAvailableDatesError(state) {
12242
+ return state.tag === "error" ? state.message : null;
12243
+ }
12244
+ function mergeAvailableDates(previous, action) {
12245
+ const availableDates = action.append ? new Set(previous.availableDates) : /* @__PURE__ */ new Set();
12246
+ for (const date of action.dates) {
12247
+ availableDates.add(date);
12248
+ }
12249
+ return {
12250
+ availableDates,
12251
+ hasMore: action.hasMore,
12252
+ loadedRange: {
12253
+ start: action.append && previous.loadedRange ? previous.loadedRange.start : action.startDate,
12254
+ end: action.endDate
12255
+ },
12256
+ nextStartDate: action.nextStartDate
12257
+ };
12258
+ }
12259
+ function availableDatesReducer(state, action) {
12260
+ switch (action.type) {
12261
+ case "query-cleared":
12262
+ return { tag: "idle", data: createEmptyAvailableDatesData() };
12263
+ case "load-started":
12264
+ return { tag: "loading", data: state.data };
12265
+ case "refresh-started":
12266
+ return { tag: "refreshing", data: state.data };
12267
+ case "load-succeeded":
12268
+ return { tag: "loaded", data: mergeAvailableDates(state.data, action) };
12269
+ case "load-failed":
12270
+ return { tag: "error", data: state.data, message: action.message };
12271
+ default:
12272
+ return assertNever4(action);
12273
+ }
12274
+ }
12275
+
12178
12276
  // ../blocks/src/system/runtime/hooks/useAvailableDates.ts
12179
12277
  var AVAILABILITY_REFRESH_INTERVAL_MS = 3e4;
12180
12278
  var AVAILABILITY_REFRESH_JITTER_MS = 5e3;
@@ -12187,25 +12285,23 @@ function useAvailableDates({
12187
12285
  initialDays = 30
12188
12286
  }) {
12189
12287
  const api = useBlockApi();
12190
- const [availableDates, setAvailableDates] = useState(/* @__PURE__ */ new Set());
12191
- const [isLoading, setIsLoading] = useState(false);
12192
- const [isRefreshing, setIsRefreshing] = useState(false);
12193
- const [error, setError] = useState(null);
12194
- const [hasMore, setHasMore] = useState(false);
12195
- const [loadedRange, setLoadedRange] = useState(null);
12196
- const nextStartDateRef = useRef3(null);
12288
+ const [state, dispatch] = useReducer(
12289
+ availableDatesReducer,
12290
+ createInitialAvailableDatesState()
12291
+ );
12197
12292
  const requestIdRef = useRef3(0);
12293
+ const loadedRange = getAvailableDatesLoadedRange(state);
12294
+ const isLoading = isLoadingAvailableDates(state);
12295
+ const nextStartDate = getAvailableDatesNextStartDate(state);
12198
12296
  const fetchDates = useCallback(
12199
12297
  async (startDate, endDate, append = false, mode = "load") => {
12200
12298
  if (!serviceId) return;
12201
12299
  const requestId = ++requestIdRef.current;
12202
12300
  if (mode === "refresh") {
12203
- setIsRefreshing(true);
12301
+ dispatch({ type: "refresh-started" });
12204
12302
  } else {
12205
- setIsLoading(true);
12206
- setIsRefreshing(false);
12303
+ dispatch({ type: "load-started" });
12207
12304
  }
12208
- setError(null);
12209
12305
  try {
12210
12306
  const data = await api.getAvailableDates({
12211
12307
  serviceId,
@@ -12215,38 +12311,29 @@ function useAvailableDates({
12215
12311
  resourceId
12216
12312
  });
12217
12313
  if (requestId !== requestIdRef.current) return;
12218
- setAvailableDates((prev) => {
12219
- const newSet = append ? new Set(prev) : /* @__PURE__ */ new Set();
12220
- data.dates.forEach((d) => newSet.add(d));
12221
- return newSet;
12314
+ dispatch({
12315
+ type: "load-succeeded",
12316
+ dates: data.dates,
12317
+ hasMore: data.hasMore,
12318
+ nextStartDate: data.nextStartDate || null,
12319
+ startDate: data.startDate,
12320
+ endDate: data.endDate,
12321
+ append
12222
12322
  });
12223
- setHasMore(data.hasMore);
12224
- nextStartDateRef.current = data.nextStartDate || null;
12225
- setLoadedRange((prev) => ({
12226
- start: append && prev ? prev.start : data.startDate,
12227
- end: data.endDate
12228
- }));
12229
12323
  } catch (err3) {
12230
12324
  if (requestId !== requestIdRef.current) return;
12231
- setError(
12232
- err3 instanceof Error ? err3.message : "Failed to load available dates"
12233
- );
12234
- } finally {
12235
- if (mode === "refresh" && requestId === requestIdRef.current) {
12236
- setIsRefreshing(false);
12237
- } else if (requestId === requestIdRef.current) {
12238
- setIsLoading(false);
12239
- }
12325
+ dispatch({
12326
+ type: "load-failed",
12327
+ message: err3 instanceof Error ? err3.message : "Failed to load available dates"
12328
+ });
12240
12329
  }
12241
12330
  },
12242
12331
  [api, serviceId, resourceId, timezone]
12243
12332
  );
12244
12333
  useEffect3(() => {
12245
12334
  if (!serviceId) {
12246
- setAvailableDates(/* @__PURE__ */ new Set());
12247
- setLoadedRange(null);
12248
- setHasMore(false);
12249
- setIsRefreshing(false);
12335
+ requestIdRef.current += 1;
12336
+ dispatch({ type: "query-cleared" });
12250
12337
  return;
12251
12338
  }
12252
12339
  const now = /* @__PURE__ */ new Date();
@@ -12270,8 +12357,8 @@ function useAvailableDates({
12270
12357
  }
12271
12358
  });
12272
12359
  const loadMore = useCallback(() => {
12273
- if (!nextStartDateRef.current || isLoading) return;
12274
- const start = nextStartDateRef.current;
12360
+ if (!nextStartDate || isLoading) return;
12361
+ const start = nextStartDate;
12275
12362
  const end = formatLocalScheduleDate(
12276
12363
  addLocalScheduleDays(
12277
12364
  parseBookingLocalDate(start),
@@ -12279,20 +12366,86 @@ function useAvailableDates({
12279
12366
  )
12280
12367
  );
12281
12368
  void fetchDates(start, end, true);
12282
- }, [fetchDates, isLoading]);
12369
+ }, [fetchDates, isLoading, nextStartDate]);
12283
12370
  return {
12284
- availableDates,
12371
+ availableDates: getAvailableDates(state),
12285
12372
  isLoading,
12286
- isRefreshing,
12287
- error,
12288
- hasMore,
12373
+ isRefreshing: isRefreshingAvailableDates(state),
12374
+ error: getAvailableDatesError(state),
12375
+ hasMore: hasMoreAvailableDates(state),
12289
12376
  loadMore,
12290
12377
  loadedRange
12291
12378
  };
12292
12379
  }
12293
12380
 
12294
12381
  // ../blocks/src/system/runtime/hooks/useAvailableSlots.ts
12295
- import { useState as useState2, useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4 } from "react";
12382
+ import { useCallback as useCallback2, useEffect as useEffect4, useReducer as useReducer2, useRef as useRef4 } from "react";
12383
+
12384
+ // ../blocks/src/system/runtime/hooks/useAvailableSlots.state.ts
12385
+ var initialAvailableSlotsState = { tag: "idle" };
12386
+ function getAvailableSlots(state) {
12387
+ switch (state.tag) {
12388
+ case "idle":
12389
+ case "loading":
12390
+ return [];
12391
+ case "loaded":
12392
+ case "refreshing":
12393
+ case "error":
12394
+ return state.slots;
12395
+ default:
12396
+ return assertNever4(state);
12397
+ }
12398
+ }
12399
+ function hasLoadedAvailableSlots(state) {
12400
+ switch (state.tag) {
12401
+ case "idle":
12402
+ return false;
12403
+ case "loading":
12404
+ case "refreshing":
12405
+ case "error":
12406
+ return state.hasLoaded;
12407
+ case "loaded":
12408
+ return true;
12409
+ default:
12410
+ return assertNever4(state);
12411
+ }
12412
+ }
12413
+ function isLoadingAvailableSlots(state) {
12414
+ return state.tag === "loading";
12415
+ }
12416
+ function isRefreshingAvailableSlots(state) {
12417
+ return state.tag === "refreshing";
12418
+ }
12419
+ function getAvailableSlotsError(state) {
12420
+ return state.tag === "error" ? state.message : null;
12421
+ }
12422
+ function availableSlotsReducer(state, action) {
12423
+ switch (action.type) {
12424
+ case "query-cleared":
12425
+ return { tag: "idle" };
12426
+ case "load-started":
12427
+ return { tag: "loading", hasLoaded: hasLoadedAvailableSlots(state) };
12428
+ case "refresh-started":
12429
+ return {
12430
+ tag: "refreshing",
12431
+ slots: getAvailableSlots(state),
12432
+ hasLoaded: hasLoadedAvailableSlots(state)
12433
+ };
12434
+ case "load-succeeded":
12435
+ return { tag: "loaded", slots: action.slots };
12436
+ case "load-failed":
12437
+ return {
12438
+ tag: "error",
12439
+ slots: getAvailableSlots(state),
12440
+ hasLoaded: hasLoadedAvailableSlots(state),
12441
+ message: action.message
12442
+ };
12443
+ default:
12444
+ return assertNever4(action);
12445
+ }
12446
+ }
12447
+
12448
+ // ../blocks/src/system/runtime/hooks/useAvailableSlots.ts
12296
12449
  var AVAILABILITY_REFRESH_INTERVAL_MS2 = 3e4;
12297
12450
  var AVAILABILITY_REFRESH_JITTER_MS2 = 5e3;
12298
12451
  function useAvailableSlots({
@@ -12304,31 +12457,23 @@ function useAvailableSlots({
12304
12457
  timezone
12305
12458
  }) {
12306
12459
  const api = useBlockApi();
12307
- const [slots, setSlots] = useState2([]);
12308
- const [isLoading, setIsLoading] = useState2(false);
12309
- const [isRefreshing, setIsRefreshing] = useState2(false);
12310
- const [hasLoaded, setHasLoaded] = useState2(false);
12311
- const [error, setError] = useState2(null);
12460
+ const [state, dispatch] = useReducer2(
12461
+ availableSlotsReducer,
12462
+ initialAvailableSlotsState
12463
+ );
12312
12464
  const requestIdRef = useRef4(0);
12313
12465
  const fetchSlots = useCallback2(
12314
12466
  async (mode) => {
12315
12467
  const requestId = ++requestIdRef.current;
12316
12468
  if (!selectedDate || !serviceId) {
12317
- setSlots([]);
12318
- setIsLoading(false);
12319
- setIsRefreshing(false);
12320
- setHasLoaded(false);
12321
- setError(null);
12469
+ dispatch({ type: "query-cleared" });
12322
12470
  return;
12323
12471
  }
12324
12472
  if (mode === "refresh") {
12325
- setIsRefreshing(true);
12473
+ dispatch({ type: "refresh-started" });
12326
12474
  } else {
12327
- setIsLoading(true);
12328
- setIsRefreshing(false);
12329
- setSlots([]);
12475
+ dispatch({ type: "load-started" });
12330
12476
  }
12331
- setError(null);
12332
12477
  try {
12333
12478
  const result = await api.getAvailableSlots({
12334
12479
  serviceId,
@@ -12338,24 +12483,19 @@ function useAvailableSlots({
12338
12483
  resourceId
12339
12484
  });
12340
12485
  if (requestId !== requestIdRef.current) return;
12341
- setSlots(
12342
- result.slots.map((slot) => ({
12486
+ dispatch({
12487
+ type: "load-succeeded",
12488
+ slots: result.slots.map((slot) => ({
12343
12489
  ...slot,
12344
12490
  resourceId: unsafeAsAppointmentResourceId(slot.resourceId)
12345
12491
  }))
12346
- );
12347
- setHasLoaded(true);
12492
+ });
12348
12493
  } catch (err3) {
12349
12494
  if (requestId !== requestIdRef.current) return;
12350
- setError(
12351
- err3 instanceof Error ? err3.message : "Failed to load available times"
12352
- );
12353
- } finally {
12354
- if (mode === "refresh" && requestId === requestIdRef.current) {
12355
- setIsRefreshing(false);
12356
- } else if (requestId === requestIdRef.current) {
12357
- setIsLoading(false);
12358
- }
12495
+ dispatch({
12496
+ type: "load-failed",
12497
+ message: err3 instanceof Error ? err3.message : "Failed to load available times"
12498
+ });
12359
12499
  }
12360
12500
  },
12361
12501
  [selectedDate, serviceId, resourceId, timezone, api]
@@ -12372,11 +12512,17 @@ function useAvailableSlots({
12372
12512
  jitterMs: AVAILABILITY_REFRESH_JITTER_MS2,
12373
12513
  onPoll: () => fetchSlots("refresh")
12374
12514
  });
12375
- return { slots, isLoading, isRefreshing, hasLoaded, error };
12515
+ return {
12516
+ slots: getAvailableSlots(state),
12517
+ isLoading: isLoadingAvailableSlots(state),
12518
+ isRefreshing: isRefreshingAvailableSlots(state),
12519
+ hasLoaded: hasLoadedAvailableSlots(state),
12520
+ error: getAvailableSlotsError(state)
12521
+ };
12376
12522
  }
12377
12523
 
12378
12524
  // ../blocks/src/system/runtime/hooks/useBookingSubmission.ts
12379
- import { useReducer } from "react";
12525
+ import { useReducer as useReducer3 } from "react";
12380
12526
 
12381
12527
  // ../blocks/src/system/runtime/hooks/useBookingSubmission.state.ts
12382
12528
  var initialBookingSubmissionState = {
@@ -12404,7 +12550,7 @@ function bookingSubmissionReducer(state, action) {
12404
12550
  case "feedback-cleared":
12405
12551
  return clearWorkflowFeedback(state);
12406
12552
  default:
12407
- return assertNever11(action);
12553
+ return assertNever4(action);
12408
12554
  }
12409
12555
  }
12410
12556
  function selectIsSubmitting(state) {
@@ -12414,7 +12560,7 @@ function selectIsSubmitting(state) {
12414
12560
  // ../blocks/src/system/runtime/hooks/useBookingSubmission.ts
12415
12561
  function useBookingSubmission(_siteId) {
12416
12562
  const api = useBlockApi();
12417
- const [state, dispatch] = useReducer(
12563
+ const [state, dispatch] = useReducer3(
12418
12564
  bookingSubmissionReducer,
12419
12565
  initialBookingSubmissionState
12420
12566
  );
@@ -12448,7 +12594,7 @@ function useBookingSubmission(_siteId) {
12448
12594
  type: "submission-succeeded",
12449
12595
  message: response.type === "checkout_redirect" ? "Redirecting to secure checkout..." : "Booking submitted successfully."
12450
12596
  });
12451
- return okWith2(response);
12597
+ return okWith(response);
12452
12598
  } catch (error) {
12453
12599
  console.error("Booking submission error:", error);
12454
12600
  const message = error instanceof Error ? error.message : "Failed to book appointment";
@@ -12469,65 +12615,157 @@ function useBookingSubmission(_siteId) {
12469
12615
  }
12470
12616
 
12471
12617
  // ../blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.ts
12472
- import { useEffect as useEffect5, useState as useState3 } from "react";
12618
+ import { useEffect as useEffect5, useReducer as useReducer4, useRef as useRef5 } from "react";
12619
+
12620
+ // ../blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.state.ts
12621
+ var initialDiscountCodeUiState = {
12622
+ discountUiOpen: false,
12623
+ discountCode: "",
12624
+ availability: { tag: "disabled" }
12625
+ };
12626
+ function getDiscountContextKey(context) {
12627
+ if (!context) return "disabled";
12628
+ switch (context.type) {
12629
+ case "event":
12630
+ return [
12631
+ context.type,
12632
+ context.eventSeriesId,
12633
+ context.eventCategoryId ?? "",
12634
+ context.ticketsCount ?? ""
12635
+ ].join(":");
12636
+ case "appointment":
12637
+ return [context.type, context.serviceId].join(":");
12638
+ case "course":
12639
+ return [context.type, context.courseId].join(":");
12640
+ case "pass":
12641
+ return [context.type, context.passId].join(":");
12642
+ case "membership":
12643
+ return [context.type, context.membershipId].join(":");
12644
+ case "product":
12645
+ return [context.type, context.productId, context.productCategoryId ?? ""].join(":");
12646
+ }
12647
+ }
12648
+ function buildDiscountAvailabilityRequestPlan(options) {
12649
+ if (!options.discountContext) {
12650
+ return { ok: false, key: "disabled" };
12651
+ }
12652
+ const subtotalCents = options.subtotalCents;
12653
+ const key = [
12654
+ getDiscountContextKey(options.discountContext),
12655
+ subtotalCents ?? ""
12656
+ ].join("|");
12657
+ return {
12658
+ ok: true,
12659
+ key,
12660
+ request: {
12661
+ context: options.discountContext,
12662
+ ...subtotalCents !== void 0 ? { subtotalCents } : {}
12663
+ }
12664
+ };
12665
+ }
12666
+ function discountAvailabilityStateFromResponse(response) {
12667
+ if (!discountAvailabilityHasDiscounts(response)) {
12668
+ return { tag: "unavailable" };
12669
+ }
12670
+ return {
12671
+ tag: "available",
12672
+ manualCodeEntryAllowed: discountAvailabilityAllowsManualEntry(response),
12673
+ autoAppliedDiscount: getAutoAppliedDiscountPreview(response)
12674
+ };
12675
+ }
12676
+ function discountCodeUiReducer(state, event) {
12677
+ switch (event.type) {
12678
+ case "availability-disabled":
12679
+ return initialDiscountCodeUiState;
12680
+ case "availability-loading":
12681
+ return {
12682
+ ...state,
12683
+ availability: { tag: "loading" }
12684
+ };
12685
+ case "availability-loaded": {
12686
+ const availability = discountAvailabilityStateFromResponse(event.response);
12687
+ if (availability.tag !== "available" || !availability.manualCodeEntryAllowed) {
12688
+ return {
12689
+ ...state,
12690
+ discountUiOpen: false,
12691
+ discountCode: "",
12692
+ availability
12693
+ };
12694
+ }
12695
+ return {
12696
+ ...state,
12697
+ availability
12698
+ };
12699
+ }
12700
+ case "availability-failed":
12701
+ return {
12702
+ ...state,
12703
+ discountUiOpen: false,
12704
+ discountCode: "",
12705
+ availability: { tag: "error" }
12706
+ };
12707
+ case "discount-code-changed":
12708
+ return {
12709
+ ...state,
12710
+ discountCode: event.code
12711
+ };
12712
+ case "discount-ui-open-changed":
12713
+ return {
12714
+ ...state,
12715
+ discountUiOpen: event.isOpen
12716
+ };
12717
+ }
12718
+ }
12719
+
12720
+ // ../blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.ts
12721
+ function useStableDiscountAvailabilityRequestPlan(options) {
12722
+ const nextPlan = buildDiscountAvailabilityRequestPlan(options);
12723
+ const planRef = useRef5(nextPlan);
12724
+ if (planRef.current.key !== nextPlan.key) {
12725
+ planRef.current = nextPlan;
12726
+ }
12727
+ return planRef.current;
12728
+ }
12473
12729
  function useDiscountCodeUi(options) {
12474
- const [discountUiOpen, setDiscountUiOpen] = useState3(false);
12475
- const [discountCode, setDiscountCode] = useState3("");
12476
- const [discountsAvailable, setDiscountsAvailable] = useState3(false);
12477
- const [manualCodeEntryAllowed, setManualCodeEntryAllowed] = useState3(false);
12478
- const [autoAppliedDiscount, setAutoAppliedDiscount] = useState3(null);
12479
- const [discountsAvailableLoading, setDiscountsAvailableLoading] = useState3(false);
12730
+ const [state, dispatch] = useReducer4(
12731
+ discountCodeUiReducer,
12732
+ initialDiscountCodeUiState
12733
+ );
12734
+ const requestPlan = useStableDiscountAvailabilityRequestPlan(options);
12480
12735
  useEffect5(() => {
12481
12736
  let cancelled = false;
12482
12737
  async function checkDiscountAvailability() {
12483
- if (!options.discountContext) {
12484
- setDiscountsAvailable(false);
12485
- setManualCodeEntryAllowed(false);
12486
- setAutoAppliedDiscount(null);
12487
- setDiscountsAvailableLoading(false);
12488
- setDiscountUiOpen(false);
12489
- setDiscountCode("");
12738
+ if (!requestPlan.ok) {
12739
+ dispatch({ type: "availability-disabled" });
12490
12740
  return;
12491
12741
  }
12492
- setDiscountsAvailableLoading(true);
12742
+ dispatch({ type: "availability-loading" });
12493
12743
  try {
12494
- const res = await options.api.getDiscountsAvailable({
12495
- context: options.discountContext,
12496
- subtotalCents: options.subtotalCents
12497
- });
12744
+ const res = await options.api.getDiscountsAvailable(requestPlan.request);
12498
12745
  if (cancelled) return;
12499
- setDiscountsAvailable(res.hasDiscounts);
12500
- setManualCodeEntryAllowed(res.manualCodeEntryAllowed);
12501
- setAutoAppliedDiscount(res.autoAppliedDiscount);
12502
- if (!res.hasDiscounts || !res.manualCodeEntryAllowed) {
12503
- setDiscountUiOpen(false);
12504
- setDiscountCode("");
12505
- }
12746
+ dispatch({ type: "availability-loaded", response: res });
12506
12747
  } catch {
12507
12748
  if (cancelled) return;
12508
- setDiscountsAvailable(false);
12509
- setManualCodeEntryAllowed(false);
12510
- setAutoAppliedDiscount(null);
12511
- setDiscountUiOpen(false);
12512
- setDiscountCode("");
12513
- } finally {
12514
- if (!cancelled) setDiscountsAvailableLoading(false);
12749
+ dispatch({ type: "availability-failed" });
12515
12750
  }
12516
12751
  }
12517
12752
  void checkDiscountAvailability();
12518
12753
  return () => {
12519
12754
  cancelled = true;
12520
12755
  };
12521
- }, [options.api, options.discountContext, options.subtotalCents]);
12756
+ }, [options.api, requestPlan]);
12757
+ const availability = state.availability;
12758
+ const isAvailable = availability.tag === "available";
12759
+ const manualCodeEntryAllowed = isAvailable ? availability.manualCodeEntryAllowed : false;
12522
12760
  return {
12523
- discountUiOpen,
12524
- setDiscountUiOpen,
12525
- discountCode,
12526
- setDiscountCode,
12527
- discountsAvailable,
12761
+ discountUiOpen: state.discountUiOpen,
12762
+ setDiscountUiOpen: (isOpen) => dispatch({ type: "discount-ui-open-changed", isOpen }),
12763
+ discountCode: state.discountCode,
12764
+ setDiscountCode: (code) => dispatch({ type: "discount-code-changed", code }),
12765
+ discountsAvailable: isAvailable,
12528
12766
  manualCodeEntryAllowed,
12529
- autoAppliedDiscount,
12530
- discountsAvailableLoading
12767
+ autoAppliedDiscount: isAvailable ? availability.autoAppliedDiscount : null,
12768
+ discountsAvailableLoading: availability.tag === "loading"
12531
12769
  };
12532
12770
  }
12533
12771
 
@@ -12710,7 +12948,7 @@ function buildBookingPaymentOptionViewModel(input) {
12710
12948
  };
12711
12949
  }
12712
12950
  default:
12713
- return assertNever11(input.option);
12951
+ return assertNever4(input.option);
12714
12952
  }
12715
12953
  }
12716
12954
  function buildInstalmentSchedulePreview(input) {
@@ -12767,7 +13005,7 @@ function buildInstalmentSchedulePreview(input) {
12767
13005
  })));
12768
13006
  }
12769
13007
  default:
12770
- return assertNever11(input.option.plan);
13008
+ return assertNever4(input.option.plan);
12771
13009
  }
12772
13010
  }
12773
13011
  function getPaymentCadenceLabel(plan) {
@@ -12994,7 +13232,7 @@ function bookingFlowReducer(state, event) {
12994
13232
  case "reset":
12995
13233
  return event.initial;
12996
13234
  default:
12997
- return assertNever11(event);
13235
+ return assertNever4(event);
12998
13236
  }
12999
13237
  }
13000
13238
  function clearAvailabilityFeedback(feedback) {
@@ -13123,7 +13361,7 @@ function validateBookingStep(input) {
13123
13361
  return Object.keys(errors).length > 0 ? { ok: false, errors: createFieldBookingValidationErrors(errors) } : { ok: true };
13124
13362
  }
13125
13363
  default:
13126
- return assertNever11(input.stepId);
13364
+ return assertNever4(input.stepId);
13127
13365
  }
13128
13366
  }
13129
13367
  function validateBookingFields(input) {
@@ -13484,7 +13722,7 @@ function resolveAppointmentPackagesModel(input) {
13484
13722
  };
13485
13723
  }
13486
13724
  default:
13487
- return assertNever11(input.state);
13725
+ return assertNever4(input.state);
13488
13726
  }
13489
13727
  }
13490
13728
  function toHeadlessEligibleAppointmentPackage(appointmentPackage) {
@@ -13589,12 +13827,12 @@ function useHeadlessBookingFlow(options) {
13589
13827
  }),
13590
13828
  [defaultResourceId, defaultServiceId, options.initialData]
13591
13829
  );
13592
- const [state, dispatch] = useReducer2(bookingFlowReducer, initialState);
13830
+ const [state, dispatch] = useReducer5(bookingFlowReducer, initialState);
13593
13831
  const api = useBlockApi();
13594
- const [resourcesState, setResourcesState] = useState4({ tag: "idle" });
13595
- const resourcesRequestIdRef = useRef5(0);
13596
- const [appointmentPackages, setAppointmentPackages] = useState4({ tag: "idle" });
13597
- const appointmentPackagesRequestIdRef = useRef5(0);
13832
+ const [resourcesState, setResourcesState] = useState({ tag: "idle" });
13833
+ const resourcesRequestIdRef = useRef6(0);
13834
+ const [appointmentPackages, setAppointmentPackages] = useState({ tag: "idle" });
13835
+ const appointmentPackagesRequestIdRef = useRef6(0);
13598
13836
  const selectedServiceId = state.selectedServiceId ?? defaultServiceId;
13599
13837
  const selectedResourceId = state.selectedResourceId ?? defaultResourceId;
13600
13838
  const selectedService = options.services.find((service) => service.id === selectedServiceId) ?? null;
@@ -13831,14 +14069,17 @@ function useHeadlessBookingFlow(options) {
13831
14069
  state.selectedDate,
13832
14070
  state.selectedSlot
13833
14071
  ]);
13834
- const appointmentDiscountContext = selectedService && (selectedService.priceAmount ?? 0) > 0 ? { type: "appointment", serviceId: selectedService.id } : null;
14072
+ const appointmentDiscountContext = useMemo2(
14073
+ () => selectedService && (selectedService.priceAmount ?? 0) > 0 ? { type: "appointment", serviceId: selectedService.id } : null,
14074
+ [selectedService?.id, selectedService?.priceAmount]
14075
+ );
13835
14076
  const discountUi = useDiscountCodeUi({
13836
14077
  api,
13837
14078
  discountContext: appointmentDiscountContext,
13838
14079
  subtotalCents: selectedService?.priceAmount ?? 0
13839
14080
  });
13840
14081
  const { submit, clearFeedback } = useBookingSubmission(options.siteId);
13841
- const submittingRef = useRef5(false);
14082
+ const submittingRef = useRef6(false);
13842
14083
  const latestRef = useLatestRef({
13843
14084
  state,
13844
14085
  data,
@@ -14155,7 +14396,7 @@ function resolvePaymentMode(input) {
14155
14396
  return resolveBookingPaymentStep(input);
14156
14397
  }
14157
14398
  function useLatestRef(value) {
14158
- const ref = useRef5(value);
14399
+ const ref = useRef6(value);
14159
14400
  useLayoutEffect(() => {
14160
14401
  ref.current = value;
14161
14402
  }, [value]);
@@ -14166,7 +14407,7 @@ function useLatestRef(value) {
14166
14407
  import { useMemo as useMemo3 } from "react";
14167
14408
 
14168
14409
  // ../blocks/src/system/runtime/hooks/usePolling.ts
14169
- import { useEffect as useEffect7, useCallback as useCallback4, useReducer as useReducer3, useRef as useRef6 } from "react";
14410
+ import { useEffect as useEffect7, useCallback as useCallback4, useReducer as useReducer6, useRef as useRef7 } from "react";
14170
14411
 
14171
14412
  // ../blocks/src/system/runtime/hooks/usePolling.state.ts
14172
14413
  function createInitialPollingState() {
@@ -14223,7 +14464,7 @@ function pollingReducer(state, action) {
14223
14464
  case "timeout":
14224
14465
  return state;
14225
14466
  default:
14226
- return assertNever11(state);
14467
+ return assertNever4(state);
14227
14468
  }
14228
14469
  case "polling-timed-out":
14229
14470
  return {
@@ -14232,7 +14473,7 @@ function pollingReducer(state, action) {
14232
14473
  error: new Error("Polling timed out")
14233
14474
  };
14234
14475
  default:
14235
- return assertNever11(action);
14476
+ return assertNever4(action);
14236
14477
  }
14237
14478
  }
14238
14479
 
@@ -14240,17 +14481,17 @@ function pollingReducer(state, action) {
14240
14481
  var DEFAULT_MAX_ATTEMPTS = 10;
14241
14482
  var DEFAULT_POLL_INTERVAL = 1e3;
14242
14483
  function usePolling(config) {
14243
- const [state, dispatch] = useReducer3(
14484
+ const [state, dispatch] = useReducer6(
14244
14485
  pollingReducer,
14245
14486
  void 0,
14246
14487
  createInitialPollingState
14247
14488
  );
14248
- const attemptsRef = useRef6(0);
14249
- const timeoutRef = useRef6(null);
14250
- const isPollingRef = useRef6(false);
14251
- const isActiveRef = useRef6(false);
14252
- const generationRef = useRef6(0);
14253
- const configRef = useRef6(config);
14489
+ const attemptsRef = useRef7(0);
14490
+ const timeoutRef = useRef7(null);
14491
+ const isPollingRef = useRef7(false);
14492
+ const isActiveRef = useRef7(false);
14493
+ const generationRef = useRef7(0);
14494
+ const configRef = useRef7(config);
14254
14495
  configRef.current = config;
14255
14496
  const cleanup = useCallback4(() => {
14256
14497
  isActiveRef.current = false;
@@ -14374,7 +14615,7 @@ function useAppointmentCheckoutVerification(config) {
14374
14615
  }
14375
14616
 
14376
14617
  // ../blocks/src/system/runtime/components/booking/DatePicker.tsx
14377
- import { jsx as jsx6, jsxs as jsxs4 } from "react/jsx-runtime";
14618
+ import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
14378
14619
  var DatePicker = ({
14379
14620
  value,
14380
14621
  onChange,
@@ -14389,21 +14630,21 @@ var DatePicker = ({
14389
14630
  return /* @__PURE__ */ jsxs4("div", { className: "ab-stack--sm", children: [
14390
14631
  /* @__PURE__ */ jsxs4("label", { className: "ab-label", children: [
14391
14632
  "Select Date",
14392
- required && /* @__PURE__ */ jsx6("span", { className: "ab-required", children: "*" })
14633
+ required && /* @__PURE__ */ jsx5("span", { className: "ab-required", children: "*" })
14393
14634
  ] }),
14394
- /* @__PURE__ */ jsx6("div", { className: "ab-skeleton" }),
14395
- /* @__PURE__ */ jsx6("p", { className: "ab-text ab-text--muted ab-text--sm", children: "Loading available dates..." })
14635
+ /* @__PURE__ */ jsx5("div", { className: "ab-skeleton" }),
14636
+ /* @__PURE__ */ jsx5("p", { className: "ab-text ab-text--muted ab-text--sm", children: "Loading available dates..." })
14396
14637
  ] });
14397
14638
  }
14398
14639
  if (isEmpty) {
14399
14640
  return /* @__PURE__ */ jsxs4("div", { className: "ab-stack--sm", children: [
14400
14641
  /* @__PURE__ */ jsxs4("label", { className: "ab-label", children: [
14401
14642
  "Select Date",
14402
- required && /* @__PURE__ */ jsx6("span", { className: "ab-required", children: "*" })
14643
+ required && /* @__PURE__ */ jsx5("span", { className: "ab-required", children: "*" })
14403
14644
  ] }),
14404
- /* @__PURE__ */ jsx6(FeedbackMessage, { tone: "warning", className: "ab-alert ab-alert--warning", role: "status", children: /* @__PURE__ */ jsxs4("p", { className: "ab-text", children: [
14645
+ /* @__PURE__ */ jsx5(FeedbackMessage, { tone: "warning", className: "ab-alert ab-alert--warning", role: "status", children: /* @__PURE__ */ jsxs4("p", { className: "ab-text", children: [
14405
14646
  "No available dates in this period.",
14406
- hasMore && onLoadMore && /* @__PURE__ */ jsx6(
14647
+ hasMore && onLoadMore && /* @__PURE__ */ jsx5(
14407
14648
  "button",
14408
14649
  {
14409
14650
  type: "button",
@@ -14418,7 +14659,7 @@ var DatePicker = ({
14418
14659
  return /* @__PURE__ */ jsxs4("div", { className: "ab-stack--sm", children: [
14419
14660
  /* @__PURE__ */ jsxs4("label", { htmlFor: "booking-date", className: "ab-label", children: [
14420
14661
  "Select Date",
14421
- required && /* @__PURE__ */ jsx6("span", { className: "ab-required", children: "*" })
14662
+ required && /* @__PURE__ */ jsx5("span", { className: "ab-required", children: "*" })
14422
14663
  ] }),
14423
14664
  /* @__PURE__ */ jsxs4(
14424
14665
  "select",
@@ -14429,12 +14670,12 @@ var DatePicker = ({
14429
14670
  required,
14430
14671
  className: "ab-select",
14431
14672
  children: [
14432
- /* @__PURE__ */ jsx6("option", { value: "", children: "Choose a date..." }),
14433
- dateOptions.map((date) => /* @__PURE__ */ jsx6("option", { value: date, children: formatDate(date) }, date))
14673
+ /* @__PURE__ */ jsx5("option", { value: "", children: "Choose a date..." }),
14674
+ dateOptions.map((date) => /* @__PURE__ */ jsx5("option", { value: date, children: formatDate(date) }, date))
14434
14675
  ]
14435
14676
  }
14436
14677
  ),
14437
- hasMore && onLoadMore && /* @__PURE__ */ jsx6(
14678
+ hasMore && onLoadMore && /* @__PURE__ */ jsx5(
14438
14679
  "button",
14439
14680
  {
14440
14681
  type: "button",
@@ -14447,7 +14688,7 @@ var DatePicker = ({
14447
14688
  };
14448
14689
 
14449
14690
  // ../blocks/src/system/runtime/components/booking/TimeSlotSelector.tsx
14450
- import { jsx as jsx7, jsxs as jsxs5 } from "react/jsx-runtime";
14691
+ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
14451
14692
  var TimeSlotSelector = ({
14452
14693
  value,
14453
14694
  onChange,
@@ -14458,9 +14699,9 @@ var TimeSlotSelector = ({
14458
14699
  return /* @__PURE__ */ jsxs5("div", { className: "ab-stack--sm", children: [
14459
14700
  /* @__PURE__ */ jsxs5("label", { htmlFor: "booking-slot", className: "ab-label", children: [
14460
14701
  "Select Time",
14461
- required && /* @__PURE__ */ jsx7("span", { className: "ab-required", children: "*" })
14702
+ required && /* @__PURE__ */ jsx6("span", { className: "ab-required", children: "*" })
14462
14703
  ] }),
14463
- isLoading ? /* @__PURE__ */ jsx7(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info ab-center", role: "status", children: "Loading available times..." }) : slots.length === 0 ? /* @__PURE__ */ jsx7(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info ab-center", role: "status", children: "No available times for this date" }) : /* @__PURE__ */ jsxs5(
14704
+ isLoading ? /* @__PURE__ */ jsx6(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info ab-center", role: "status", children: "Loading available times..." }) : slots.length === 0 ? /* @__PURE__ */ jsx6(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info ab-center", role: "status", children: "No available times for this date" }) : /* @__PURE__ */ jsxs5(
14464
14705
  "select",
14465
14706
  {
14466
14707
  id: "booking-slot",
@@ -14469,8 +14710,8 @@ var TimeSlotSelector = ({
14469
14710
  required,
14470
14711
  className: "ab-select",
14471
14712
  children: [
14472
- /* @__PURE__ */ jsx7("option", { value: "", children: "Choose a time..." }),
14473
- slots.map((slot) => /* @__PURE__ */ jsx7("option", { value: slot.startAt, children: formatTime(slot.startAt) }, slot.startAt))
14713
+ /* @__PURE__ */ jsx6("option", { value: "", children: "Choose a time..." }),
14714
+ slots.map((slot) => /* @__PURE__ */ jsx6("option", { value: slot.startAt, children: formatTime(slot.startAt) }, slot.startAt))
14474
14715
  ]
14475
14716
  }
14476
14717
  )
@@ -14479,7 +14720,7 @@ var TimeSlotSelector = ({
14479
14720
 
14480
14721
  // ../blocks/src/system/runtime/shared/components/DiscountCodeDisclosure.tsx
14481
14722
  import { useId } from "react";
14482
- import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
14723
+ import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
14483
14724
  var BLOCK_DISCOUNT_CODE_DISCLOSURE_CLASSES = {
14484
14725
  "course-registration": {
14485
14726
  root: "cr-discount",
@@ -14555,10 +14796,10 @@ function DiscountCodeDisclosure({
14555
14796
  onApply();
14556
14797
  };
14557
14798
  const feedbackClassName = feedback ? `${classes.feedback} status-${feedback.tone}` : classes.feedback;
14558
- return /* @__PURE__ */ jsx8("div", { className: classes.root, children: !isOpen ? /* @__PURE__ */ jsx8("button", { type: "button", className: classes.toggle, onClick: onOpen, children: toggleLabel }) : /* @__PURE__ */ jsxs6("div", { className: classes.form, children: [
14559
- /* @__PURE__ */ jsx8("label", { htmlFor: inputId, className: classes.label, children: label }),
14799
+ return /* @__PURE__ */ jsx7("div", { className: classes.root, children: !isOpen ? /* @__PURE__ */ jsx7("button", { type: "button", className: classes.toggle, onClick: onOpen, children: toggleLabel }) : /* @__PURE__ */ jsxs6("div", { className: classes.form, children: [
14800
+ /* @__PURE__ */ jsx7("label", { htmlFor: inputId, className: classes.label, children: label }),
14560
14801
  /* @__PURE__ */ jsxs6("div", { className: classes.row, children: [
14561
- /* @__PURE__ */ jsx8(
14802
+ /* @__PURE__ */ jsx7(
14562
14803
  "input",
14563
14804
  {
14564
14805
  id: inputId,
@@ -14571,7 +14812,7 @@ function DiscountCodeDisclosure({
14571
14812
  disabled: disabled || isApplying
14572
14813
  }
14573
14814
  ),
14574
- onApply ? /* @__PURE__ */ jsx8(
14815
+ onApply ? /* @__PURE__ */ jsx7(
14575
14816
  "button",
14576
14817
  {
14577
14818
  type: "button",
@@ -14581,7 +14822,7 @@ function DiscountCodeDisclosure({
14581
14822
  children: isApplying ? "Applying..." : applyLabel
14582
14823
  }
14583
14824
  ) : null,
14584
- /* @__PURE__ */ jsx8(
14825
+ /* @__PURE__ */ jsx7(
14585
14826
  "button",
14586
14827
  {
14587
14828
  type: "button",
@@ -14592,8 +14833,8 @@ function DiscountCodeDisclosure({
14592
14833
  }
14593
14834
  )
14594
14835
  ] }),
14595
- /* @__PURE__ */ jsx8("p", { className: classes.hint, children: hint }),
14596
- feedback ? /* @__PURE__ */ jsx8(
14836
+ /* @__PURE__ */ jsx7("p", { className: classes.hint, children: hint }),
14837
+ feedback ? /* @__PURE__ */ jsx7(
14597
14838
  "p",
14598
14839
  {
14599
14840
  className: feedbackClassName,
@@ -14605,7 +14846,7 @@ function DiscountCodeDisclosure({
14605
14846
  }
14606
14847
 
14607
14848
  // ../blocks/src/system/runtime/shared/components/FieldValidationMessage.tsx
14608
- import { jsx as jsx9 } from "react/jsx-runtime";
14849
+ import { jsx as jsx8 } from "react/jsx-runtime";
14609
14850
  function getFieldValidationControlProps({
14610
14851
  message,
14611
14852
  messageId,
@@ -14624,7 +14865,7 @@ function FieldValidationMessage({
14624
14865
  className,
14625
14866
  live = "assertive"
14626
14867
  }) {
14627
- return /* @__PURE__ */ jsx9(
14868
+ return /* @__PURE__ */ jsx8(
14628
14869
  "p",
14629
14870
  {
14630
14871
  id,
@@ -14639,7 +14880,7 @@ function FieldValidationMessage({
14639
14880
  }
14640
14881
 
14641
14882
  // ../blocks/src/system/runtime/nodes/booking-form.default-ui.tsx
14642
- import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
14883
+ import { Fragment as Fragment2, jsx as jsx9, jsxs as jsxs7 } from "react/jsx-runtime";
14643
14884
  var paymentOptionLayoutStyle = {
14644
14885
  alignItems: "flex-start",
14645
14886
  display: "flex",
@@ -14668,20 +14909,20 @@ function HeadlessBookingDefaultForm({
14668
14909
  }
14669
14910
  };
14670
14911
  if (!currentStep) {
14671
- return /* @__PURE__ */ jsx10("div", { className: "rb-text-center rb-py-12", children: /* @__PURE__ */ jsx10("p", { className: "status-muted", children: "No steps available" }) });
14912
+ return /* @__PURE__ */ jsx9("div", { className: "rb-text-center rb-py-12", children: /* @__PURE__ */ jsx9("p", { className: "status-muted", children: "No steps available" }) });
14672
14913
  }
14673
14914
  return /* @__PURE__ */ jsxs7("div", { className: "multi-step-form", children: [
14674
- /* @__PURE__ */ jsx10("div", { className: "rb-mb-8", children: /* @__PURE__ */ jsx10(
14915
+ /* @__PURE__ */ jsx9("div", { className: "rb-mb-8", children: /* @__PURE__ */ jsx9(
14675
14916
  DefaultBookingProgress,
14676
14917
  {
14677
14918
  steps: booking.steps,
14678
14919
  currentIndex: currentStepIndex
14679
14920
  }
14680
14921
  ) }),
14681
- /* @__PURE__ */ jsx10("div", { className: "step-content", children: /* @__PURE__ */ jsx10(DefaultBookingStepContent, { booking }) }),
14682
- /* @__PURE__ */ jsx10(DefaultBookingErrorSummary, { errors: currentStep.errors }),
14922
+ /* @__PURE__ */ jsx9("div", { className: "step-content", children: /* @__PURE__ */ jsx9(DefaultBookingStepContent, { booking }) }),
14923
+ /* @__PURE__ */ jsx9(DefaultBookingErrorSummary, { errors: currentStep.errors }),
14683
14924
  /* @__PURE__ */ jsxs7("div", { className: "rb-flex rb-gap-3 rb-mt-8", children: [
14684
- !isFirstStep ? /* @__PURE__ */ jsx10(
14925
+ !isFirstStep ? /* @__PURE__ */ jsx9(
14685
14926
  "button",
14686
14927
  {
14687
14928
  type: "button",
@@ -14690,7 +14931,7 @@ function HeadlessBookingDefaultForm({
14690
14931
  children: "Back"
14691
14932
  }
14692
14933
  ) : null,
14693
- /* @__PURE__ */ jsx10(
14934
+ /* @__PURE__ */ jsx9(
14694
14935
  "button",
14695
14936
  {
14696
14937
  type: "button",
@@ -14704,7 +14945,7 @@ function HeadlessBookingDefaultForm({
14704
14945
  extraClassName: "rb-flex-1"
14705
14946
  }),
14706
14947
  children: isSubmitting ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
14707
- /* @__PURE__ */ jsx10(
14948
+ /* @__PURE__ */ jsx9(
14708
14949
  SpinnerNode,
14709
14950
  {
14710
14951
  size: "sm",
@@ -14718,22 +14959,22 @@ function HeadlessBookingDefaultForm({
14718
14959
  }
14719
14960
  )
14720
14961
  ] }),
14721
- /* @__PURE__ */ jsx10(DefaultBookingDiscount, { booking }),
14722
- /* @__PURE__ */ jsx10(DefaultBookingFeedback, { booking }),
14723
- /* @__PURE__ */ jsx10(DefaultBookingAltcha, { booking })
14962
+ /* @__PURE__ */ jsx9(DefaultBookingDiscount, { booking }),
14963
+ /* @__PURE__ */ jsx9(DefaultBookingFeedback, { booking }),
14964
+ /* @__PURE__ */ jsx9(DefaultBookingAltcha, { booking })
14724
14965
  ] });
14725
14966
  }
14726
14967
  function DefaultBookingProgress({
14727
14968
  steps,
14728
14969
  currentIndex
14729
14970
  }) {
14730
- return /* @__PURE__ */ jsx10("div", { className: "rb-flex rb-items-center rb-justify-between", children: steps.map((step, index) => {
14971
+ return /* @__PURE__ */ jsx9("div", { className: "rb-flex rb-items-center rb-justify-between", children: steps.map((step, index) => {
14731
14972
  const isActive = index === currentIndex;
14732
14973
  const isCompleted = index < currentIndex;
14733
14974
  const isLast = index === steps.length - 1;
14734
14975
  return /* @__PURE__ */ jsxs7("div", { className: "rb-flex rb-items-center rb-flex-1", children: [
14735
14976
  /* @__PURE__ */ jsxs7("div", { className: "rb-flex rb-items-center rb-gap-2 rb-cursor-default", children: [
14736
- /* @__PURE__ */ jsx10(
14977
+ /* @__PURE__ */ jsx9(
14737
14978
  "div",
14738
14979
  {
14739
14980
  className: `
@@ -14744,7 +14985,7 @@ function DefaultBookingProgress({
14744
14985
  children: isCompleted ? "\u2713" : index + 1
14745
14986
  }
14746
14987
  ),
14747
- /* @__PURE__ */ jsx10(
14988
+ /* @__PURE__ */ jsx9(
14748
14989
  "span",
14749
14990
  {
14750
14991
  className: `
@@ -14755,7 +14996,7 @@ function DefaultBookingProgress({
14755
14996
  }
14756
14997
  )
14757
14998
  ] }),
14758
- !isLast ? /* @__PURE__ */ jsx10("div", { className: "step-connector rb-ml-2 rb-mr-2 rb-hidden rb-sm-block" }) : null
14999
+ !isLast ? /* @__PURE__ */ jsx9("div", { className: "step-connector rb-ml-2 rb-mr-2 rb-hidden rb-sm-block" }) : null
14759
15000
  ] }, step.id);
14760
15001
  }) });
14761
15002
  }
@@ -14766,15 +15007,15 @@ function DefaultBookingStepContent({
14766
15007
  if (!stepId) return null;
14767
15008
  switch (stepId) {
14768
15009
  case "service-selection":
14769
- return /* @__PURE__ */ jsx10(DefaultServiceSelectionStep, { booking });
15010
+ return /* @__PURE__ */ jsx9(DefaultServiceSelectionStep, { booking });
14770
15011
  case "datetime-selection":
14771
- return /* @__PURE__ */ jsx10(DefaultDateTimeSelectionStep, { booking });
15012
+ return /* @__PURE__ */ jsx9(DefaultDateTimeSelectionStep, { booking });
14772
15013
  case "payment-selection":
14773
- return /* @__PURE__ */ jsx10(HeadlessBookingPaymentSelectionStep, { booking });
15014
+ return /* @__PURE__ */ jsx9(HeadlessBookingPaymentSelectionStep, { booking });
14774
15015
  case "custom-fields":
14775
- return /* @__PURE__ */ jsx10(DefaultDynamicFields, { fields: booking.fields.items, booking });
15016
+ return /* @__PURE__ */ jsx9(DefaultDynamicFields, { fields: booking.fields.items, booking });
14776
15017
  default:
14777
- return assertNever11(stepId);
15018
+ return assertNever4(stepId);
14778
15019
  }
14779
15020
  }
14780
15021
  function DefaultServiceSelectionStep({
@@ -14789,14 +15030,14 @@ function DefaultServiceSelectionStep({
14789
15030
  const allowAnyResource = !booking.resources.requiresSelection;
14790
15031
  return /* @__PURE__ */ jsxs7("div", { className: "ab-stack", children: [
14791
15032
  /* @__PURE__ */ jsxs7("div", { children: [
14792
- /* @__PURE__ */ jsx10("h2", { className: "ab-title", children: "Select Service" }),
14793
- /* @__PURE__ */ jsx10("p", { className: "ab-text ab-text--muted", children: "Choose the service you'd like to book" })
15033
+ /* @__PURE__ */ jsx9("h2", { className: "ab-title", children: "Select Service" }),
15034
+ /* @__PURE__ */ jsx9("p", { className: "ab-text ab-text--muted", children: "Choose the service you'd like to book" })
14794
15035
  ] }),
14795
15036
  showServiceSelect ? /* @__PURE__ */ jsxs7("div", { className: "ab-stack--sm", children: [
14796
- /* @__PURE__ */ jsx10("label", { className: "ab-subtitle", children: "Service" }),
14797
- /* @__PURE__ */ jsx10("div", { className: "ab-grid", children: services.map((service) => {
15037
+ /* @__PURE__ */ jsx9("label", { className: "ab-subtitle", children: "Service" }),
15038
+ /* @__PURE__ */ jsx9("div", { className: "ab-grid", children: services.map((service) => {
14798
15039
  const isSelected = selectedServiceId === service.id;
14799
- return /* @__PURE__ */ jsx10(
15040
+ return /* @__PURE__ */ jsx9(
14800
15041
  "button",
14801
15042
  {
14802
15043
  type: "button",
@@ -14804,14 +15045,14 @@ function DefaultServiceSelectionStep({
14804
15045
  className: `ab-card ${isSelected ? "ab-card--selected" : ""}`,
14805
15046
  children: /* @__PURE__ */ jsxs7("div", { className: "ab-row--between", children: [
14806
15047
  /* @__PURE__ */ jsxs7("div", { children: [
14807
- /* @__PURE__ */ jsx10("div", { className: "ab-subtitle", children: service.title }),
14808
- service.description ? /* @__PURE__ */ jsx10("div", { className: "ab-text ab-text--muted", children: service.description }) : null,
15048
+ /* @__PURE__ */ jsx9("div", { className: "ab-subtitle", children: service.title }),
15049
+ service.description ? /* @__PURE__ */ jsx9("div", { className: "ab-text ab-text--muted", children: service.description }) : null,
14809
15050
  service.durationMinutes ? /* @__PURE__ */ jsxs7("div", { className: "ab-text ab-text--muted", children: [
14810
15051
  service.durationMinutes,
14811
15052
  " minutes"
14812
15053
  ] }) : null
14813
15054
  ] }),
14814
- isSelected ? /* @__PURE__ */ jsx10(SelectedCheck, {}) : null
15055
+ isSelected ? /* @__PURE__ */ jsx9(SelectedCheck, {}) : null
14815
15056
  ] })
14816
15057
  },
14817
15058
  service.id
@@ -14819,41 +15060,41 @@ function DefaultServiceSelectionStep({
14819
15060
  }) })
14820
15061
  ] }) : null,
14821
15062
  booking.resources.state.tag === "loading" ? /* @__PURE__ */ jsxs7("div", { className: "ab-center", children: [
14822
- /* @__PURE__ */ jsx10(SpinnerNode, { size: "md", srLabel: "Loading practitioners" }),
14823
- /* @__PURE__ */ jsx10("p", { className: "ab-text ab-text--muted", children: "Loading practitioners..." })
15063
+ /* @__PURE__ */ jsx9(SpinnerNode, { size: "md", srLabel: "Loading practitioners" }),
15064
+ /* @__PURE__ */ jsx9("p", { className: "ab-text ab-text--muted", children: "Loading practitioners..." })
14824
15065
  ] }) : null,
14825
- booking.resources.state.tag === "error" ? /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: booking.resources.state.message }) : null,
14826
- showResourceSelect && booking.resources.state.tag === "loaded" && resources.length === 0 ? /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: "No practitioners are available for this service right now." }) : null,
15066
+ booking.resources.state.tag === "error" ? /* @__PURE__ */ jsx9(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: booking.resources.state.message }) : null,
15067
+ showResourceSelect && booking.resources.state.tag === "loaded" && resources.length === 0 ? /* @__PURE__ */ jsx9(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: "No practitioners are available for this service right now." }) : null,
14827
15068
  showResourceSelect && booking.resources.state.tag !== "loading" && (allowAnyResource || resources.length > 0) ? /* @__PURE__ */ jsxs7("div", { className: "ab-stack--sm", children: [
14828
15069
  /* @__PURE__ */ jsxs7("label", { className: "ab-subtitle", children: [
14829
15070
  "Practitioner",
14830
15071
  booking.resources.requiresSelection ? "" : " (Optional)"
14831
15072
  ] }),
14832
- /* @__PURE__ */ jsx10("p", { className: "ab-text ab-text--muted", children: allowAnyResource ? 'Choose a specific practitioner or select "Any Available"' : "Choose the practitioner you'd like to book" }),
15073
+ /* @__PURE__ */ jsx9("p", { className: "ab-text ab-text--muted", children: allowAnyResource ? 'Choose a specific practitioner or select "Any Available"' : "Choose the practitioner you'd like to book" }),
14833
15074
  /* @__PURE__ */ jsxs7("div", { className: "ab-grid", children: [
14834
- allowAnyResource ? /* @__PURE__ */ jsx10(
15075
+ allowAnyResource ? /* @__PURE__ */ jsx9(
14835
15076
  "button",
14836
15077
  {
14837
15078
  type: "button",
14838
15079
  onClick: () => booking.actions.selectResource(null),
14839
15080
  className: `ab-card ${!selectedResourceId ? "ab-card--selected" : ""}`,
14840
15081
  children: /* @__PURE__ */ jsxs7("div", { className: "ab-row--between", children: [
14841
- /* @__PURE__ */ jsx10("div", { className: "ab-subtitle", children: "Any Available" }),
14842
- !selectedResourceId ? /* @__PURE__ */ jsx10(SelectedCheck, {}) : null
15082
+ /* @__PURE__ */ jsx9("div", { className: "ab-subtitle", children: "Any Available" }),
15083
+ !selectedResourceId ? /* @__PURE__ */ jsx9(SelectedCheck, {}) : null
14843
15084
  ] })
14844
15085
  }
14845
15086
  ) : null,
14846
15087
  resources.map((resource) => {
14847
15088
  const isSelected = selectedResourceId === resource.id;
14848
- return /* @__PURE__ */ jsx10(
15089
+ return /* @__PURE__ */ jsx9(
14849
15090
  "button",
14850
15091
  {
14851
15092
  type: "button",
14852
15093
  onClick: () => booking.actions.selectResource(resource.id),
14853
15094
  className: `ab-card ${isSelected ? "ab-card--selected" : ""}`,
14854
15095
  children: /* @__PURE__ */ jsxs7("div", { className: "ab-row--between", children: [
14855
- /* @__PURE__ */ jsx10("div", { className: "ab-subtitle", children: resource.label }),
14856
- isSelected ? /* @__PURE__ */ jsx10(SelectedCheck, {}) : null
15096
+ /* @__PURE__ */ jsx9("div", { className: "ab-subtitle", children: resource.label }),
15097
+ isSelected ? /* @__PURE__ */ jsx9(SelectedCheck, {}) : null
14857
15098
  ] })
14858
15099
  },
14859
15100
  resource.id
@@ -14876,16 +15117,16 @@ function DefaultDateTimeSelectionStep({
14876
15117
  const error = booking.availability.datesState.tag === "error" ? booking.availability.datesState.message : booking.availability.slotsState.tag === "error" ? booking.availability.slotsState.message : null;
14877
15118
  return /* @__PURE__ */ jsxs7("div", { className: "ab-stack", children: [
14878
15119
  singleService ? /* @__PURE__ */ jsxs7("div", { className: "ab-info-box", children: [
14879
- /* @__PURE__ */ jsx10("h3", { className: "ab-subtitle", children: singleService.title }),
14880
- singleService.description ? /* @__PURE__ */ jsx10("p", { className: "ab-text ab-text--muted", children: singleService.description }) : null,
15120
+ /* @__PURE__ */ jsx9("h3", { className: "ab-subtitle", children: singleService.title }),
15121
+ singleService.description ? /* @__PURE__ */ jsx9("p", { className: "ab-text ab-text--muted", children: singleService.description }) : null,
14881
15122
  singleService.durationMinutes ? /* @__PURE__ */ jsxs7("p", { className: "ab-text ab-text--muted", children: [
14882
15123
  "Duration: ",
14883
15124
  singleService.durationMinutes,
14884
15125
  " minutes"
14885
15126
  ] }) : null
14886
15127
  ] }) : null,
14887
- error ? /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: error }) : null,
14888
- /* @__PURE__ */ jsx10(
15128
+ error ? /* @__PURE__ */ jsx9(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: error }) : null,
15129
+ /* @__PURE__ */ jsx9(
14889
15130
  DatePicker,
14890
15131
  {
14891
15132
  value: selectedDate,
@@ -14897,7 +15138,7 @@ function DefaultDateTimeSelectionStep({
14897
15138
  onLoadMore: booking.availability.loadMoreDates
14898
15139
  }
14899
15140
  ),
14900
- selectedDate ? /* @__PURE__ */ jsx10(
15141
+ selectedDate ? /* @__PURE__ */ jsx9(
14901
15142
  TimeSlotSelector,
14902
15143
  {
14903
15144
  value: selectedSlotStart,
@@ -14920,19 +15161,19 @@ function HeadlessBookingPaymentSelectionStep({
14920
15161
  const service = booking.services.selected;
14921
15162
  const viewModel = booking.payment.selection;
14922
15163
  if (booking.payment.kind === "unsupported") {
14923
- return /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: booking.payment.errorMessage });
15164
+ return /* @__PURE__ */ jsx9(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: booking.payment.errorMessage });
14924
15165
  }
14925
15166
  if (!service || !viewModel) {
14926
- return /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: "Payment options are unavailable for this service right now." });
15167
+ return /* @__PURE__ */ jsx9(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: "Payment options are unavailable for this service right now." });
14927
15168
  }
14928
15169
  const packageOptions = booking.payment.appointmentPackages.items;
14929
15170
  const hasPackageOptions = packageOptions.length > 0;
14930
15171
  return /* @__PURE__ */ jsxs7("div", { className: "ab-stack", children: [
14931
15172
  /* @__PURE__ */ jsxs7("div", { className: "ab-info-box", children: [
14932
- /* @__PURE__ */ jsx10("h3", { className: "ab-subtitle", children: viewModel.sectionTitle }),
14933
- /* @__PURE__ */ jsx10("p", { className: "ab-text ab-text--muted", children: service.title })
15173
+ /* @__PURE__ */ jsx9("h3", { className: "ab-subtitle", children: viewModel.sectionTitle }),
15174
+ /* @__PURE__ */ jsx9("p", { className: "ab-text ab-text--muted", children: service.title })
14934
15175
  ] }),
14935
- booking.payment.appointmentPackages.state.tag === "loading" ? /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info", role: "status", children: "Checking package credits..." }) : null,
15176
+ booking.payment.appointmentPackages.state.tag === "loading" ? /* @__PURE__ */ jsx9(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info", role: "status", children: "Checking package credits..." }) : null,
14936
15177
  booking.payment.appointmentPackages.state.tag === "error" ? /* @__PURE__ */ jsxs7(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info", role: "status", children: [
14937
15178
  booking.payment.appointmentPackages.state.message,
14938
15179
  " You can continue with the normal payment option."
@@ -14940,7 +15181,7 @@ function HeadlessBookingPaymentSelectionStep({
14940
15181
  /* @__PURE__ */ jsxs7("div", { className: "ab-stack", role: "list", "aria-label": "Payment options", children: [
14941
15182
  packageOptions.map((appointmentPackage) => {
14942
15183
  const isSelected = booking.payment.selectedAppointmentPackageId === appointmentPackage.customerPassId;
14943
- return /* @__PURE__ */ jsx10(
15184
+ return /* @__PURE__ */ jsx9(
14944
15185
  "button",
14945
15186
  {
14946
15187
  type: "button",
@@ -14953,7 +15194,7 @@ function HeadlessBookingPaymentSelectionStep({
14953
15194
  appointmentPackage.customerPassId
14954
15195
  ),
14955
15196
  "aria-pressed": isSelected,
14956
- children: /* @__PURE__ */ jsx10(
15197
+ children: /* @__PURE__ */ jsx9(
14957
15198
  PaymentOptionContent,
14958
15199
  {
14959
15200
  id: appointmentPackage.customerPassId,
@@ -14972,12 +15213,12 @@ function HeadlessBookingPaymentSelectionStep({
14972
15213
  viewModel.options.map((option) => {
14973
15214
  const isSelected = !booking.payment.selectedAppointmentPackageId && (booking.payment.selectedCollectionOptionKind === option.kind || viewModel.mode === "single_option");
14974
15215
  if (viewModel.mode === "single_option" && !hasPackageOptions) {
14975
- return /* @__PURE__ */ jsx10(
15216
+ return /* @__PURE__ */ jsx9(
14976
15217
  "div",
14977
15218
  {
14978
15219
  className: "ab-card",
14979
15220
  style: paymentOptionLayoutStyle,
14980
- children: /* @__PURE__ */ jsx10(
15221
+ children: /* @__PURE__ */ jsx9(
14981
15222
  PaymentOptionContent,
14982
15223
  {
14983
15224
  id: option.kind,
@@ -14991,7 +15232,7 @@ function HeadlessBookingPaymentSelectionStep({
14991
15232
  option.kind
14992
15233
  );
14993
15234
  }
14994
- return /* @__PURE__ */ jsx10(
15235
+ return /* @__PURE__ */ jsx9(
14995
15236
  "button",
14996
15237
  {
14997
15238
  type: "button",
@@ -15002,7 +15243,7 @@ function HeadlessBookingPaymentSelectionStep({
15002
15243
  style: paymentOptionLayoutStyle,
15003
15244
  onClick: () => booking.actions.selectPaymentOption(option.kind),
15004
15245
  "aria-pressed": isSelected,
15005
- children: /* @__PURE__ */ jsx10(
15246
+ children: /* @__PURE__ */ jsx9(
15006
15247
  PaymentOptionContent,
15007
15248
  {
15008
15249
  id: option.kind,
@@ -15027,21 +15268,21 @@ function PaymentOptionContent({
15027
15268
  title
15028
15269
  }) {
15029
15270
  return /* @__PURE__ */ jsxs7(Fragment2, { children: [
15030
- /* @__PURE__ */ jsx10("span", { children: title }),
15031
- /* @__PURE__ */ jsx10("span", { className: "ab-text ab-text--muted", children: description }),
15032
- /* @__PURE__ */ jsx10("div", { className: "ab-stack", style: summaryStackStyle, children: summaryRows.map((row) => /* @__PURE__ */ jsxs7("span", { className: "ab-text ab-text--muted", children: [
15271
+ /* @__PURE__ */ jsx9("span", { children: title }),
15272
+ /* @__PURE__ */ jsx9("span", { className: "ab-text ab-text--muted", children: description }),
15273
+ /* @__PURE__ */ jsx9("div", { className: "ab-stack", style: summaryStackStyle, children: summaryRows.map((row) => /* @__PURE__ */ jsxs7("span", { className: "ab-text ab-text--muted", children: [
15033
15274
  row.label,
15034
15275
  ": ",
15035
15276
  row.value
15036
15277
  ] }, `${id}-${row.label}`)) }),
15037
- helperText ? /* @__PURE__ */ jsx10("span", { className: "ab-text ab-text--muted", children: helperText }) : null
15278
+ helperText ? /* @__PURE__ */ jsx9("span", { className: "ab-text ab-text--muted", children: helperText }) : null
15038
15279
  ] });
15039
15280
  }
15040
15281
  function DefaultDynamicFields({
15041
15282
  booking,
15042
15283
  fields
15043
15284
  }) {
15044
- return /* @__PURE__ */ jsx10("div", { className: "rb-space-y-6", children: fields.map((field) => /* @__PURE__ */ jsx10(DefaultDynamicField, { booking, field }, field.id)) });
15285
+ return /* @__PURE__ */ jsx9("div", { className: "rb-space-y-6", children: fields.map((field) => /* @__PURE__ */ jsx9(DefaultDynamicField, { booking, field }, field.id)) });
15045
15286
  }
15046
15287
  function DefaultDynamicField({
15047
15288
  booking,
@@ -15054,10 +15295,10 @@ function DefaultDynamicField({
15054
15295
  return /* @__PURE__ */ jsxs7("div", { className: "rb-space-y-2", children: [
15055
15296
  /* @__PURE__ */ jsxs7("label", { id: field.labelId, htmlFor: field.inputId, className: "form-label", children: [
15056
15297
  field.label,
15057
- field.required ? /* @__PURE__ */ jsx10("span", { className: "required-marker", children: "*" }) : null
15298
+ field.required ? /* @__PURE__ */ jsx9("span", { className: "required-marker", children: "*" }) : null
15058
15299
  ] }),
15059
- field.helpText ? /* @__PURE__ */ jsx10("p", { id: field.helpTextId ?? void 0, className: "rb-caption status-muted", children: field.helpText }) : null,
15060
- /* @__PURE__ */ jsx10(
15300
+ field.helpText ? /* @__PURE__ */ jsx9("p", { id: field.helpTextId ?? void 0, className: "rb-caption status-muted", children: field.helpText }) : null,
15301
+ /* @__PURE__ */ jsx9(
15061
15302
  DefaultFieldInput,
15062
15303
  {
15063
15304
  field,
@@ -15069,7 +15310,7 @@ function DefaultDynamicField({
15069
15310
  describedBy
15070
15311
  }
15071
15312
  ),
15072
- error ? /* @__PURE__ */ jsx10(
15313
+ error ? /* @__PURE__ */ jsx9(
15073
15314
  FieldValidationMessage,
15074
15315
  {
15075
15316
  id: errorId ?? `${field.inputId}-error`,
@@ -15103,7 +15344,7 @@ function DefaultFieldInput({
15103
15344
  };
15104
15345
  switch (field.type) {
15105
15346
  case "textarea":
15106
- return /* @__PURE__ */ jsx10(
15347
+ return /* @__PURE__ */ jsx9(
15107
15348
  "textarea",
15108
15349
  {
15109
15350
  ...commonProps,
@@ -15118,7 +15359,7 @@ function DefaultFieldInput({
15118
15359
  );
15119
15360
  case "select":
15120
15361
  if (field.field.multiple) {
15121
- return /* @__PURE__ */ jsx10(
15362
+ return /* @__PURE__ */ jsx9(
15122
15363
  "select",
15123
15364
  {
15124
15365
  ...commonProps,
@@ -15131,7 +15372,7 @@ function DefaultFieldInput({
15131
15372
  },
15132
15373
  multiple: true,
15133
15374
  className: "form-select rb-h-32",
15134
- children: field.field.options?.map((option) => /* @__PURE__ */ jsx10("option", { value: option.value, children: option.label }, option.value))
15375
+ children: field.field.options?.map((option) => /* @__PURE__ */ jsx9("option", { value: option.value, children: option.label }, option.value))
15135
15376
  }
15136
15377
  );
15137
15378
  }
@@ -15143,14 +15384,14 @@ function DefaultFieldInput({
15143
15384
  onChange: (event) => onChange(event.target.value),
15144
15385
  className: "form-select",
15145
15386
  children: [
15146
- /* @__PURE__ */ jsx10("option", { value: "", children: "Select an option..." }),
15147
- field.field.options?.map((option) => /* @__PURE__ */ jsx10("option", { value: option.value, children: option.label }, option.value))
15387
+ /* @__PURE__ */ jsx9("option", { value: "", children: "Select an option..." }),
15388
+ field.field.options?.map((option) => /* @__PURE__ */ jsx9("option", { value: option.value, children: option.label }, option.value))
15148
15389
  ]
15149
15390
  }
15150
15391
  );
15151
15392
  case "radio":
15152
- return /* @__PURE__ */ jsx10("div", { className: "rb-space-y-2", children: field.field.options?.map((option) => /* @__PURE__ */ jsxs7("label", { className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer", children: [
15153
- /* @__PURE__ */ jsx10(
15393
+ return /* @__PURE__ */ jsx9("div", { className: "rb-space-y-2", children: field.field.options?.map((option) => /* @__PURE__ */ jsxs7("label", { className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer", children: [
15394
+ /* @__PURE__ */ jsx9(
15154
15395
  "input",
15155
15396
  {
15156
15397
  type: "radio",
@@ -15164,13 +15405,13 @@ function DefaultFieldInput({
15164
15405
  className: "form-radio"
15165
15406
  }
15166
15407
  ),
15167
- /* @__PURE__ */ jsx10("span", { className: "rb-caption", children: option.label })
15408
+ /* @__PURE__ */ jsx9("span", { className: "rb-caption", children: option.label })
15168
15409
  ] }, option.value)) });
15169
15410
  case "checkbox":
15170
15411
  if (field.field.options && field.field.options.length > 1) {
15171
15412
  const checkedValues = toStringArray(value);
15172
- return /* @__PURE__ */ jsx10("div", { className: "rb-space-y-2", children: field.field.options.map((option) => /* @__PURE__ */ jsxs7("label", { className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer", children: [
15173
- /* @__PURE__ */ jsx10(
15413
+ return /* @__PURE__ */ jsx9("div", { className: "rb-space-y-2", children: field.field.options.map((option) => /* @__PURE__ */ jsxs7("label", { className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer", children: [
15414
+ /* @__PURE__ */ jsx9(
15174
15415
  "input",
15175
15416
  {
15176
15417
  type: "checkbox",
@@ -15187,11 +15428,11 @@ function DefaultFieldInput({
15187
15428
  className: "form-checkbox"
15188
15429
  }
15189
15430
  ),
15190
- /* @__PURE__ */ jsx10("span", { className: "rb-caption", children: option.label })
15431
+ /* @__PURE__ */ jsx9("span", { className: "rb-caption", children: option.label })
15191
15432
  ] }, option.value)) });
15192
15433
  }
15193
15434
  return /* @__PURE__ */ jsxs7("label", { className: "rb-flex rb-items-center rb-gap-2 rb-cursor-pointer", children: [
15194
- /* @__PURE__ */ jsx10(
15435
+ /* @__PURE__ */ jsx9(
15195
15436
  "input",
15196
15437
  {
15197
15438
  type: "checkbox",
@@ -15205,11 +15446,11 @@ function DefaultFieldInput({
15205
15446
  className: "form-checkbox"
15206
15447
  }
15207
15448
  ),
15208
- /* @__PURE__ */ jsx10("span", { className: "rb-caption", children: field.field.placeholder || field.label })
15449
+ /* @__PURE__ */ jsx9("span", { className: "rb-caption", children: field.field.placeholder || field.label })
15209
15450
  ] });
15210
15451
  case "booking_requirement_consent":
15211
15452
  return /* @__PURE__ */ jsxs7("label", { className: "rb-flex rb-items-start rb-gap-2 rb-cursor-pointer", children: [
15212
- /* @__PURE__ */ jsx10(
15453
+ /* @__PURE__ */ jsx9(
15213
15454
  "input",
15214
15455
  {
15215
15456
  type: "checkbox",
@@ -15223,10 +15464,10 @@ function DefaultFieldInput({
15223
15464
  className: "form-checkbox rb-mt-0.5"
15224
15465
  }
15225
15466
  ),
15226
- /* @__PURE__ */ jsx10("span", { className: "rb-caption", children: field.field.placeholder || field.label })
15467
+ /* @__PURE__ */ jsx9("span", { className: "rb-caption", children: field.field.placeholder || field.label })
15227
15468
  ] });
15228
15469
  case "number":
15229
- return /* @__PURE__ */ jsx10(
15470
+ return /* @__PURE__ */ jsx9(
15230
15471
  "input",
15231
15472
  {
15232
15473
  ...commonProps,
@@ -15240,7 +15481,7 @@ function DefaultFieldInput({
15240
15481
  }
15241
15482
  );
15242
15483
  case "date":
15243
- return /* @__PURE__ */ jsx10(
15484
+ return /* @__PURE__ */ jsx9(
15244
15485
  "input",
15245
15486
  {
15246
15487
  ...commonProps,
@@ -15253,7 +15494,7 @@ function DefaultFieldInput({
15253
15494
  }
15254
15495
  );
15255
15496
  case "time":
15256
- return /* @__PURE__ */ jsx10(
15497
+ return /* @__PURE__ */ jsx9(
15257
15498
  "input",
15258
15499
  {
15259
15500
  ...commonProps,
@@ -15267,7 +15508,7 @@ function DefaultFieldInput({
15267
15508
  case "email":
15268
15509
  case "tel":
15269
15510
  case "url":
15270
- return /* @__PURE__ */ jsx10(
15511
+ return /* @__PURE__ */ jsx9(
15271
15512
  "input",
15272
15513
  {
15273
15514
  ...commonProps,
@@ -15292,7 +15533,7 @@ function DefaultBookingDiscount({
15292
15533
  const shouldShowDiscountSection = !booking.payment.selectedAppointmentPackageId && !booking.discount.loading && (booking.discount.manualCodeEntryAllowed || Boolean(booking.discount.autoAppliedDiscount));
15293
15534
  if (!shouldShowDiscountSection) return null;
15294
15535
  return /* @__PURE__ */ jsxs7("div", { className: "rb-mt-6", children: [
15295
- booking.discount.manualCodeEntryAllowed ? /* @__PURE__ */ jsx10(
15536
+ booking.discount.manualCodeEntryAllowed ? /* @__PURE__ */ jsx9(
15296
15537
  DiscountCodeDisclosure,
15297
15538
  {
15298
15539
  surface: "theme-form",
@@ -15306,7 +15547,7 @@ function DefaultBookingDiscount({
15306
15547
  }
15307
15548
  }
15308
15549
  ) : null,
15309
- booking.discount.autoAppliedDiscount && booking.discount.code.trim().length === 0 ? /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info rb-mt-4", role: "status", children: /* @__PURE__ */ jsxs7("p", { className: "ab-text", children: [
15550
+ booking.discount.autoAppliedDiscount && booking.discount.code.trim().length === 0 ? /* @__PURE__ */ jsx9(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info rb-mt-4", role: "status", children: /* @__PURE__ */ jsxs7("p", { className: "ab-text", children: [
15310
15551
  "Discount available: ",
15311
15552
  booking.discount.autoAppliedDiscount.publicLabel,
15312
15553
  " ",
@@ -15319,8 +15560,8 @@ function DefaultBookingFeedback({
15319
15560
  }) {
15320
15561
  if (booking.feedback.kind !== "error") return null;
15321
15562
  return /* @__PURE__ */ jsxs7(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: [
15322
- /* @__PURE__ */ jsx10("p", { className: "ab-text", children: booking.feedback.message }),
15323
- /* @__PURE__ */ jsx10(
15563
+ /* @__PURE__ */ jsx9("p", { className: "ab-text", children: booking.feedback.message }),
15564
+ /* @__PURE__ */ jsx9(
15324
15565
  "button",
15325
15566
  {
15326
15567
  type: "button",
@@ -15335,7 +15576,7 @@ function DefaultBookingAltcha({
15335
15576
  booking
15336
15577
  }) {
15337
15578
  if (!booking.spamProtection.enabled) return null;
15338
- return /* @__PURE__ */ jsx10("div", { className: "ab-altcha", children: /* @__PURE__ */ jsx10(
15579
+ return /* @__PURE__ */ jsx9("div", { className: "ab-altcha", children: /* @__PURE__ */ jsx9(
15339
15580
  AltchaWidget,
15340
15581
  {
15341
15582
  challengeUrl: booking.spamProtection.challenge.url,
@@ -15348,12 +15589,12 @@ function DefaultBookingErrorSummary({
15348
15589
  }) {
15349
15590
  if (!hasBookingValidationErrors(errors)) return null;
15350
15591
  return /* @__PURE__ */ jsxs7(FeedbackMessage, { tone: "error", className: "rb-mt-6 alert alert-error", role: "alert", children: [
15351
- errors.formError ? /* @__PURE__ */ jsx10("p", { className: "rb-caption", children: /* @__PURE__ */ jsx10("strong", { children: errors.formError }) }) : null,
15352
- Object.entries(errors.fieldErrors).map(([key, message]) => /* @__PURE__ */ jsx10("p", { className: "rb-caption", children: message }, key))
15592
+ errors.formError ? /* @__PURE__ */ jsx9("p", { className: "rb-caption", children: /* @__PURE__ */ jsx9("strong", { children: errors.formError }) }) : null,
15593
+ Object.entries(errors.fieldErrors).map(([key, message]) => /* @__PURE__ */ jsx9("p", { className: "rb-caption", children: message }, key))
15353
15594
  ] });
15354
15595
  }
15355
15596
  function SelectedCheck() {
15356
- return /* @__PURE__ */ jsx10("div", { className: "ab-check", children: /* @__PURE__ */ jsx10(
15597
+ return /* @__PURE__ */ jsx9("div", { className: "ab-check", children: /* @__PURE__ */ jsx9(
15357
15598
  "svg",
15358
15599
  {
15359
15600
  fill: "none",
@@ -15362,7 +15603,7 @@ function SelectedCheck() {
15362
15603
  strokeWidth: "2",
15363
15604
  viewBox: "0 0 24 24",
15364
15605
  stroke: "currentColor",
15365
- children: /* @__PURE__ */ jsx10("path", { d: "M5 13l4 4L19 7" })
15606
+ children: /* @__PURE__ */ jsx9("path", { d: "M5 13l4 4L19 7" })
15366
15607
  }
15367
15608
  ) });
15368
15609
  }
@@ -15429,7 +15670,7 @@ function consumeSearchParam(paramName) {
15429
15670
  }
15430
15671
 
15431
15672
  // ../blocks/src/system/runtime/nodes/booking-form.client.tsx
15432
- import { jsx as jsx11, jsxs as jsxs8 } from "react/jsx-runtime";
15673
+ import { jsx as jsx10, jsxs as jsxs8 } from "react/jsx-runtime";
15433
15674
  var PORTAL_REBOOK_QUERY_PARAM = "rebook";
15434
15675
  var PORTAL_REBOOK_QUERY_VALUE = "1";
15435
15676
  var REBOOK_COMPLETION_MODE_VERIFIED_CHECKOUT = "verified_checkout";
@@ -15466,8 +15707,8 @@ var BookingFormClient = ({
15466
15707
  const initialServiceId = render.hydration.serviceId ?? defaultServiceId ?? void 0;
15467
15708
  const initialResourceId = render.hydration.resourceId ?? void 0;
15468
15709
  const isPortalRebook = render.hydration.rebookContext?.kind === "portal_rebook";
15469
- const hasLoggedRebookCompletionRef = useRef7(false);
15470
- const [redirectState] = useState5(
15710
+ const hasLoggedRebookCompletionRef = useRef8(false);
15711
+ const [redirectState] = useState2(
15471
15712
  () => getBookingRedirectStateFromLocation(getBookingRedirectLocationSnapshot())
15472
15713
  );
15473
15714
  const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
@@ -15547,13 +15788,13 @@ var BookingFormClient = ({
15547
15788
  viewState.kind
15548
15789
  ]);
15549
15790
  if (render.display.state === "missing" || !form || !render.hydration.formId) {
15550
- return /* @__PURE__ */ jsx11(
15791
+ return /* @__PURE__ */ jsx10(
15551
15792
  FeedbackMessage,
15552
15793
  {
15553
15794
  tone: "error",
15554
15795
  className: `ab-alert ab-alert--error ${render.display.className ?? ""}`.trim(),
15555
15796
  role: "alert",
15556
- children: /* @__PURE__ */ jsx11("p", { className: "ab-text", children: render.display.message ?? "Booking form not found. Please check your configuration." })
15797
+ children: /* @__PURE__ */ jsx10("p", { className: "ab-text", children: render.display.message ?? "Booking form not found. Please check your configuration." })
15557
15798
  }
15558
15799
  );
15559
15800
  }
@@ -15573,7 +15814,7 @@ var BookingFormClient = ({
15573
15814
  }
15574
15815
  };
15575
15816
  if (viewState.kind === "success") {
15576
- return /* @__PURE__ */ jsx11(
15817
+ return /* @__PURE__ */ jsx10(
15577
15818
  SuccessMessage,
15578
15819
  {
15579
15820
  message: getBookingSuccessMessage(render.display.successMessage),
@@ -15583,19 +15824,19 @@ var BookingFormClient = ({
15583
15824
  );
15584
15825
  }
15585
15826
  if (viewState.kind === "verifying") {
15586
- return /* @__PURE__ */ jsx11(
15827
+ return /* @__PURE__ */ jsx10(
15587
15828
  "div",
15588
15829
  {
15589
15830
  id: bookingAnchorId,
15590
15831
  className: render.display.className ?? void 0,
15591
- children: /* @__PURE__ */ jsx11(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info", role: "status", children: /* @__PURE__ */ jsx11("p", { className: "ab-text", children: viewState.message }) })
15832
+ children: /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info", role: "status", children: /* @__PURE__ */ jsx10("p", { className: "ab-text", children: viewState.message }) })
15592
15833
  }
15593
15834
  );
15594
15835
  }
15595
15836
  return /* @__PURE__ */ jsxs8("div", { id: bookingAnchorId, className: render.display.className ?? void 0, children: [
15596
- render.hydration.noticeMessage ? /* @__PURE__ */ jsx11(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info rb-mb-4", role: "status", children: /* @__PURE__ */ jsx11("p", { className: "ab-text", children: render.hydration.noticeMessage }) }) : null,
15597
- viewState.kind === "error" ? /* @__PURE__ */ jsx11(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: /* @__PURE__ */ jsx11("p", { className: "ab-text", children: viewState.message }) }) : null,
15598
- /* @__PURE__ */ jsx11(HeadlessBookingDefaultForm, { booking, onSubmit: handleComplete })
15837
+ render.hydration.noticeMessage ? /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "info", className: "ab-alert ab-alert--info rb-mb-4", role: "status", children: /* @__PURE__ */ jsx10("p", { className: "ab-text", children: render.hydration.noticeMessage }) }) : null,
15838
+ viewState.kind === "error" ? /* @__PURE__ */ jsx10(FeedbackMessage, { tone: "error", className: "ab-alert ab-alert--error", role: "alert", children: /* @__PURE__ */ jsx10("p", { className: "ab-text", children: viewState.message }) }) : null,
15839
+ /* @__PURE__ */ jsx10(HeadlessBookingDefaultForm, { booking, onSubmit: handleComplete })
15599
15840
  ] });
15600
15841
  };
15601
15842
 
@@ -15612,12 +15853,18 @@ function createInitialRegistrationFlowState(hasPreSelectedContext) {
15612
15853
  };
15613
15854
  }
15614
15855
  function selectionEquals(a, b2) {
15615
- return a.method === b2.method && a.passId === b2.passId && a.membershipId === b2.membershipId && a.bundlePassId === b2.bundlePassId && a.bundleMembershipId === b2.bundleMembershipId && a.productName === b2.productName && a.productDescription === b2.productDescription && a.productPrice === b2.productPrice && a.productCurrency === b2.productCurrency && a.productInterval === b2.productInterval;
15856
+ return a.method === b2.method && a.passId === b2.passId && a.membershipId === b2.membershipId && a.bundlePassId === b2.bundlePassId && a.bundleMembershipId === b2.bundleMembershipId && a.productName === b2.productName && a.productDescription === b2.productDescription && a.productPrice === b2.productPrice && a.productCurrency === b2.productCurrency && a.productInterval === b2.productInterval && a.collectionOptionKind === b2.collectionOptionKind;
15616
15857
  }
15617
15858
  function withDefaultSelection(selection) {
15618
15859
  if (!selection || !selection.method) {
15619
15860
  return { method: null };
15620
15861
  }
15862
+ if (selection.method === "stripe") {
15863
+ return {
15864
+ ...selection,
15865
+ collectionOptionKind: selection.collectionOptionKind ?? "upfront"
15866
+ };
15867
+ }
15621
15868
  return selection;
15622
15869
  }
15623
15870
  function computeAutoSelection(input) {
@@ -15643,7 +15890,7 @@ function computeAutoSelection(input) {
15643
15890
  }
15644
15891
  }
15645
15892
  if (eligibility.canPayDirectly && eligibility.price) {
15646
- return { method: "stripe" };
15893
+ return { method: "stripe", collectionOptionKind: "upfront" };
15647
15894
  }
15648
15895
  return { method: null };
15649
15896
  }
@@ -15661,11 +15908,17 @@ function isSelectionValid(input) {
15661
15908
  case "pass":
15662
15909
  return isAuthenticated && ticketsCount === 1 && !!selection.passId && eligibility.eligiblePasses.some((pass) => pass.id === selection.passId);
15663
15910
  case "membership":
15664
- return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some((membership) => membership.id === selection.membershipId);
15911
+ return isAuthenticated && ticketsCount === 1 && !!selection.membershipId && eligibility.eligibleMemberships.some(
15912
+ (membership) => membership.id === selection.membershipId
15913
+ );
15665
15914
  case "pass_bundle":
15666
- return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some((pass) => pass.id === selection.bundlePassId);
15915
+ return ticketsCount === 1 && !!selection.bundlePassId && eligibility.availablePasses.some(
15916
+ (pass) => pass.id === selection.bundlePassId
15917
+ );
15667
15918
  case "membership_bundle":
15668
- return ticketsCount === 1 && !!selection.bundleMembershipId && eligibility.availableMemberships.some((membership) => membership.id === selection.bundleMembershipId);
15919
+ return ticketsCount === 1 && !!selection.bundleMembershipId && eligibility.availableMemberships.some(
15920
+ (membership) => membership.id === selection.bundleMembershipId
15921
+ );
15669
15922
  default:
15670
15923
  return false;
15671
15924
  }
@@ -15712,9 +15965,15 @@ function registrationFlowReducer(state, action) {
15712
15965
  ticketsCount: Math.max(1, action.ticketsCount)
15713
15966
  });
15714
15967
  case "set-authenticated":
15715
- return normalizeRegistrationFlowState({ ...state, isAuthenticated: action.isAuthenticated });
15968
+ return normalizeRegistrationFlowState({
15969
+ ...state,
15970
+ isAuthenticated: action.isAuthenticated
15971
+ });
15716
15972
  case "eligibility-updated":
15717
- return normalizeRegistrationFlowState({ ...state, eligibility: action.eligibility });
15973
+ return normalizeRegistrationFlowState({
15974
+ ...state,
15975
+ eligibility: action.eligibility
15976
+ });
15718
15977
  case "set-manual-payment-selection":
15719
15978
  return normalizeRegistrationFlowState({
15720
15979
  ...state,
@@ -15726,7 +15985,7 @@ function registrationFlowReducer(state, action) {
15726
15985
  return normalizeRegistrationFlowState({
15727
15986
  ...state,
15728
15987
  passOptOut: true,
15729
- paymentSelection: { method: "stripe" },
15988
+ paymentSelection: { method: "stripe", collectionOptionKind: "upfront" },
15730
15989
  selectionSource: "manual"
15731
15990
  });
15732
15991
  case "event-changed":
@@ -15844,7 +16103,10 @@ function toHeadlessPaymentSelection(selection) {
15844
16103
  case "free":
15845
16104
  return { method: "free" };
15846
16105
  case "stripe":
15847
- return { method: "stripe" };
16106
+ return {
16107
+ method: "stripe",
16108
+ collectionOptionKind: selection.collectionOptionKind
16109
+ };
15848
16110
  case "pass":
15849
16111
  if (!selection.passId) return { method: "none" };
15850
16112
  return {
@@ -15882,7 +16144,10 @@ function toInternalPaymentSelection(selection) {
15882
16144
  case "free":
15883
16145
  return { method: "free" };
15884
16146
  case "stripe":
15885
- return { method: "stripe" };
16147
+ return {
16148
+ method: "stripe",
16149
+ collectionOptionKind: selection.collectionOptionKind ?? "upfront"
16150
+ };
15886
16151
  case "pass":
15887
16152
  return {
15888
16153
  method: "pass",
@@ -15912,7 +16177,10 @@ function toInternalPaymentSelection(selection) {
15912
16177
  function resolveEventRegistrationSubmitPlan(input) {
15913
16178
  const selection = input.paymentSelection.method ? input.paymentSelection : void 0;
15914
16179
  if (input.canJoinWaitlist) {
15915
- return { ok: true, args: withOptionalSelection({ method: "free" }, selection) };
16180
+ return {
16181
+ ok: true,
16182
+ args: withOptionalSelection({ method: "free" }, selection)
16183
+ };
15916
16184
  }
15917
16185
  switch (input.paymentSelection.method) {
15918
16186
  case "pass":
@@ -15927,19 +16195,28 @@ function resolveEventRegistrationSubmitPlan(input) {
15927
16195
  return input.paymentSelection.membershipId ? {
15928
16196
  ok: true,
15929
16197
  args: withOptionalSelection(
15930
- { method: "membership", membershipId: input.paymentSelection.membershipId },
16198
+ {
16199
+ method: "membership",
16200
+ membershipId: input.paymentSelection.membershipId
16201
+ },
15931
16202
  selection
15932
16203
  )
15933
16204
  } : missingPaymentSelection();
15934
16205
  case "free":
15935
- return { ok: true, args: withOptionalSelection({ method: "free" }, selection) };
16206
+ return {
16207
+ ok: true,
16208
+ args: withOptionalSelection({ method: "free" }, selection)
16209
+ };
15936
16210
  case null:
15937
16211
  return input.eventRequiresPayment ? missingPaymentSelection() : { ok: true, args: { method: "free" } };
15938
16212
  case "pass_bundle":
15939
16213
  return input.paymentSelection.bundlePassId ? {
15940
16214
  ok: true,
15941
16215
  args: withOptionalSelection(
15942
- { method: "pass_bundle", passId: input.paymentSelection.bundlePassId },
16216
+ {
16217
+ method: "pass_bundle",
16218
+ passId: input.paymentSelection.bundlePassId
16219
+ },
15943
16220
  selection
15944
16221
  )
15945
16222
  } : missingPaymentSelection();
@@ -15955,7 +16232,10 @@ function resolveEventRegistrationSubmitPlan(input) {
15955
16232
  )
15956
16233
  } : missingPaymentSelection();
15957
16234
  case "stripe":
15958
- return { ok: true, args: withOptionalSelection({ method: "stripe" }, selection) };
16235
+ return {
16236
+ ok: true,
16237
+ args: withOptionalSelection({ method: "stripe" }, selection)
16238
+ };
15959
16239
  }
15960
16240
  }
15961
16241
  function resolveHeadlessEventRegistrationStatus(wizard) {
@@ -16117,7 +16397,7 @@ function findSelectedTicketType(input) {
16117
16397
  }
16118
16398
 
16119
16399
  // ../blocks/src/system/runtime/nodes/event-registration/hooks.ts
16120
- import { useState as useState6, useEffect as useEffect8, useCallback as useCallback5, useRef as useRef8, useReducer as useReducer4 } from "react";
16400
+ import { useState as useState3, useEffect as useEffect8, useCallback as useCallback5, useRef as useRef9, useReducer as useReducer7 } from "react";
16121
16401
 
16122
16402
  // ../blocks/src/system/runtime/nodes/event-registration/hooks.state.ts
16123
16403
  var initialEligibilityLookupState = {
@@ -16148,7 +16428,7 @@ function eligibilityLookupReducer(state, action) {
16148
16428
  error: action.message
16149
16429
  };
16150
16430
  default:
16151
- return assertNever11(action);
16431
+ return assertNever4(action);
16152
16432
  }
16153
16433
  }
16154
16434
  var initialExistingRegistrationLookupState = {
@@ -16170,15 +16450,15 @@ function existingRegistrationLookupReducer(state, action) {
16170
16450
  registration: action.registration
16171
16451
  };
16172
16452
  default:
16173
- return assertNever11(action);
16453
+ return assertNever4(action);
16174
16454
  }
16175
16455
  }
16176
16456
 
16177
16457
  // ../blocks/src/system/runtime/nodes/event-registration/hooks.ts
16178
16458
  function usePortalAuth() {
16179
16459
  const api = useBlockApi();
16180
- const [authState, setAuthState] = useState6("checking");
16181
- const [profile, setProfile] = useState6(null);
16460
+ const [authState, setAuthState] = useState3("checking");
16461
+ const [profile, setProfile] = useState3(null);
16182
16462
  useEffect8(() => {
16183
16463
  let cancelled = false;
16184
16464
  async function checkPortalAuth() {
@@ -16225,11 +16505,11 @@ function usePortalAuth() {
16225
16505
  }
16226
16506
  function useEligibility(params) {
16227
16507
  const api = useBlockApi();
16228
- const [state, dispatch] = useReducer4(
16508
+ const [state, dispatch] = useReducer7(
16229
16509
  eligibilityLookupReducer,
16230
16510
  initialEligibilityLookupState
16231
16511
  );
16232
- const requestIdRef = useRef8(0);
16512
+ const requestIdRef = useRef9(0);
16233
16513
  useEffect8(() => {
16234
16514
  let cancelled = false;
16235
16515
  async function fetchEligibility() {
@@ -16284,11 +16564,11 @@ function useExistingEventRegistration({
16284
16564
  occurrenceId
16285
16565
  }) {
16286
16566
  const api = useBlockApi();
16287
- const [state, dispatch] = useReducer4(
16567
+ const [state, dispatch] = useReducer7(
16288
16568
  existingRegistrationLookupReducer,
16289
16569
  initialExistingRegistrationLookupState
16290
16570
  );
16291
- const requestIdRef = useRef8(0);
16571
+ const requestIdRef = useRef9(0);
16292
16572
  useEffect8(() => {
16293
16573
  let cancelled = false;
16294
16574
  async function fetchExistingRegistration() {
@@ -16491,7 +16771,7 @@ function cleanupStaleRegistrations() {
16491
16771
  }
16492
16772
 
16493
16773
  // ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
16494
- import { useCallback as useCallback6, useEffect as useEffect11, useMemo as useMemo6, useReducer as useReducer5, useState as useState8 } from "react";
16774
+ import { useCallback as useCallback6, useEffect as useEffect11, useMemo as useMemo6, useReducer as useReducer9, useState as useState4 } from "react";
16495
16775
 
16496
16776
  // ../blocks/src/system/runtime/nodes/event-registration/validation.ts
16497
16777
  function validateFormData2(formData) {
@@ -16508,7 +16788,55 @@ function validateFormData2(formData) {
16508
16788
  }
16509
16789
 
16510
16790
  // ../blocks/src/system/runtime/shared/useWaitlistClaim.ts
16511
- import { useEffect as useEffect9, useState as useState7, useSyncExternalStore } from "react";
16791
+ import { useEffect as useEffect9, useReducer as useReducer8, useSyncExternalStore } from "react";
16792
+
16793
+ // ../blocks/src/system/runtime/shared/useWaitlistClaim.state.ts
16794
+ var DEFAULT_WAITLIST_CLAIM_ERROR = "Failed to resolve waitlist claim";
16795
+ function createInitialWaitlistClaimState(hasToken) {
16796
+ return hasToken ? { kind: "resolving" } : { kind: "idle" };
16797
+ }
16798
+ function waitlistClaimReducer(_state, action) {
16799
+ switch (action.type) {
16800
+ case "cleared":
16801
+ return { kind: "idle" };
16802
+ case "started":
16803
+ return { kind: "resolving" };
16804
+ case "resolved":
16805
+ return { kind: "resolved", claim: action.claim };
16806
+ case "failed":
16807
+ return action.failure;
16808
+ }
16809
+ }
16810
+ function toWaitlistClaimResolveFailure(error) {
16811
+ const message = error instanceof Error ? error.message : DEFAULT_WAITLIST_CLAIM_ERROR;
16812
+ if (isUnauthorizedBlockApiError(error)) {
16813
+ return { kind: "portal-login-required", message };
16814
+ }
16815
+ return { kind: "error", message };
16816
+ }
16817
+ function isUnauthorizedBlockApiError(error) {
16818
+ return error instanceof Error && error.name === "BlockApiError" && hasStatus(error) && error.status === 401;
16819
+ }
16820
+ function hasStatus(value) {
16821
+ return typeof value === "object" && value !== null && "status" in value;
16822
+ }
16823
+ function getWaitlistClaim(state) {
16824
+ return state.kind === "resolved" ? state.claim : null;
16825
+ }
16826
+ function getWaitlistClaimError(state) {
16827
+ return state.kind === "error" ? state.message : null;
16828
+ }
16829
+ function getWaitlistClaimLoginMessage(state) {
16830
+ return state.kind === "portal-login-required" ? state.message : null;
16831
+ }
16832
+ function requiresWaitlistClaimPortalLogin(state) {
16833
+ return state.kind === "portal-login-required";
16834
+ }
16835
+ function isWaitlistClaimLoading(state) {
16836
+ return state.kind === "resolving";
16837
+ }
16838
+
16839
+ // ../blocks/src/system/runtime/shared/useWaitlistClaim.ts
16512
16840
  var WAITLIST_CLAIM_LOCATION_EVENT = "riverbank:waitlist-claim-location-change";
16513
16841
  var historyPatched = false;
16514
16842
  function emitWaitlistClaimLocationChange() {
@@ -16566,46 +16894,29 @@ function useWaitlistClaim() {
16566
16894
  getWaitlistClaimTokenSnapshot,
16567
16895
  () => null
16568
16896
  );
16569
- const [claim, setClaim] = useState7(null);
16570
- const [error, setError] = useState7(null);
16571
- const [loginMessage, setLoginMessage] = useState7(null);
16572
- const [requiresPortalLogin, setRequiresPortalLogin] = useState7(false);
16573
- const [isLoading, setIsLoading] = useState7(() => Boolean(token));
16897
+ const [state, dispatch] = useReducer8(
16898
+ waitlistClaimReducer,
16899
+ Boolean(token),
16900
+ createInitialWaitlistClaimState
16901
+ );
16574
16902
  useEffect9(() => {
16575
16903
  let cancelled = false;
16576
16904
  async function resolveClaim() {
16577
16905
  if (!token) {
16578
- setClaim(null);
16579
- setError(null);
16580
- setLoginMessage(null);
16581
- setRequiresPortalLogin(false);
16582
- setIsLoading(false);
16906
+ dispatch({ type: "cleared" });
16583
16907
  return;
16584
16908
  }
16585
- setIsLoading(true);
16586
- setClaim(null);
16587
- setError(null);
16588
- setLoginMessage(null);
16589
- setRequiresPortalLogin(false);
16909
+ dispatch({ type: "started" });
16590
16910
  try {
16591
16911
  const result = await api.resolveWaitlistClaim({ claimToken: token });
16592
16912
  if (cancelled) return;
16593
- setClaim(result);
16913
+ dispatch({ type: "resolved", claim: result });
16594
16914
  } catch (claimError) {
16595
16915
  if (cancelled) return;
16596
- const message = claimError instanceof Error ? claimError.message : "Failed to resolve waitlist claim";
16597
- setClaim(null);
16598
- if (claimError instanceof BlockApiError && claimError.status === 401) {
16599
- setRequiresPortalLogin(true);
16600
- setLoginMessage(message);
16601
- setError(null);
16602
- } else {
16603
- setError(message);
16604
- }
16605
- } finally {
16606
- if (!cancelled) {
16607
- setIsLoading(false);
16608
- }
16916
+ dispatch({
16917
+ type: "failed",
16918
+ failure: toWaitlistClaimResolveFailure(claimError)
16919
+ });
16609
16920
  }
16610
16921
  }
16611
16922
  void resolveClaim();
@@ -16615,11 +16926,11 @@ function useWaitlistClaim() {
16615
16926
  }, [api, token]);
16616
16927
  return {
16617
16928
  token,
16618
- claim,
16619
- error,
16620
- loginMessage,
16621
- requiresPortalLogin,
16622
- isLoading
16929
+ claim: getWaitlistClaim(state),
16930
+ error: getWaitlistClaimError(state),
16931
+ loginMessage: getWaitlistClaimLoginMessage(state),
16932
+ requiresPortalLogin: requiresWaitlistClaimPortalLogin(state),
16933
+ isLoading: isWaitlistClaimLoading(state)
16623
16934
  };
16624
16935
  }
16625
16936
 
@@ -16907,7 +17218,7 @@ function useEventRegistrationWizard(options) {
16907
17218
  [scopedEvents, options.occurrenceContext]
16908
17219
  );
16909
17220
  const hasPreSelectedContext = !!(options.occurrenceContext || preSelectedEvent);
16910
- const [flowState, dispatchFlow] = useReducer5(
17221
+ const [flowState, dispatchFlow] = useReducer9(
16911
17222
  registrationFlowReducer,
16912
17223
  hasPreSelectedContext,
16913
17224
  createInitialRegistrationFlowState
@@ -16915,24 +17226,24 @@ function useEventRegistrationWizard(options) {
16915
17226
  const step = flowState.step;
16916
17227
  const ticketsCount = flowState.ticketsCount;
16917
17228
  const paymentSelection = flowState.paymentSelection;
16918
- const [selectedEvent, setSelectedEvent] = useState8(preSelectedEvent ?? null);
16919
- const [formData, setFormData] = useState8({ name: "", email: "", phone: "", notes: "" });
16920
- const [errors, setErrors] = useState8({});
16921
- const [guests, setGuests] = useState8([]);
16922
- const [guestErrors, setGuestErrors] = useState8({});
16923
- const [guestSectionShake, setGuestSectionShake] = useState8(false);
16924
- const [selectedAttendanceMode, setSelectedAttendanceMode] = useState8(
17229
+ const [selectedEvent, setSelectedEvent] = useState4(preSelectedEvent ?? null);
17230
+ const [formData, setFormData] = useState4({ name: "", email: "", phone: "", notes: "" });
17231
+ const [errors, setErrors] = useState4({});
17232
+ const [guests, setGuests] = useState4([]);
17233
+ const [guestErrors, setGuestErrors] = useState4({});
17234
+ const [guestSectionShake, setGuestSectionShake] = useState4(false);
17235
+ const [selectedAttendanceMode, setSelectedAttendanceMode] = useState4(
16925
17236
  preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
16926
17237
  );
16927
- const [selectedTicketTypeId, setSelectedTicketTypeId] = useState8(null);
16928
- const [registrationResult, setRegistrationResult] = useState8(null);
16929
- const [errorMessage, setErrorMessage] = useState8("");
16930
- const [altchaSolution, setAltchaSolution] = useState8(null);
17238
+ const [selectedTicketTypeId, setSelectedTicketTypeId] = useState4(null);
17239
+ const [registrationResult, setRegistrationResult] = useState4(null);
17240
+ const [errorMessage, setErrorMessage] = useState4("");
17241
+ const [altchaSolution, setAltchaSolution] = useState4(null);
16931
17242
  const { authState: portalAuthState, profile: portalProfile } = usePortalAuth();
16932
17243
  const waitlistClaim = useWaitlistClaim();
16933
- const [showMagicLinkModal, setShowMagicLinkModal] = useState8(false);
16934
- const [pendingAttendeeId, setPendingAttendeeId] = useState8(null);
16935
- const [paymentStepState, setPaymentStepState] = useState8({
17244
+ const [showMagicLinkModal, setShowMagicLinkModal] = useState4(false);
17245
+ const [pendingAttendeeId, setPendingAttendeeId] = useState4(null);
17246
+ const [paymentStepState, setPaymentStepState] = useState4({
16936
17247
  status: "loading",
16937
17248
  canContinue: false,
16938
17249
  buttonText: "Continue",
@@ -18129,10 +18440,10 @@ function buildResponsiveScopeRulePatternSource() {
18129
18440
  }
18130
18441
 
18131
18442
  // ../theme-core/src/ThemeScopeCore.tsx
18132
- import { jsx as jsx12, jsxs as jsxs9 } from "react/jsx-runtime";
18443
+ import { jsx as jsx11, jsxs as jsxs9 } from "react/jsx-runtime";
18133
18444
 
18134
18445
  // ../theme-core/src/ClientThemeScope.tsx
18135
- import { jsx as jsx13 } from "react/jsx-runtime";
18446
+ import { jsx as jsx12 } from "react/jsx-runtime";
18136
18447
 
18137
18448
  // ../blocks/src/system/runtime/hooks/useHeadlessEventRegistrationFlow.ts
18138
18449
  import React4, { useCallback as useCallback7, useMemo as useMemo8 } from "react";
@@ -18406,63 +18717,140 @@ function resolvePaymentModel(wizard) {
18406
18717
  }
18407
18718
 
18408
18719
  // ../blocks/src/system/runtime/hooks/useBookingFormConfig.ts
18409
- import { useState as useState9, useEffect as useEffect12 } from "react";
18720
+ import { useEffect as useEffect12, useReducer as useReducer10 } from "react";
18721
+
18722
+ // ../blocks/src/system/runtime/hooks/useBookingFormConfig.state.ts
18723
+ var EMPTY_SNAPSHOT = Object.freeze({
18724
+ formConfig: null,
18725
+ services: []
18726
+ });
18727
+ function createInitialBookingFormConfigState() {
18728
+ return {
18729
+ tag: "loading",
18730
+ previous: EMPTY_SNAPSHOT
18731
+ };
18732
+ }
18733
+ function bookingFormConfigReducer(state, action) {
18734
+ switch (action.type) {
18735
+ case "load-started":
18736
+ return {
18737
+ tag: "loading",
18738
+ previous: toBookingFormConfigSnapshot(state)
18739
+ };
18740
+ case "form-loaded": {
18741
+ const previous = toBookingFormConfigSnapshot(state);
18742
+ return {
18743
+ tag: "loading",
18744
+ previous: {
18745
+ formConfig: action.formConfig,
18746
+ services: previous.formConfig?.id === action.formConfig.id ? previous.services : []
18747
+ }
18748
+ };
18749
+ }
18750
+ case "load-succeeded":
18751
+ return {
18752
+ tag: "loaded",
18753
+ formConfig: action.formConfig,
18754
+ services: action.services
18755
+ };
18756
+ case "services-load-failed": {
18757
+ const previous = toBookingFormConfigSnapshot(state);
18758
+ return previous.formConfig ? {
18759
+ tag: "loaded",
18760
+ formConfig: previous.formConfig,
18761
+ services: previous.services
18762
+ } : {
18763
+ tag: "error",
18764
+ message: action.message,
18765
+ previous
18766
+ };
18767
+ }
18768
+ case "load-failed":
18769
+ return {
18770
+ tag: "error",
18771
+ message: action.message,
18772
+ previous: toBookingFormConfigSnapshot(state)
18773
+ };
18774
+ default:
18775
+ return assertNever4(action);
18776
+ }
18777
+ }
18778
+ function selectBookingFormConfig(state) {
18779
+ return toBookingFormConfigSnapshot(state).formConfig;
18780
+ }
18781
+ function selectBookingFormServices(state) {
18782
+ return toBookingFormConfigSnapshot(state).services;
18783
+ }
18784
+ function selectBookingFormConfigIsLoading(state) {
18785
+ return state.tag === "loading";
18786
+ }
18787
+ function selectBookingFormConfigError(state) {
18788
+ return state.tag === "error" ? state.message : null;
18789
+ }
18790
+ function toBookingFormConfigSnapshot(state) {
18791
+ switch (state.tag) {
18792
+ case "loading":
18793
+ case "error":
18794
+ return state.previous;
18795
+ case "loaded":
18796
+ return {
18797
+ formConfig: state.formConfig,
18798
+ services: state.services
18799
+ };
18800
+ default:
18801
+ return assertNever4(state);
18802
+ }
18803
+ }
18804
+
18805
+ // ../blocks/src/system/runtime/hooks/useBookingFormConfig.ts
18410
18806
  function useBookingFormConfig(siteId, formId) {
18411
18807
  const api = useBlockApi();
18412
- const [formConfig, setFormConfig] = useState9(null);
18413
- const [services, setServices] = useState9([]);
18414
- const [isLoading, setIsLoading] = useState9(true);
18415
- const [error, setError] = useState9(null);
18808
+ const [state, dispatch] = useReducer10(
18809
+ bookingFormConfigReducer,
18810
+ void 0,
18811
+ createInitialBookingFormConfigState
18812
+ );
18813
+ const formConfig = selectBookingFormConfig(state);
18814
+ const services = selectBookingFormServices(state);
18416
18815
  useEffect12(() => {
18417
18816
  let mounted = true;
18418
18817
  async function loadFormAndServices() {
18818
+ dispatch({ type: "load-started" });
18419
18819
  try {
18420
- setIsLoading(true);
18421
- setError(null);
18422
18820
  const formResponse = await api.getForm(formId, siteId);
18423
18821
  if (!mounted) return;
18424
- const rawData = formResponse.form;
18425
- const normalizedForm = {
18426
- id: rawData.id,
18427
- name: rawData.name,
18428
- slug: rawData.slug,
18429
- settings: rawData.settingsJson ?? rawData.settings,
18430
- schema: rawData.schemaJson ?? rawData.schema
18431
- };
18432
- setFormConfig(normalizedForm);
18433
- if (!normalizedForm.settings?.serviceId && !normalizedForm.settings?.serviceIds) {
18434
- try {
18435
- const servicesData = await api.getBookingServices();
18436
- if (mounted) {
18437
- setServices(servicesData.services || []);
18438
- }
18439
- } catch {
18440
- }
18441
- } else if (normalizedForm.settings?.serviceIds && normalizedForm.settings.serviceIds.length > 0) {
18442
- try {
18443
- const servicesData = await api.getBookingServices({ ids: normalizedForm.settings.serviceIds });
18444
- if (mounted) {
18445
- setServices(servicesData.services || []);
18446
- }
18447
- } catch {
18448
- }
18449
- } else if (normalizedForm.settings?.serviceId) {
18450
- try {
18451
- const serviceData = await api.getBookingService(normalizedForm.settings.serviceId);
18452
- if (mounted) {
18453
- setServices([serviceData.service]);
18454
- }
18455
- } catch {
18822
+ const normalizedForm = normalizeBookingFormConfig(formResponse.form);
18823
+ if (!normalizedForm) {
18824
+ throw new Error("Invalid booking form response.");
18825
+ }
18826
+ dispatch({
18827
+ type: "form-loaded",
18828
+ formConfig: normalizedForm
18829
+ });
18830
+ try {
18831
+ const services2 = await loadBookingFormServices(api, normalizedForm);
18832
+ if (!mounted) return;
18833
+ dispatch({
18834
+ type: "load-succeeded",
18835
+ formConfig: normalizedForm,
18836
+ services: services2
18837
+ });
18838
+ } catch (err3) {
18839
+ console.warn("Failed to load booking form services:", err3);
18840
+ if (mounted) {
18841
+ dispatch({
18842
+ type: "services-load-failed",
18843
+ message: "Failed to load booking services."
18844
+ });
18456
18845
  }
18457
18846
  }
18458
18847
  } catch (err3) {
18459
18848
  console.error("Failed to load form:", err3);
18460
18849
  if (mounted) {
18461
- setError("Failed to load booking form. Please try again later.");
18462
- }
18463
- } finally {
18464
- if (mounted) {
18465
- setIsLoading(false);
18850
+ dispatch({
18851
+ type: "load-failed",
18852
+ message: "Failed to load booking form. Please try again later."
18853
+ });
18466
18854
  }
18467
18855
  }
18468
18856
  }
@@ -18471,7 +18859,27 @@ function useBookingFormConfig(siteId, formId) {
18471
18859
  mounted = false;
18472
18860
  };
18473
18861
  }, [siteId, formId, api]);
18474
- return { formConfig, services, isLoading, error };
18862
+ return {
18863
+ formConfig,
18864
+ services,
18865
+ isLoading: selectBookingFormConfigIsLoading(state),
18866
+ error: selectBookingFormConfigError(state)
18867
+ };
18868
+ }
18869
+ async function loadBookingFormServices(api, formConfig) {
18870
+ if (!formConfig.settings?.serviceId && !formConfig.settings?.serviceIds) {
18871
+ const servicesData = await api.getBookingServices();
18872
+ return normalizeBookingServices(servicesData.services);
18873
+ }
18874
+ if (formConfig.settings?.serviceIds && formConfig.settings.serviceIds.length > 0) {
18875
+ const servicesData = await api.getBookingServices({ ids: [...formConfig.settings.serviceIds] });
18876
+ return normalizeBookingServices(servicesData.services);
18877
+ }
18878
+ if (formConfig.settings?.serviceId) {
18879
+ const serviceData = await api.getBookingService(formConfig.settings.serviceId);
18880
+ return normalizeBookingServices([serviceData.service]);
18881
+ }
18882
+ return [];
18475
18883
  }
18476
18884
 
18477
18885
  // src/bookings/index.ts