@riverbankcms/sdk 0.85.0 → 0.89.1

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 (166) hide show
  1. package/dist/{PreviewEditorSidebar-4PH35ZIE.mjs → PreviewEditorSidebar-JDR64FEC.mjs} +3 -3
  2. package/dist/{PreviewEditorUI-WHMCRJGM.mjs → PreviewEditorUI-67TMJMAF.mjs} +3 -3
  3. package/dist/SdkPreviewModeRuntime-ZBEMRV7N.mjs +8 -0
  4. package/dist/_dts/api/src/accessAdmin.d.ts +7 -0
  5. package/dist/_dts/api/src/endpoints.d.ts +66 -14
  6. package/dist/_dts/api/src/index.d.ts +5 -2
  7. package/dist/_dts/api/src/launchReadiness.d.ts +3 -3
  8. package/dist/_dts/api/src/mailchimpIntegration.d.ts +215 -0
  9. package/dist/_dts/api/src/publicExperienceEndpoints.d.ts +35 -15
  10. package/dist/_dts/api/src/siteInfrastructure.d.ts +0 -14
  11. package/dist/_dts/api/src/siteManagementEndpoints.d.ts +5 -1
  12. package/dist/_dts/api/src/siteMembers.d.ts +6 -1
  13. package/dist/_dts/api/src/siteRuntimeEndpoints.d.ts +1 -13
  14. package/dist/_dts/api/src/types.d.ts +7 -4
  15. package/dist/_dts/blocks/src/PageRenderer.d.ts +1 -0
  16. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +4 -0
  17. package/dist/_dts/blocks/src/index.d.ts +2 -1
  18. package/dist/_dts/blocks/src/system/blocks/appointment-booking.d.ts +288 -288
  19. package/dist/_dts/blocks/src/system/blocks/blog-listing.d.ts +288 -288
  20. package/dist/_dts/blocks/src/system/blocks/cart.d.ts +288 -288
  21. package/dist/_dts/blocks/src/system/blocks/checkout.d.ts +288 -288
  22. package/dist/_dts/blocks/src/system/blocks/collection.d.ts +288 -288
  23. package/dist/_dts/blocks/src/system/blocks/events/shared/schemas.d.ts +42 -0
  24. package/dist/_dts/blocks/src/system/blocks/events/shared/types.d.ts +4 -0
  25. package/dist/_dts/blocks/src/system/blocks/faq.d.ts +288 -288
  26. package/dist/_dts/blocks/src/system/blocks/gifting.d.ts +288 -288
  27. package/dist/_dts/blocks/src/system/blocks/location-map.d.ts +1 -1
  28. package/dist/_dts/blocks/src/system/blocks/media-text.d.ts +42 -42
  29. package/dist/_dts/blocks/src/system/blocks/newsletter-signup-destination.d.ts +300 -0
  30. package/dist/_dts/blocks/src/system/blocks/newsletter-signup.d.ts +63 -3
  31. package/dist/_dts/blocks/src/system/blocks/product-detail.d.ts +288 -288
  32. package/dist/_dts/blocks/src/system/blocks/product-list.d.ts +288 -288
  33. package/dist/_dts/blocks/src/system/blocks/shop.d.ts +288 -288
  34. package/dist/_dts/blocks/src/system/fragments/library/newsletterForm.d.ts +53 -1
  35. package/dist/_dts/blocks/src/system/icons/cta.d.ts +3 -3
  36. package/dist/_dts/blocks/src/system/icons/index.d.ts +1 -0
  37. package/dist/_dts/blocks/src/system/icons/registry.d.ts +2 -2
  38. package/dist/_dts/blocks/src/system/icons/semantic.d.ts +3 -3
  39. package/dist/_dts/blocks/src/system/icons/svg.d.ts +72 -0
  40. package/dist/_dts/blocks/src/system/manifest/richTextSchema.d.ts +27 -0
  41. package/dist/_dts/blocks/src/system/manifest/schema.d.ts +23 -23
  42. package/dist/_dts/blocks/src/system/runtime/api/types.d.ts +11 -2
  43. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +24 -0
  44. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +12 -0
  45. package/dist/_dts/blocks/src/system/runtime/hooks/loadStateError.d.ts +1 -0
  46. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.d.ts +1 -1
  47. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableDates.state.d.ts +55 -0
  48. package/dist/_dts/blocks/src/system/runtime/hooks/useAvailableSlots.state.d.ts +39 -0
  49. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.d.ts +4 -27
  50. package/dist/_dts/blocks/src/system/runtime/hooks/useBookingFormConfig.state.d.ts +40 -0
  51. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +20 -0
  52. package/dist/_dts/blocks/src/system/runtime/hooks/useEventFilters.state.d.ts +31 -0
  53. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.d.ts +3 -3
  54. package/dist/_dts/blocks/src/system/runtime/hooks/useEventPagination.state.d.ts +39 -0
  55. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/types.d.ts +1 -0
  56. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.interactive.d.ts +4 -0
  57. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration.server.d.ts +1 -1
  58. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventPaginatedListView.client.d.ts +1 -1
  59. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +11 -1
  60. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.client.state.d.ts +24 -2
  61. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.interactive.d.ts +15 -0
  62. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.server.d.ts +1 -1
  63. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.submission.d.ts +32 -0
  64. package/dist/_dts/blocks/src/system/runtime/nodes/newsletter-form.types.d.ts +5 -1
  65. package/dist/_dts/blocks/src/system/runtime/nodes/shared/MagicLinkForm.state.d.ts +24 -0
  66. package/dist/_dts/blocks/src/system/runtime/shared/components/ModalShell.d.ts +5 -1
  67. package/dist/_dts/blocks/src/system/runtime/shared/useWaitlistClaim.state.d.ts +35 -0
  68. package/dist/_dts/blocks/src/system/runtime/shared/utils/formatting.d.ts +1 -1
  69. package/dist/_dts/content-model/src/entry-slots/types.d.ts +54 -0
  70. package/dist/_dts/content-model/src/referenceFields.d.ts +1 -1
  71. package/dist/_dts/core/src/branded.d.ts +7 -0
  72. package/dist/_dts/core/src/currency-format.d.ts +37 -2
  73. package/dist/_dts/core/src/event-pricing.d.ts +24 -0
  74. package/dist/_dts/core/src/index.d.ts +1 -0
  75. package/dist/_dts/core/src/site-route-target.d.ts +40 -0
  76. package/dist/_dts/db/src/generated/supabase/database.types.d.ts +705 -17
  77. package/dist/_dts/editor-blocks/src/widgets/reference/loaders.d.ts +3 -1
  78. package/dist/_dts/media-core/src/fileDomain.d.ts +4 -0
  79. package/dist/_dts/sdk/src/client/runtimeCachePolicy.d.ts +160 -0
  80. package/dist/_dts/sdk/src/client/types.d.ts +35 -1
  81. package/dist/_dts/sdk/src/config/validation.d.ts +3 -0
  82. package/dist/_dts/sdk/src/contracts/system-block-content.d.ts +3 -0
  83. package/dist/_dts/sdk/src/data/prefetchBlockData.d.ts +3 -9
  84. package/dist/_dts/sdk/src/index.d.ts +3 -1
  85. package/dist/_dts/sdk/src/manifest/passes/pass1-fields.d.ts +1 -1
  86. package/dist/_dts/sdk/src/manifest/three-pass-converter.d.ts +7 -18
  87. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +2 -0
  88. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +3 -1
  89. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +7 -3
  90. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +4 -24
  91. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +45 -0
  92. package/dist/_dts/sdk/src/version.d.ts +1 -1
  93. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  94. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +9 -9
  95. package/dist/_dts/theme-core/src/schema.d.ts +11 -11
  96. package/dist/{chunk-PYDHOMEO.mjs → chunk-7N46MZHI.mjs} +1 -1
  97. package/dist/{chunk-ZR2GQK2A.mjs → chunk-7YUAXONX.mjs} +1880 -588
  98. package/dist/{chunk-4QNLOTES.mjs → chunk-F645A5UV.mjs} +76 -14
  99. package/dist/{chunk-OCGTXHSO.mjs → chunk-HKJQERFR.mjs} +7 -7
  100. package/dist/{chunk-NFWGLRZZ.mjs → chunk-TGBJWKMP.mjs} +37 -3
  101. package/dist/{chunk-WFPYN7KA.mjs → chunk-ZQRBLCW5.mjs} +2 -2
  102. package/dist/cli/index.mjs +1075 -126
  103. package/dist/client/{accordion-2UZPBMYM.mjs → accordion-MUCVNGQ7.mjs} +2 -2
  104. package/dist/client/{bookingForm-36CWQUMV.mjs → bookingForm-PKD6EFIE.mjs} +193 -77
  105. package/dist/client/bookings.mjs +487 -197
  106. package/dist/client/{carousel-QH77HR6X.mjs → carousel-3TKQSNJC.mjs} +4 -3
  107. package/dist/client/cart-6XHSZK23.mjs +19 -0
  108. package/dist/client/checkout-FVSPM6FI.mjs +19 -0
  109. package/dist/client/{chunk-ZE5G642V.mjs → chunk-25W2EQUN.mjs} +75 -1
  110. package/dist/client/chunk-6N7YRNYU.mjs +183 -0
  111. package/dist/client/{chunk-4OXKTA3D.mjs → chunk-7DH35FGA.mjs} +2 -2
  112. package/dist/client/{chunk-3C2VTPWI.mjs → chunk-CQKKFEQD.mjs} +363 -66
  113. package/dist/client/{chunk-7UCLJ5SP.mjs → chunk-EY42X22F.mjs} +4 -7
  114. package/dist/client/{chunk-SYIJ5JO2.mjs → chunk-FHU6PFPM.mjs} +1 -1
  115. package/dist/client/{chunk-ZKUO52W3.mjs → chunk-LQFDYWPJ.mjs} +1 -1
  116. package/dist/client/chunk-RSQWWUAD.mjs +390 -0
  117. package/dist/client/{chunk-UDNSI5PY.mjs → chunk-STJ2NCQM.mjs} +2 -3
  118. package/dist/client/{chunk-VGDBVNOO.mjs → chunk-UQFY4AHX.mjs} +511 -406
  119. package/dist/client/{chunk-F5VRX5Y6.mjs → chunk-VGLXACVK.mjs} +1 -1
  120. package/dist/client/{chunk-DVNUDUVT.mjs → chunk-WBQG7VJA.mjs} +4 -1
  121. package/dist/client/{chunk-52CGCQ7B.mjs → chunk-ZJZZA5EP.mjs} +10 -80
  122. package/dist/client/{chunk-XSV6KW4D.mjs → chunk-ZT5XE7FK.mjs} +1 -1
  123. package/dist/client/client.mjs +5820 -4782
  124. package/dist/client/{courseRegistration-TMKU6ABO.mjs → courseRegistration-ATZSYDHM.mjs} +7 -7
  125. package/dist/client/{eventCalendar-G6TI32X6.mjs → eventCalendar-6T2UGKKP.mjs} +11 -11
  126. package/dist/client/{eventCombined-SCKEMNAR.mjs → eventCombined-Q4VANXVF.mjs} +11 -11
  127. package/dist/client/{eventDetails-XPIFXXPK.mjs → eventDetails-DW37E7VW.mjs} +11 -11
  128. package/dist/client/{eventListing-7QFMEMGT.mjs → eventListing-XURTSAUW.mjs} +11 -11
  129. package/dist/client/{eventRegistration-TOODSZUI.mjs → eventRegistration-MRKEVAXW.mjs} +11 -11
  130. package/dist/client/{form-MTCMVCZT.mjs → form-WZZFFGMU.mjs} +3 -3
  131. package/dist/client/{headerSection-Y5TMR3TW.mjs → headerSection-EQYVQBLM.mjs} +4 -4
  132. package/dist/client/hooks.mjs +1700 -1412
  133. package/dist/client/{locationMap-RH2LG7FZ.mjs → locationMap-MFF5VAZR.mjs} +3 -4
  134. package/dist/client/{newsletterForm-PCAIPFMA.mjs → newsletterForm-JQ77UYIE.mjs} +127 -43
  135. package/dist/client/{productDetail-OIGDR4YE.mjs → productDetail-25LMT3IZ.mjs} +9 -9
  136. package/dist/client/{productList-4MA5S2CX.mjs → productList-5ABEMKUG.mjs} +9 -9
  137. package/dist/client/rendering/client.mjs +3884 -3722
  138. package/dist/client/rendering/islands.mjs +19 -19
  139. package/dist/client/rendering.mjs +6774 -6331
  140. package/dist/client/shop-OMMQZ6YO.mjs +21 -0
  141. package/dist/preview-next/before-render.mjs +76 -14
  142. package/dist/preview-next/client/runtime.mjs +5 -5
  143. package/dist/preview-next/editor-chrome.css +56 -9
  144. package/dist/preview-next/middleware.mjs +76 -14
  145. package/dist/{sdk-runtime-QLOCYKVU.mjs → sdk-runtime-WNLBZ3ZH.mjs} +6 -6
  146. package/dist/server/components.mjs +2579 -2548
  147. package/dist/server/config-validation.mjs +1737 -1461
  148. package/dist/server/config.mjs +1737 -1461
  149. package/dist/server/data.mjs +1701 -1413
  150. package/dist/server/index.mjs +1048 -400
  151. package/dist/server/next.mjs +3602 -2858
  152. package/dist/server/page-converter.mjs +2193 -1169
  153. package/dist/server/prebuild.mjs +1 -1
  154. package/dist/server/rendering/server.mjs +2770 -2742
  155. package/dist/server/rendering.mjs +2961 -2886
  156. package/dist/server/routing.mjs +2186 -1508
  157. package/dist/server/server.mjs +2237 -1287
  158. package/dist/server/theme-bridge.mjs +260 -0
  159. package/dist/styles/index.css +258 -0
  160. package/package.json +2 -1
  161. package/dist/SdkPreviewModeRuntime-4FGSVUYI.mjs +0 -8
  162. package/dist/client/cart-X4YK4FTW.mjs +0 -19
  163. package/dist/client/checkout-OM2BEPWD.mjs +0 -19
  164. package/dist/client/chunk-3DTWLTXM.mjs +0 -204
  165. package/dist/client/chunk-I2MMZO53.mjs +0 -6
  166. package/dist/client/shop-WXSYV5QO.mjs +0 -21
@@ -3682,9 +3682,8 @@ function createBlockApi(config) {
3682
3682
  name: data.name,
3683
3683
  company: data.company,
3684
3684
  phone: data.phone,
3685
- listId: data.listId,
3685
+ target: data.target,
3686
3686
  tags: data.tags,
3687
- blockId: data.blockId,
3688
3687
  meta: data.meta
3689
3688
  }
3690
3689
  });
@@ -5225,6 +5224,43 @@ function subtractDaysFromIso(isoString, dayCount) {
5225
5224
  return addDaysToIso(isoString, -dayCount);
5226
5225
  }
5227
5226
 
5227
+ // ../core/src/currency-format.ts
5228
+ var CURRENCY_LOCALE_BY_CODE = {
5229
+ USD: "en-US",
5230
+ GBP: "en-GB",
5231
+ EUR: "de-DE",
5232
+ AUD: "en-AU",
5233
+ CAD: "en-CA",
5234
+ NZD: "en-NZ",
5235
+ JPY: "ja-JP",
5236
+ CNY: "zh-CN",
5237
+ CHF: "de-CH"
5238
+ };
5239
+ function resolveCurrencyLocale(currencyCode, override) {
5240
+ return override ?? CURRENCY_LOCALE_BY_CODE[currencyCode] ?? "en";
5241
+ }
5242
+ function formatCurrencyAmount(amountCents, currency, options) {
5243
+ const currencyCode = currency.toUpperCase();
5244
+ const locale = resolveCurrencyLocale(currencyCode, options?.locale);
5245
+ try {
5246
+ const exactFormatter = new Intl.NumberFormat(locale, {
5247
+ style: "currency",
5248
+ currency: currencyCode
5249
+ });
5250
+ const fractionDigits = options?.decimals === "auto" ? {
5251
+ minimumFractionDigits: 0,
5252
+ maximumFractionDigits: exactFormatter.resolvedOptions().maximumFractionDigits
5253
+ } : {};
5254
+ return new Intl.NumberFormat(locale, {
5255
+ style: "currency",
5256
+ currency: currencyCode,
5257
+ ...fractionDigits
5258
+ }).format(amountCents / 100);
5259
+ } catch {
5260
+ return `${(amountCents / 100).toFixed(2)} ${currencyCode}`;
5261
+ }
5262
+ }
5263
+
5228
5264
  // ../core/src/event-pricing.ts
5229
5265
  function publicEventPricingType(pricing) {
5230
5266
  switch (pricing.kind) {
@@ -5263,6 +5299,7 @@ function isFreePublicEventPriceDisplay(display) {
5263
5299
  return display.display.kind === "free";
5264
5300
  case "exact":
5265
5301
  case "from":
5302
+ case "range":
5266
5303
  case "mixed":
5267
5304
  case "unavailable":
5268
5305
  return false;
@@ -6482,10 +6519,21 @@ function readLegacyPriceDisplay(value, currency) {
6482
6519
  amount: readAmount(value.amount) ?? 0,
6483
6520
  currency: displayCurrency
6484
6521
  } : { kind: "unavailable", currency };
6522
+ case "range": {
6523
+ const minAmount = readAmount(value.minAmount);
6524
+ const maxAmount = readAmount(value.maxAmount);
6525
+ return minAmount !== null && maxAmount !== null ? {
6526
+ kind: "range",
6527
+ minAmount,
6528
+ maxAmount,
6529
+ currency: displayCurrency
6530
+ } : { kind: "unavailable", currency };
6531
+ }
6485
6532
  case "mixed":
6486
6533
  return readAmount(value.paidFromAmount) !== null ? {
6487
6534
  kind: "mixed",
6488
6535
  paidFromAmount: readAmount(value.paidFromAmount) ?? 0,
6536
+ paidToAmount: readAmount(value.paidToAmount) ?? readAmount(value.paidFromAmount) ?? 0,
6489
6537
  currency: displayCurrency
6490
6538
  } : { kind: "unavailable", currency };
6491
6539
  case "unavailable":
@@ -11902,7 +11950,7 @@ function FeedbackMessage({
11902
11950
  }
11903
11951
 
11904
11952
  // ../blocks/src/system/runtime/nodes/booking-form.client.tsx
11905
- import React3, { useRef as useRef7, useState as useState5 } from "react";
11953
+ import React3, { useRef as useRef7, useState as useState3 } from "react";
11906
11954
 
11907
11955
  // ../altcha/src/AltchaWidget.tsx
11908
11956
  import { useEffect, useRef } from "react";
@@ -11989,9 +12037,9 @@ import React2, {
11989
12037
  useEffect as useEffect6,
11990
12038
  useLayoutEffect,
11991
12039
  useMemo as useMemo2,
11992
- useReducer as useReducer2,
12040
+ useReducer as useReducer4,
11993
12041
  useRef as useRef5,
11994
- useState as useState4
12042
+ useState as useState2
11995
12043
  } from "react";
11996
12044
 
11997
12045
  // ../../node_modules/.pnpm/altcha-lib@1.4.1/node_modules/altcha-lib/dist/helpers.js
@@ -12018,7 +12066,7 @@ function getChallengeUrl() {
12018
12066
  }
12019
12067
 
12020
12068
  // ../blocks/src/system/runtime/hooks/useAvailableDates.ts
12021
- import { useState, useEffect as useEffect3, useCallback, useRef as useRef3 } from "react";
12069
+ import { useEffect as useEffect3, useCallback, useReducer, useRef as useRef3 } from "react";
12022
12070
 
12023
12071
  // ../blocks/src/utils/date-formatting.ts
12024
12072
  var BOOKING_FETCH_CHUNK_DAYS = 14;
@@ -12127,6 +12175,75 @@ function useVisibleTabPolling({
12127
12175
  }, [enabled, intervalMs, jitterMs, minVisibleRefreshIntervalMs]);
12128
12176
  }
12129
12177
 
12178
+ // ../blocks/src/system/runtime/hooks/useAvailableDates.state.ts
12179
+ function createEmptyAvailableDatesData() {
12180
+ return {
12181
+ availableDates: /* @__PURE__ */ new Set(),
12182
+ hasMore: false,
12183
+ loadedRange: null,
12184
+ nextStartDate: null
12185
+ };
12186
+ }
12187
+ function createInitialAvailableDatesState() {
12188
+ return {
12189
+ tag: "idle",
12190
+ data: createEmptyAvailableDatesData()
12191
+ };
12192
+ }
12193
+ var initialAvailableDatesState = createInitialAvailableDatesState();
12194
+ function getAvailableDates(state) {
12195
+ return state.data.availableDates;
12196
+ }
12197
+ function getAvailableDatesLoadedRange(state) {
12198
+ return state.data.loadedRange;
12199
+ }
12200
+ function getAvailableDatesNextStartDate(state) {
12201
+ return state.data.nextStartDate;
12202
+ }
12203
+ function hasMoreAvailableDates(state) {
12204
+ return state.data.hasMore;
12205
+ }
12206
+ function isLoadingAvailableDates(state) {
12207
+ return state.tag === "loading";
12208
+ }
12209
+ function isRefreshingAvailableDates(state) {
12210
+ return state.tag === "refreshing";
12211
+ }
12212
+ function getAvailableDatesError(state) {
12213
+ return state.tag === "error" ? state.message : null;
12214
+ }
12215
+ function mergeAvailableDates(previous, action) {
12216
+ const availableDates = action.append ? new Set(previous.availableDates) : /* @__PURE__ */ new Set();
12217
+ for (const date of action.dates) {
12218
+ availableDates.add(date);
12219
+ }
12220
+ return {
12221
+ availableDates,
12222
+ hasMore: action.hasMore,
12223
+ loadedRange: {
12224
+ start: action.append && previous.loadedRange ? previous.loadedRange.start : action.startDate,
12225
+ end: action.endDate
12226
+ },
12227
+ nextStartDate: action.nextStartDate
12228
+ };
12229
+ }
12230
+ function availableDatesReducer(state, action) {
12231
+ switch (action.type) {
12232
+ case "query-cleared":
12233
+ return { tag: "idle", data: createEmptyAvailableDatesData() };
12234
+ case "load-started":
12235
+ return { tag: "loading", data: state.data };
12236
+ case "refresh-started":
12237
+ return { tag: "refreshing", data: state.data };
12238
+ case "load-succeeded":
12239
+ return { tag: "loaded", data: mergeAvailableDates(state.data, action) };
12240
+ case "load-failed":
12241
+ return { tag: "error", data: state.data, message: action.message };
12242
+ default:
12243
+ return assertNever11(action);
12244
+ }
12245
+ }
12246
+
12130
12247
  // ../blocks/src/system/runtime/hooks/useAvailableDates.ts
12131
12248
  var AVAILABILITY_REFRESH_INTERVAL_MS = 3e4;
12132
12249
  var AVAILABILITY_REFRESH_JITTER_MS = 5e3;
@@ -12139,25 +12256,23 @@ function useAvailableDates({
12139
12256
  initialDays = 30
12140
12257
  }) {
12141
12258
  const api = useBlockApi();
12142
- const [availableDates, setAvailableDates] = useState(/* @__PURE__ */ new Set());
12143
- const [isLoading, setIsLoading] = useState(false);
12144
- const [isRefreshing, setIsRefreshing] = useState(false);
12145
- const [error, setError] = useState(null);
12146
- const [hasMore, setHasMore] = useState(false);
12147
- const [loadedRange, setLoadedRange] = useState(null);
12148
- const nextStartDateRef = useRef3(null);
12259
+ const [state, dispatch] = useReducer(
12260
+ availableDatesReducer,
12261
+ createInitialAvailableDatesState()
12262
+ );
12149
12263
  const requestIdRef = useRef3(0);
12264
+ const loadedRange = getAvailableDatesLoadedRange(state);
12265
+ const isLoading = isLoadingAvailableDates(state);
12266
+ const nextStartDate = getAvailableDatesNextStartDate(state);
12150
12267
  const fetchDates = useCallback(
12151
12268
  async (startDate, endDate, append = false, mode = "load") => {
12152
12269
  if (!serviceId) return;
12153
12270
  const requestId = ++requestIdRef.current;
12154
12271
  if (mode === "refresh") {
12155
- setIsRefreshing(true);
12272
+ dispatch({ type: "refresh-started" });
12156
12273
  } else {
12157
- setIsLoading(true);
12158
- setIsRefreshing(false);
12274
+ dispatch({ type: "load-started" });
12159
12275
  }
12160
- setError(null);
12161
12276
  try {
12162
12277
  const data = await api.getAvailableDates({
12163
12278
  serviceId,
@@ -12167,38 +12282,29 @@ function useAvailableDates({
12167
12282
  resourceId
12168
12283
  });
12169
12284
  if (requestId !== requestIdRef.current) return;
12170
- setAvailableDates((prev) => {
12171
- const newSet = append ? new Set(prev) : /* @__PURE__ */ new Set();
12172
- data.dates.forEach((d) => newSet.add(d));
12173
- return newSet;
12285
+ dispatch({
12286
+ type: "load-succeeded",
12287
+ dates: data.dates,
12288
+ hasMore: data.hasMore,
12289
+ nextStartDate: data.nextStartDate || null,
12290
+ startDate: data.startDate,
12291
+ endDate: data.endDate,
12292
+ append
12174
12293
  });
12175
- setHasMore(data.hasMore);
12176
- nextStartDateRef.current = data.nextStartDate || null;
12177
- setLoadedRange((prev) => ({
12178
- start: append && prev ? prev.start : data.startDate,
12179
- end: data.endDate
12180
- }));
12181
12294
  } catch (err3) {
12182
12295
  if (requestId !== requestIdRef.current) return;
12183
- setError(
12184
- err3 instanceof Error ? err3.message : "Failed to load available dates"
12185
- );
12186
- } finally {
12187
- if (mode === "refresh" && requestId === requestIdRef.current) {
12188
- setIsRefreshing(false);
12189
- } else if (requestId === requestIdRef.current) {
12190
- setIsLoading(false);
12191
- }
12296
+ dispatch({
12297
+ type: "load-failed",
12298
+ message: err3 instanceof Error ? err3.message : "Failed to load available dates"
12299
+ });
12192
12300
  }
12193
12301
  },
12194
12302
  [api, serviceId, resourceId, timezone]
12195
12303
  );
12196
12304
  useEffect3(() => {
12197
12305
  if (!serviceId) {
12198
- setAvailableDates(/* @__PURE__ */ new Set());
12199
- setLoadedRange(null);
12200
- setHasMore(false);
12201
- setIsRefreshing(false);
12306
+ requestIdRef.current += 1;
12307
+ dispatch({ type: "query-cleared" });
12202
12308
  return;
12203
12309
  }
12204
12310
  const now = /* @__PURE__ */ new Date();
@@ -12222,8 +12328,8 @@ function useAvailableDates({
12222
12328
  }
12223
12329
  });
12224
12330
  const loadMore = useCallback(() => {
12225
- if (!nextStartDateRef.current || isLoading) return;
12226
- const start = nextStartDateRef.current;
12331
+ if (!nextStartDate || isLoading) return;
12332
+ const start = nextStartDate;
12227
12333
  const end = formatLocalScheduleDate(
12228
12334
  addLocalScheduleDays(
12229
12335
  parseBookingLocalDate(start),
@@ -12231,20 +12337,86 @@ function useAvailableDates({
12231
12337
  )
12232
12338
  );
12233
12339
  void fetchDates(start, end, true);
12234
- }, [fetchDates, isLoading]);
12340
+ }, [fetchDates, isLoading, nextStartDate]);
12235
12341
  return {
12236
- availableDates,
12342
+ availableDates: getAvailableDates(state),
12237
12343
  isLoading,
12238
- isRefreshing,
12239
- error,
12240
- hasMore,
12344
+ isRefreshing: isRefreshingAvailableDates(state),
12345
+ error: getAvailableDatesError(state),
12346
+ hasMore: hasMoreAvailableDates(state),
12241
12347
  loadMore,
12242
12348
  loadedRange
12243
12349
  };
12244
12350
  }
12245
12351
 
12246
12352
  // ../blocks/src/system/runtime/hooks/useAvailableSlots.ts
12247
- import { useState as useState2, useCallback as useCallback2, useEffect as useEffect4, useRef as useRef4 } from "react";
12353
+ import { useCallback as useCallback2, useEffect as useEffect4, useReducer as useReducer2, useRef as useRef4 } from "react";
12354
+
12355
+ // ../blocks/src/system/runtime/hooks/useAvailableSlots.state.ts
12356
+ var initialAvailableSlotsState = { tag: "idle" };
12357
+ function getAvailableSlots(state) {
12358
+ switch (state.tag) {
12359
+ case "idle":
12360
+ case "loading":
12361
+ return [];
12362
+ case "loaded":
12363
+ case "refreshing":
12364
+ case "error":
12365
+ return state.slots;
12366
+ default:
12367
+ return assertNever11(state);
12368
+ }
12369
+ }
12370
+ function hasLoadedAvailableSlots(state) {
12371
+ switch (state.tag) {
12372
+ case "idle":
12373
+ return false;
12374
+ case "loading":
12375
+ case "refreshing":
12376
+ case "error":
12377
+ return state.hasLoaded;
12378
+ case "loaded":
12379
+ return true;
12380
+ default:
12381
+ return assertNever11(state);
12382
+ }
12383
+ }
12384
+ function isLoadingAvailableSlots(state) {
12385
+ return state.tag === "loading";
12386
+ }
12387
+ function isRefreshingAvailableSlots(state) {
12388
+ return state.tag === "refreshing";
12389
+ }
12390
+ function getAvailableSlotsError(state) {
12391
+ return state.tag === "error" ? state.message : null;
12392
+ }
12393
+ function availableSlotsReducer(state, action) {
12394
+ switch (action.type) {
12395
+ case "query-cleared":
12396
+ return { tag: "idle" };
12397
+ case "load-started":
12398
+ return { tag: "loading", hasLoaded: hasLoadedAvailableSlots(state) };
12399
+ case "refresh-started":
12400
+ return {
12401
+ tag: "refreshing",
12402
+ slots: getAvailableSlots(state),
12403
+ hasLoaded: hasLoadedAvailableSlots(state)
12404
+ };
12405
+ case "load-succeeded":
12406
+ return { tag: "loaded", slots: action.slots };
12407
+ case "load-failed":
12408
+ return {
12409
+ tag: "error",
12410
+ slots: getAvailableSlots(state),
12411
+ hasLoaded: hasLoadedAvailableSlots(state),
12412
+ message: action.message
12413
+ };
12414
+ default:
12415
+ return assertNever11(action);
12416
+ }
12417
+ }
12418
+
12419
+ // ../blocks/src/system/runtime/hooks/useAvailableSlots.ts
12248
12420
  var AVAILABILITY_REFRESH_INTERVAL_MS2 = 3e4;
12249
12421
  var AVAILABILITY_REFRESH_JITTER_MS2 = 5e3;
12250
12422
  function useAvailableSlots({
@@ -12256,31 +12428,23 @@ function useAvailableSlots({
12256
12428
  timezone
12257
12429
  }) {
12258
12430
  const api = useBlockApi();
12259
- const [slots, setSlots] = useState2([]);
12260
- const [isLoading, setIsLoading] = useState2(false);
12261
- const [isRefreshing, setIsRefreshing] = useState2(false);
12262
- const [hasLoaded, setHasLoaded] = useState2(false);
12263
- const [error, setError] = useState2(null);
12431
+ const [state, dispatch] = useReducer2(
12432
+ availableSlotsReducer,
12433
+ initialAvailableSlotsState
12434
+ );
12264
12435
  const requestIdRef = useRef4(0);
12265
12436
  const fetchSlots = useCallback2(
12266
12437
  async (mode) => {
12267
12438
  const requestId = ++requestIdRef.current;
12268
12439
  if (!selectedDate || !serviceId) {
12269
- setSlots([]);
12270
- setIsLoading(false);
12271
- setIsRefreshing(false);
12272
- setHasLoaded(false);
12273
- setError(null);
12440
+ dispatch({ type: "query-cleared" });
12274
12441
  return;
12275
12442
  }
12276
12443
  if (mode === "refresh") {
12277
- setIsRefreshing(true);
12444
+ dispatch({ type: "refresh-started" });
12278
12445
  } else {
12279
- setIsLoading(true);
12280
- setIsRefreshing(false);
12281
- setSlots([]);
12446
+ dispatch({ type: "load-started" });
12282
12447
  }
12283
- setError(null);
12284
12448
  try {
12285
12449
  const result = await api.getAvailableSlots({
12286
12450
  serviceId,
@@ -12290,24 +12454,19 @@ function useAvailableSlots({
12290
12454
  resourceId
12291
12455
  });
12292
12456
  if (requestId !== requestIdRef.current) return;
12293
- setSlots(
12294
- result.slots.map((slot) => ({
12457
+ dispatch({
12458
+ type: "load-succeeded",
12459
+ slots: result.slots.map((slot) => ({
12295
12460
  ...slot,
12296
12461
  resourceId: unsafeAsAppointmentResourceId(slot.resourceId)
12297
12462
  }))
12298
- );
12299
- setHasLoaded(true);
12463
+ });
12300
12464
  } catch (err3) {
12301
12465
  if (requestId !== requestIdRef.current) return;
12302
- setError(
12303
- err3 instanceof Error ? err3.message : "Failed to load available times"
12304
- );
12305
- } finally {
12306
- if (mode === "refresh" && requestId === requestIdRef.current) {
12307
- setIsRefreshing(false);
12308
- } else if (requestId === requestIdRef.current) {
12309
- setIsLoading(false);
12310
- }
12466
+ dispatch({
12467
+ type: "load-failed",
12468
+ message: err3 instanceof Error ? err3.message : "Failed to load available times"
12469
+ });
12311
12470
  }
12312
12471
  },
12313
12472
  [selectedDate, serviceId, resourceId, timezone, api]
@@ -12324,11 +12483,17 @@ function useAvailableSlots({
12324
12483
  jitterMs: AVAILABILITY_REFRESH_JITTER_MS2,
12325
12484
  onPoll: () => fetchSlots("refresh")
12326
12485
  });
12327
- return { slots, isLoading, isRefreshing, hasLoaded, error };
12486
+ return {
12487
+ slots: getAvailableSlots(state),
12488
+ isLoading: isLoadingAvailableSlots(state),
12489
+ isRefreshing: isRefreshingAvailableSlots(state),
12490
+ hasLoaded: hasLoadedAvailableSlots(state),
12491
+ error: getAvailableSlotsError(state)
12492
+ };
12328
12493
  }
12329
12494
 
12330
12495
  // ../blocks/src/system/runtime/hooks/useBookingSubmission.ts
12331
- import { useReducer } from "react";
12496
+ import { useReducer as useReducer3 } from "react";
12332
12497
 
12333
12498
  // ../blocks/src/system/runtime/hooks/useBookingSubmission.state.ts
12334
12499
  var initialBookingSubmissionState = {
@@ -12366,7 +12531,7 @@ function selectIsSubmitting(state) {
12366
12531
  // ../blocks/src/system/runtime/hooks/useBookingSubmission.ts
12367
12532
  function useBookingSubmission(_siteId) {
12368
12533
  const api = useBlockApi();
12369
- const [state, dispatch] = useReducer(
12534
+ const [state, dispatch] = useReducer3(
12370
12535
  bookingSubmissionReducer,
12371
12536
  initialBookingSubmissionState
12372
12537
  );
@@ -12421,14 +12586,14 @@ function useBookingSubmission(_siteId) {
12421
12586
  }
12422
12587
 
12423
12588
  // ../blocks/src/system/runtime/nodes/event-registration/useDiscountCodeUi.ts
12424
- import { useEffect as useEffect5, useState as useState3 } from "react";
12589
+ import { useEffect as useEffect5, useState } from "react";
12425
12590
  function useDiscountCodeUi(options) {
12426
- const [discountUiOpen, setDiscountUiOpen] = useState3(false);
12427
- const [discountCode, setDiscountCode] = useState3("");
12428
- const [discountsAvailable, setDiscountsAvailable] = useState3(false);
12429
- const [manualCodeEntryAllowed, setManualCodeEntryAllowed] = useState3(false);
12430
- const [autoAppliedDiscount, setAutoAppliedDiscount] = useState3(null);
12431
- const [discountsAvailableLoading, setDiscountsAvailableLoading] = useState3(false);
12591
+ const [discountUiOpen, setDiscountUiOpen] = useState(false);
12592
+ const [discountCode, setDiscountCode] = useState("");
12593
+ const [discountsAvailable, setDiscountsAvailable] = useState(false);
12594
+ const [manualCodeEntryAllowed, setManualCodeEntryAllowed] = useState(false);
12595
+ const [autoAppliedDiscount, setAutoAppliedDiscount] = useState(null);
12596
+ const [discountsAvailableLoading, setDiscountsAvailableLoading] = useState(false);
12432
12597
  useEffect5(() => {
12433
12598
  let cancelled = false;
12434
12599
  async function checkDiscountAvailability() {
@@ -12537,10 +12702,7 @@ var DEFAULT_CURRENCY = "GBP";
12537
12702
 
12538
12703
  // ../blocks/src/system/runtime/shared/utils/formatting.ts
12539
12704
  function formatPrice(cents, currency = DEFAULT_CURRENCY, locale) {
12540
- return new Intl.NumberFormat(locale, {
12541
- style: "currency",
12542
- currency: currency.toUpperCase()
12543
- }).format(cents / 100);
12705
+ return formatCurrencyAmount(cents, currency, { locale });
12544
12706
  }
12545
12707
 
12546
12708
  // ../blocks/src/system/runtime/shared/bookingPaymentOptions.ts
@@ -13544,11 +13706,11 @@ function useHeadlessBookingFlow(options) {
13544
13706
  }),
13545
13707
  [defaultResourceId, defaultServiceId, options.initialData]
13546
13708
  );
13547
- const [state, dispatch] = useReducer2(bookingFlowReducer, initialState);
13709
+ const [state, dispatch] = useReducer4(bookingFlowReducer, initialState);
13548
13710
  const api = useBlockApi();
13549
- const [resourcesState, setResourcesState] = useState4({ tag: "idle" });
13711
+ const [resourcesState, setResourcesState] = useState2({ tag: "idle" });
13550
13712
  const resourcesRequestIdRef = useRef5(0);
13551
- const [appointmentPackages, setAppointmentPackages] = useState4({ tag: "idle" });
13713
+ const [appointmentPackages, setAppointmentPackages] = useState2({ tag: "idle" });
13552
13714
  const appointmentPackagesRequestIdRef = useRef5(0);
13553
13715
  const selectedServiceId = state.selectedServiceId ?? defaultServiceId;
13554
13716
  const selectedResourceId = state.selectedResourceId ?? defaultResourceId;
@@ -14121,7 +14283,7 @@ function useLatestRef(value) {
14121
14283
  import { useMemo as useMemo3 } from "react";
14122
14284
 
14123
14285
  // ../blocks/src/system/runtime/hooks/usePolling.ts
14124
- import { useEffect as useEffect7, useCallback as useCallback4, useReducer as useReducer3, useRef as useRef6 } from "react";
14286
+ import { useEffect as useEffect7, useCallback as useCallback4, useReducer as useReducer5, useRef as useRef6 } from "react";
14125
14287
 
14126
14288
  // ../blocks/src/system/runtime/hooks/usePolling.state.ts
14127
14289
  function createInitialPollingState() {
@@ -14195,7 +14357,7 @@ function pollingReducer(state, action) {
14195
14357
  var DEFAULT_MAX_ATTEMPTS = 10;
14196
14358
  var DEFAULT_POLL_INTERVAL = 1e3;
14197
14359
  function usePolling(config) {
14198
- const [state, dispatch] = useReducer3(
14360
+ const [state, dispatch] = useReducer5(
14199
14361
  pollingReducer,
14200
14362
  void 0,
14201
14363
  createInitialPollingState
@@ -15422,7 +15584,7 @@ var BookingFormClient = ({
15422
15584
  const initialResourceId = render.hydration.resourceId ?? void 0;
15423
15585
  const isPortalRebook = render.hydration.rebookContext?.kind === "portal_rebook";
15424
15586
  const hasLoggedRebookCompletionRef = useRef7(false);
15425
- const [redirectState] = useState5(
15587
+ const [redirectState] = useState3(
15426
15588
  () => getBookingRedirectStateFromLocation(getBookingRedirectLocationSnapshot())
15427
15589
  );
15428
15590
  const showSpamProtection = render.hydration.spamProtectionEnabled ?? isSpamProtectionEnabled();
@@ -16072,7 +16234,7 @@ function findSelectedTicketType(input) {
16072
16234
  }
16073
16235
 
16074
16236
  // ../blocks/src/system/runtime/nodes/event-registration/hooks.ts
16075
- import { useState as useState6, useEffect as useEffect8, useCallback as useCallback5, useRef as useRef8, useReducer as useReducer4 } from "react";
16237
+ import { useState as useState4, useEffect as useEffect8, useCallback as useCallback5, useRef as useRef8, useReducer as useReducer6 } from "react";
16076
16238
 
16077
16239
  // ../blocks/src/system/runtime/nodes/event-registration/hooks.state.ts
16078
16240
  var initialEligibilityLookupState = {
@@ -16132,8 +16294,8 @@ function existingRegistrationLookupReducer(state, action) {
16132
16294
  // ../blocks/src/system/runtime/nodes/event-registration/hooks.ts
16133
16295
  function usePortalAuth() {
16134
16296
  const api = useBlockApi();
16135
- const [authState, setAuthState] = useState6("checking");
16136
- const [profile, setProfile] = useState6(null);
16297
+ const [authState, setAuthState] = useState4("checking");
16298
+ const [profile, setProfile] = useState4(null);
16137
16299
  useEffect8(() => {
16138
16300
  let cancelled = false;
16139
16301
  async function checkPortalAuth() {
@@ -16180,7 +16342,7 @@ function usePortalAuth() {
16180
16342
  }
16181
16343
  function useEligibility(params) {
16182
16344
  const api = useBlockApi();
16183
- const [state, dispatch] = useReducer4(
16345
+ const [state, dispatch] = useReducer6(
16184
16346
  eligibilityLookupReducer,
16185
16347
  initialEligibilityLookupState
16186
16348
  );
@@ -16239,7 +16401,7 @@ function useExistingEventRegistration({
16239
16401
  occurrenceId
16240
16402
  }) {
16241
16403
  const api = useBlockApi();
16242
- const [state, dispatch] = useReducer4(
16404
+ const [state, dispatch] = useReducer6(
16243
16405
  existingRegistrationLookupReducer,
16244
16406
  initialExistingRegistrationLookupState
16245
16407
  );
@@ -16446,7 +16608,7 @@ function cleanupStaleRegistrations() {
16446
16608
  }
16447
16609
 
16448
16610
  // ../blocks/src/system/runtime/nodes/event-registration/useEventRegistrationWizard.ts
16449
- import { useCallback as useCallback6, useEffect as useEffect11, useMemo as useMemo6, useReducer as useReducer5, useState as useState8 } from "react";
16611
+ import { useCallback as useCallback6, useEffect as useEffect11, useMemo as useMemo6, useReducer as useReducer8, useState as useState5 } from "react";
16450
16612
 
16451
16613
  // ../blocks/src/system/runtime/nodes/event-registration/validation.ts
16452
16614
  function validateFormData2(formData) {
@@ -16463,7 +16625,55 @@ function validateFormData2(formData) {
16463
16625
  }
16464
16626
 
16465
16627
  // ../blocks/src/system/runtime/shared/useWaitlistClaim.ts
16466
- import { useEffect as useEffect9, useState as useState7, useSyncExternalStore } from "react";
16628
+ import { useEffect as useEffect9, useReducer as useReducer7, useSyncExternalStore } from "react";
16629
+
16630
+ // ../blocks/src/system/runtime/shared/useWaitlistClaim.state.ts
16631
+ var DEFAULT_WAITLIST_CLAIM_ERROR = "Failed to resolve waitlist claim";
16632
+ function createInitialWaitlistClaimState(hasToken) {
16633
+ return hasToken ? { kind: "resolving" } : { kind: "idle" };
16634
+ }
16635
+ function waitlistClaimReducer(_state, action) {
16636
+ switch (action.type) {
16637
+ case "cleared":
16638
+ return { kind: "idle" };
16639
+ case "started":
16640
+ return { kind: "resolving" };
16641
+ case "resolved":
16642
+ return { kind: "resolved", claim: action.claim };
16643
+ case "failed":
16644
+ return action.failure;
16645
+ }
16646
+ }
16647
+ function toWaitlistClaimResolveFailure(error) {
16648
+ const message = error instanceof Error ? error.message : DEFAULT_WAITLIST_CLAIM_ERROR;
16649
+ if (isUnauthorizedBlockApiError(error)) {
16650
+ return { kind: "portal-login-required", message };
16651
+ }
16652
+ return { kind: "error", message };
16653
+ }
16654
+ function isUnauthorizedBlockApiError(error) {
16655
+ return error instanceof Error && error.name === "BlockApiError" && hasStatus(error) && error.status === 401;
16656
+ }
16657
+ function hasStatus(value) {
16658
+ return typeof value === "object" && value !== null && "status" in value;
16659
+ }
16660
+ function getWaitlistClaim(state) {
16661
+ return state.kind === "resolved" ? state.claim : null;
16662
+ }
16663
+ function getWaitlistClaimError(state) {
16664
+ return state.kind === "error" ? state.message : null;
16665
+ }
16666
+ function getWaitlistClaimLoginMessage(state) {
16667
+ return state.kind === "portal-login-required" ? state.message : null;
16668
+ }
16669
+ function requiresWaitlistClaimPortalLogin(state) {
16670
+ return state.kind === "portal-login-required";
16671
+ }
16672
+ function isWaitlistClaimLoading(state) {
16673
+ return state.kind === "resolving";
16674
+ }
16675
+
16676
+ // ../blocks/src/system/runtime/shared/useWaitlistClaim.ts
16467
16677
  var WAITLIST_CLAIM_LOCATION_EVENT = "riverbank:waitlist-claim-location-change";
16468
16678
  var historyPatched = false;
16469
16679
  function emitWaitlistClaimLocationChange() {
@@ -16521,46 +16731,29 @@ function useWaitlistClaim() {
16521
16731
  getWaitlistClaimTokenSnapshot,
16522
16732
  () => null
16523
16733
  );
16524
- const [claim, setClaim] = useState7(null);
16525
- const [error, setError] = useState7(null);
16526
- const [loginMessage, setLoginMessage] = useState7(null);
16527
- const [requiresPortalLogin, setRequiresPortalLogin] = useState7(false);
16528
- const [isLoading, setIsLoading] = useState7(() => Boolean(token));
16734
+ const [state, dispatch] = useReducer7(
16735
+ waitlistClaimReducer,
16736
+ Boolean(token),
16737
+ createInitialWaitlistClaimState
16738
+ );
16529
16739
  useEffect9(() => {
16530
16740
  let cancelled = false;
16531
16741
  async function resolveClaim() {
16532
16742
  if (!token) {
16533
- setClaim(null);
16534
- setError(null);
16535
- setLoginMessage(null);
16536
- setRequiresPortalLogin(false);
16537
- setIsLoading(false);
16743
+ dispatch({ type: "cleared" });
16538
16744
  return;
16539
16745
  }
16540
- setIsLoading(true);
16541
- setClaim(null);
16542
- setError(null);
16543
- setLoginMessage(null);
16544
- setRequiresPortalLogin(false);
16746
+ dispatch({ type: "started" });
16545
16747
  try {
16546
16748
  const result = await api.resolveWaitlistClaim({ claimToken: token });
16547
16749
  if (cancelled) return;
16548
- setClaim(result);
16750
+ dispatch({ type: "resolved", claim: result });
16549
16751
  } catch (claimError) {
16550
16752
  if (cancelled) return;
16551
- const message = claimError instanceof Error ? claimError.message : "Failed to resolve waitlist claim";
16552
- setClaim(null);
16553
- if (claimError instanceof BlockApiError && claimError.status === 401) {
16554
- setRequiresPortalLogin(true);
16555
- setLoginMessage(message);
16556
- setError(null);
16557
- } else {
16558
- setError(message);
16559
- }
16560
- } finally {
16561
- if (!cancelled) {
16562
- setIsLoading(false);
16563
- }
16753
+ dispatch({
16754
+ type: "failed",
16755
+ failure: toWaitlistClaimResolveFailure(claimError)
16756
+ });
16564
16757
  }
16565
16758
  }
16566
16759
  void resolveClaim();
@@ -16570,11 +16763,11 @@ function useWaitlistClaim() {
16570
16763
  }, [api, token]);
16571
16764
  return {
16572
16765
  token,
16573
- claim,
16574
- error,
16575
- loginMessage,
16576
- requiresPortalLogin,
16577
- isLoading
16766
+ claim: getWaitlistClaim(state),
16767
+ error: getWaitlistClaimError(state),
16768
+ loginMessage: getWaitlistClaimLoginMessage(state),
16769
+ requiresPortalLogin: requiresWaitlistClaimPortalLogin(state),
16770
+ isLoading: isWaitlistClaimLoading(state)
16578
16771
  };
16579
16772
  }
16580
16773
 
@@ -16862,7 +17055,7 @@ function useEventRegistrationWizard(options) {
16862
17055
  [scopedEvents, options.occurrenceContext]
16863
17056
  );
16864
17057
  const hasPreSelectedContext = !!(options.occurrenceContext || preSelectedEvent);
16865
- const [flowState, dispatchFlow] = useReducer5(
17058
+ const [flowState, dispatchFlow] = useReducer8(
16866
17059
  registrationFlowReducer,
16867
17060
  hasPreSelectedContext,
16868
17061
  createInitialRegistrationFlowState
@@ -16870,24 +17063,24 @@ function useEventRegistrationWizard(options) {
16870
17063
  const step = flowState.step;
16871
17064
  const ticketsCount = flowState.ticketsCount;
16872
17065
  const paymentSelection = flowState.paymentSelection;
16873
- const [selectedEvent, setSelectedEvent] = useState8(preSelectedEvent ?? null);
16874
- const [formData, setFormData] = useState8({ name: "", email: "", phone: "", notes: "" });
16875
- const [errors, setErrors] = useState8({});
16876
- const [guests, setGuests] = useState8([]);
16877
- const [guestErrors, setGuestErrors] = useState8({});
16878
- const [guestSectionShake, setGuestSectionShake] = useState8(false);
16879
- const [selectedAttendanceMode, setSelectedAttendanceMode] = useState8(
17066
+ const [selectedEvent, setSelectedEvent] = useState5(preSelectedEvent ?? null);
17067
+ const [formData, setFormData] = useState5({ name: "", email: "", phone: "", notes: "" });
17068
+ const [errors, setErrors] = useState5({});
17069
+ const [guests, setGuests] = useState5([]);
17070
+ const [guestErrors, setGuestErrors] = useState5({});
17071
+ const [guestSectionShake, setGuestSectionShake] = useState5(false);
17072
+ const [selectedAttendanceMode, setSelectedAttendanceMode] = useState5(
16880
17073
  preSelectedEvent?.deliveryMode === "online" ? "online" : preSelectedEvent?.deliveryMode === "in_person" ? "in_person" : null
16881
17074
  );
16882
- const [selectedTicketTypeId, setSelectedTicketTypeId] = useState8(null);
16883
- const [registrationResult, setRegistrationResult] = useState8(null);
16884
- const [errorMessage, setErrorMessage] = useState8("");
16885
- const [altchaSolution, setAltchaSolution] = useState8(null);
17075
+ const [selectedTicketTypeId, setSelectedTicketTypeId] = useState5(null);
17076
+ const [registrationResult, setRegistrationResult] = useState5(null);
17077
+ const [errorMessage, setErrorMessage] = useState5("");
17078
+ const [altchaSolution, setAltchaSolution] = useState5(null);
16886
17079
  const { authState: portalAuthState, profile: portalProfile } = usePortalAuth();
16887
17080
  const waitlistClaim = useWaitlistClaim();
16888
- const [showMagicLinkModal, setShowMagicLinkModal] = useState8(false);
16889
- const [pendingAttendeeId, setPendingAttendeeId] = useState8(null);
16890
- const [paymentStepState, setPaymentStepState] = useState8({
17081
+ const [showMagicLinkModal, setShowMagicLinkModal] = useState5(false);
17082
+ const [pendingAttendeeId, setPendingAttendeeId] = useState5(null);
17083
+ const [paymentStepState, setPaymentStepState] = useState5({
16891
17084
  status: "loading",
16892
17085
  canContinue: false,
16893
17086
  buttonText: "Continue",
@@ -18361,63 +18554,140 @@ function resolvePaymentModel(wizard) {
18361
18554
  }
18362
18555
 
18363
18556
  // ../blocks/src/system/runtime/hooks/useBookingFormConfig.ts
18364
- import { useState as useState9, useEffect as useEffect12 } from "react";
18557
+ import { useEffect as useEffect12, useReducer as useReducer9 } from "react";
18558
+
18559
+ // ../blocks/src/system/runtime/hooks/useBookingFormConfig.state.ts
18560
+ var EMPTY_SNAPSHOT = Object.freeze({
18561
+ formConfig: null,
18562
+ services: []
18563
+ });
18564
+ function createInitialBookingFormConfigState() {
18565
+ return {
18566
+ tag: "loading",
18567
+ previous: EMPTY_SNAPSHOT
18568
+ };
18569
+ }
18570
+ function bookingFormConfigReducer(state, action) {
18571
+ switch (action.type) {
18572
+ case "load-started":
18573
+ return {
18574
+ tag: "loading",
18575
+ previous: toBookingFormConfigSnapshot(state)
18576
+ };
18577
+ case "form-loaded": {
18578
+ const previous = toBookingFormConfigSnapshot(state);
18579
+ return {
18580
+ tag: "loading",
18581
+ previous: {
18582
+ formConfig: action.formConfig,
18583
+ services: previous.formConfig?.id === action.formConfig.id ? previous.services : []
18584
+ }
18585
+ };
18586
+ }
18587
+ case "load-succeeded":
18588
+ return {
18589
+ tag: "loaded",
18590
+ formConfig: action.formConfig,
18591
+ services: action.services
18592
+ };
18593
+ case "services-load-failed": {
18594
+ const previous = toBookingFormConfigSnapshot(state);
18595
+ return previous.formConfig ? {
18596
+ tag: "loaded",
18597
+ formConfig: previous.formConfig,
18598
+ services: previous.services
18599
+ } : {
18600
+ tag: "error",
18601
+ message: action.message,
18602
+ previous
18603
+ };
18604
+ }
18605
+ case "load-failed":
18606
+ return {
18607
+ tag: "error",
18608
+ message: action.message,
18609
+ previous: toBookingFormConfigSnapshot(state)
18610
+ };
18611
+ default:
18612
+ return assertNever11(action);
18613
+ }
18614
+ }
18615
+ function selectBookingFormConfig(state) {
18616
+ return toBookingFormConfigSnapshot(state).formConfig;
18617
+ }
18618
+ function selectBookingFormServices(state) {
18619
+ return toBookingFormConfigSnapshot(state).services;
18620
+ }
18621
+ function selectBookingFormConfigIsLoading(state) {
18622
+ return state.tag === "loading";
18623
+ }
18624
+ function selectBookingFormConfigError(state) {
18625
+ return state.tag === "error" ? state.message : null;
18626
+ }
18627
+ function toBookingFormConfigSnapshot(state) {
18628
+ switch (state.tag) {
18629
+ case "loading":
18630
+ case "error":
18631
+ return state.previous;
18632
+ case "loaded":
18633
+ return {
18634
+ formConfig: state.formConfig,
18635
+ services: state.services
18636
+ };
18637
+ default:
18638
+ return assertNever11(state);
18639
+ }
18640
+ }
18641
+
18642
+ // ../blocks/src/system/runtime/hooks/useBookingFormConfig.ts
18365
18643
  function useBookingFormConfig(siteId, formId) {
18366
18644
  const api = useBlockApi();
18367
- const [formConfig, setFormConfig] = useState9(null);
18368
- const [services, setServices] = useState9([]);
18369
- const [isLoading, setIsLoading] = useState9(true);
18370
- const [error, setError] = useState9(null);
18645
+ const [state, dispatch] = useReducer9(
18646
+ bookingFormConfigReducer,
18647
+ void 0,
18648
+ createInitialBookingFormConfigState
18649
+ );
18650
+ const formConfig = selectBookingFormConfig(state);
18651
+ const services = selectBookingFormServices(state);
18371
18652
  useEffect12(() => {
18372
18653
  let mounted = true;
18373
18654
  async function loadFormAndServices() {
18655
+ dispatch({ type: "load-started" });
18374
18656
  try {
18375
- setIsLoading(true);
18376
- setError(null);
18377
18657
  const formResponse = await api.getForm(formId, siteId);
18378
18658
  if (!mounted) return;
18379
- const rawData = formResponse.form;
18380
- const normalizedForm = {
18381
- id: rawData.id,
18382
- name: rawData.name,
18383
- slug: rawData.slug,
18384
- settings: rawData.settingsJson ?? rawData.settings,
18385
- schema: rawData.schemaJson ?? rawData.schema
18386
- };
18387
- setFormConfig(normalizedForm);
18388
- if (!normalizedForm.settings?.serviceId && !normalizedForm.settings?.serviceIds) {
18389
- try {
18390
- const servicesData = await api.getBookingServices();
18391
- if (mounted) {
18392
- setServices(servicesData.services || []);
18393
- }
18394
- } catch {
18395
- }
18396
- } else if (normalizedForm.settings?.serviceIds && normalizedForm.settings.serviceIds.length > 0) {
18397
- try {
18398
- const servicesData = await api.getBookingServices({ ids: normalizedForm.settings.serviceIds });
18399
- if (mounted) {
18400
- setServices(servicesData.services || []);
18401
- }
18402
- } catch {
18403
- }
18404
- } else if (normalizedForm.settings?.serviceId) {
18405
- try {
18406
- const serviceData = await api.getBookingService(normalizedForm.settings.serviceId);
18407
- if (mounted) {
18408
- setServices([serviceData.service]);
18409
- }
18410
- } catch {
18659
+ const normalizedForm = normalizeBookingFormConfig(formResponse.form);
18660
+ if (!normalizedForm) {
18661
+ throw new Error("Invalid booking form response.");
18662
+ }
18663
+ dispatch({
18664
+ type: "form-loaded",
18665
+ formConfig: normalizedForm
18666
+ });
18667
+ try {
18668
+ const services2 = await loadBookingFormServices(api, normalizedForm);
18669
+ if (!mounted) return;
18670
+ dispatch({
18671
+ type: "load-succeeded",
18672
+ formConfig: normalizedForm,
18673
+ services: services2
18674
+ });
18675
+ } catch (err3) {
18676
+ console.warn("Failed to load booking form services:", err3);
18677
+ if (mounted) {
18678
+ dispatch({
18679
+ type: "services-load-failed",
18680
+ message: "Failed to load booking services."
18681
+ });
18411
18682
  }
18412
18683
  }
18413
18684
  } catch (err3) {
18414
18685
  console.error("Failed to load form:", err3);
18415
18686
  if (mounted) {
18416
- setError("Failed to load booking form. Please try again later.");
18417
- }
18418
- } finally {
18419
- if (mounted) {
18420
- setIsLoading(false);
18687
+ dispatch({
18688
+ type: "load-failed",
18689
+ message: "Failed to load booking form. Please try again later."
18690
+ });
18421
18691
  }
18422
18692
  }
18423
18693
  }
@@ -18426,7 +18696,27 @@ function useBookingFormConfig(siteId, formId) {
18426
18696
  mounted = false;
18427
18697
  };
18428
18698
  }, [siteId, formId, api]);
18429
- return { formConfig, services, isLoading, error };
18699
+ return {
18700
+ formConfig,
18701
+ services,
18702
+ isLoading: selectBookingFormConfigIsLoading(state),
18703
+ error: selectBookingFormConfigError(state)
18704
+ };
18705
+ }
18706
+ async function loadBookingFormServices(api, formConfig) {
18707
+ if (!formConfig.settings?.serviceId && !formConfig.settings?.serviceIds) {
18708
+ const servicesData = await api.getBookingServices();
18709
+ return normalizeBookingServices(servicesData.services);
18710
+ }
18711
+ if (formConfig.settings?.serviceIds && formConfig.settings.serviceIds.length > 0) {
18712
+ const servicesData = await api.getBookingServices({ ids: [...formConfig.settings.serviceIds] });
18713
+ return normalizeBookingServices(servicesData.services);
18714
+ }
18715
+ if (formConfig.settings?.serviceId) {
18716
+ const serviceData = await api.getBookingService(formConfig.settings.serviceId);
18717
+ return normalizeBookingServices([serviceData.service]);
18718
+ }
18719
+ return [];
18430
18720
  }
18431
18721
 
18432
18722
  // src/bookings/index.ts