@riverbankcms/sdk 0.135.1 → 0.136.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 (152) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/README.md +4 -8
  3. package/dist/{PreviewEditorSidebar-D4p_5TdY.mjs → PreviewEditorSidebar-BU5ZlhQR.mjs} +4 -4
  4. package/dist/{PreviewEditorUI-D0cRoTX1.mjs → PreviewEditorUI-9XkHL-bC.mjs} +3 -3
  5. package/dist/{PreviewQueryProvider-DcgaESkm.mjs → PreviewQueryProvider-wbEpXryy.mjs} +1 -1
  6. package/dist/{SdkPreviewModeRuntime-BKLtM3Nz.mjs → SdkPreviewModeRuntime-CnWmj-2B.mjs} +50 -99
  7. package/dist/{SiteChromeCustomizeContext-61X2m7QV.mjs → SiteChromeCustomizeContext-B6d5zkog.mjs} +2299 -1149
  8. package/dist/_dts/ai/src/contracts/proposals.d.ts +8 -554
  9. package/dist/_dts/ai/src/contracts/siteStyleProposalSchemas.d.ts +401 -2312
  10. package/dist/_dts/api/src/contentRuntime.d.ts +6 -0
  11. package/dist/_dts/api/src/endpoints.d.ts +7 -0
  12. package/dist/_dts/api/src/index.d.ts +1 -0
  13. package/dist/_dts/api/src/publicEventEndpointDefinitions.d.ts +7 -0
  14. package/dist/_dts/api/src/publicExperience/eventEndpoints.d.ts +26 -0
  15. package/dist/_dts/api/src/sdkBlockContentAdmission.d.ts +5 -0
  16. package/dist/_dts/api/src/sdkThemeWire.d.ts +6 -432
  17. package/dist/_dts/block-form/src/blockDraftSaveability.d.ts +2 -3
  18. package/dist/_dts/block-form/src/utils/slug.d.ts +6 -0
  19. package/dist/_dts/blocks/src/PageRenderer.d.ts +12 -6
  20. package/dist/_dts/blocks/src/contracts/proof-block-islands.d.ts +48 -0
  21. package/dist/_dts/blocks/src/definitions.d.ts +14 -0
  22. package/dist/_dts/blocks/src/index.d.ts +4 -3
  23. package/dist/_dts/blocks/src/pageRenderAdmission.d.ts +40 -0
  24. package/dist/_dts/blocks/src/server.d.ts +2 -2
  25. package/dist/_dts/blocks/src/system/data/index.d.ts +2 -0
  26. package/dist/_dts/blocks/src/system/data/publicLoaderCachePolicy.d.ts +78 -0
  27. package/dist/_dts/blocks/src/system/manifest/fieldValidation/index.d.ts +2 -18
  28. package/dist/_dts/blocks/src/system/manifest/validation.d.ts +103 -16
  29. package/dist/_dts/blocks/src/system/node/validation-constants.d.ts +1 -1
  30. package/dist/_dts/blocks/src/system/runtime/api/client.d.ts +2 -1
  31. package/dist/_dts/blocks/src/system/runtime/api/endpoints.d.ts +8 -0
  32. package/dist/_dts/blocks/src/system/runtime/api/index.d.ts +1 -1
  33. package/dist/_dts/blocks/src/system/runtime/api/types/events.d.ts +19 -0
  34. package/dist/_dts/blocks/src/system/runtime/components/registry.client.d.ts +52 -0
  35. package/dist/_dts/blocks/src/system/runtime/components/runtime-backed-blocks.d.ts +24 -0
  36. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.d.ts +44 -18
  37. package/dist/_dts/blocks/src/system/runtime/hooks/useCalendarEvents.state.d.ts +20 -3
  38. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/VerifyingTimeoutStep.d.ts +3 -1
  39. package/dist/_dts/blocks/src/system/runtime/nodes/event-registration/useEventRegistrationStripeReturn.d.ts +1 -0
  40. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.client.d.ts +2 -2
  41. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCalendar.interactive.d.ts +40 -0
  42. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.client.d.ts +2 -0
  43. package/dist/_dts/blocks/src/system/runtime/nodes/events/EventCombined.interactive.d.ts +43 -0
  44. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/CalendarDayCell.d.ts +3 -1
  45. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/CalendarNavigationChevron.d.ts +4 -0
  46. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/DayEventsModal.d.ts +2 -1
  47. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/EventModalContext.d.ts +3 -2
  48. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekAgendaView.d.ts +3 -0
  49. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekBoardView.d.ts +31 -3
  50. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/WeekTimetableView.d.ts +3 -1
  51. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/eventCollectionContract.d.ts +9 -1
  52. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/timetableModel.d.ts +4 -3
  53. package/dist/_dts/blocks/src/system/runtime/nodes/events/shared/utils.d.ts +3 -3
  54. package/dist/_dts/blocks/src/system/transforms/registry/layout.d.ts +0 -1
  55. package/dist/_dts/calendar/src/grid.d.ts +24 -66
  56. package/dist/_dts/calendar/src/index.d.ts +2 -2
  57. package/dist/_dts/calendar/src/timetable.d.ts +5 -9
  58. package/dist/_dts/commerce/src/purchase/allocation.d.ts +11 -0
  59. package/dist/_dts/commerce/src/purchase/index.d.ts +2 -0
  60. package/dist/_dts/commerce/src/purchase/settlement.d.ts +33 -0
  61. package/dist/_dts/commerce/src/purchase/stripeCheckoutReturnUrl.d.ts +8 -0
  62. package/dist/_dts/content-model/src/templates/defaults.d.ts +6 -0
  63. package/dist/_dts/core/src/slug.d.ts +20 -5
  64. package/dist/_dts/preview-next/src/client/blocks/EditablePageRenderer.d.ts +1 -1
  65. package/dist/_dts/preview-next/src/client/preview/headerInteractionPaletteSurfaceState.d.ts +2 -1
  66. package/dist/_dts/sdk/src/client/publicLoaderCacheAccess.d.ts +6 -0
  67. package/dist/_dts/sdk/src/public-api/contracts.d.ts +5 -1
  68. package/dist/_dts/sdk/src/rendering/blocks-page-renderer.d.ts +10 -6
  69. package/dist/_dts/sdk/src/rendering/components/Block.shared.d.ts +0 -1
  70. package/dist/_dts/sdk/src/rendering/components/pageShared.d.ts +4 -4
  71. package/dist/_dts/sdk/src/rendering/helpers/footerPageOutline.d.ts +3 -0
  72. package/dist/_dts/sdk/src/rendering/helpers/loadContent.d.ts +3 -0
  73. package/dist/_dts/sdk/src/rendering/helpers/loadPage.d.ts +1 -1
  74. package/dist/_dts/sdk/src/rendering/helpers/pageRuntimeSupport.d.ts +17 -0
  75. package/dist/_dts/sdk/src/rendering/helpers/templateContent.d.ts +9 -3
  76. package/dist/_dts/sdk/src/rendering/hooks/usePage.d.ts +1 -1
  77. package/dist/_dts/sdk/src/rendering/index.d.ts +2 -2
  78. package/dist/_dts/sdk/src/rendering/overrideResolution.d.ts +7 -4
  79. package/dist/_dts/sdk/src/version.d.ts +1 -1
  80. package/dist/_dts/theme-core/src/cards/types.d.ts +8 -8
  81. package/dist/_dts/theme-core/src/data.d.ts +12 -0
  82. package/dist/_dts/theme-core/src/generated/containerResponsiveThemeCss.d.ts +1 -1
  83. package/dist/_dts/theme-core/src/header/legacyHeaderVariant.d.ts +2 -6
  84. package/dist/_dts/theme-core/src/mock-themes/all.d.ts +6 -807
  85. package/dist/_dts/theme-core/src/schema.d.ts +452 -1278
  86. package/dist/_dts/theme-core/src/site-styles/curatedSiteStyles.d.ts +213 -1
  87. package/dist/_dts/theme-core/src/site-styles/headerLayoutCatalog.d.ts +0 -29
  88. package/dist/_dts/theme-core/src/site-styles/headerLayoutStyles.d.ts +10 -0
  89. package/dist/_dts/theme-core/src/site-styles/headerLayoutTypes.d.ts +8 -5
  90. package/dist/_dts/theme-core/src/site-styles/headerOpeningForeground.d.ts +4 -4
  91. package/dist/_dts/theme-core/src/site-styles/headerStyleCompiler.d.ts +16 -2
  92. package/dist/_dts/theme-core/src/site-styles/headerStyleDefaults.d.ts +465 -0
  93. package/dist/_dts/theme-core/src/site-styles/headerStyleRecipe.d.ts +161 -0
  94. package/dist/client/{BookingConsentAgreement-Bz9znbpn.mjs → BookingConsentAgreement-DCch21a6.mjs} +2 -2
  95. package/dist/client/{DiscountCodeDisclosure-35Ru8yB9.mjs → DiscountCodeDisclosure-DIj1T59K.mjs} +1 -1
  96. package/dist/client/{EventCombined.client-BKB0ZxRR.mjs → EventCombined.client-BWVNlXTx.mjs} +226 -206
  97. package/dist/client/{EventListing.client-Dx8I21ok.mjs → EventListing.client-DVFCDe3i.mjs} +2 -2
  98. package/dist/client/{LeafletStaticMap-CEWx-Bhe.mjs → LeafletStaticMap-BY5mIHw9.mjs} +1 -1
  99. package/dist/client/{accordion-KIDsKTwS.mjs → accordion-CK29E8rG.mjs} +1 -1
  100. package/dist/client/{bookingForm-D96Rmp-5.mjs → bookingForm-DFvnet-N.mjs} +5 -5
  101. package/dist/client/bookings.mjs +86 -47
  102. package/dist/client/{carousel-YwUgyL66.mjs → carousel-BVU5NQlb.mjs} +1 -1
  103. package/dist/client/{cart-BbwuNrUT.mjs → cart-BNItcZVa.mjs} +3 -3
  104. package/dist/client/{checkout-hp1ucmEY.mjs → checkout-Bu6iCdkP.mjs} +3 -3
  105. package/dist/client/client.mjs +1950 -1031
  106. package/dist/client/{context-DljQn8L5.mjs → context-BImarOAq.mjs} +12 -0
  107. package/dist/client/{eventCalendar-DU4iNLpo.mjs → eventCalendar-DS2h-UXD.mjs} +256 -114
  108. package/dist/client/{eventCombined-CZuupW8m.mjs → eventCombined-Drt4Oq9p.mjs} +3 -3
  109. package/dist/client/{eventDetails-DPQWwCIi.mjs → eventDetails-Bl2vWgTX.mjs} +4 -3
  110. package/dist/client/{eventListing-C7oMidwS.mjs → eventListing-CS7PHY7v.mjs} +3 -3
  111. package/dist/client/{eventRegistration-zEiunlUs.mjs → eventRegistration-D-j8eNy2.mjs} +85 -41
  112. package/dist/client/{form-D2KIyCVJ.mjs → form-RMpoLTyr.mjs} +2 -2
  113. package/dist/client/{headerSection-CK5uChUK.mjs → headerSection-BYE3Lb3k.mjs} +2 -2
  114. package/dist/client/hooks.mjs +2225 -276
  115. package/dist/client/{locationMap-DLQNH1ln.mjs → locationMap-BxSr7Kkh.mjs} +2 -2
  116. package/dist/client/{newsletterForm-ZuhIG7fZ.mjs → newsletterForm-DerbXwFC.mjs} +2 -2
  117. package/dist/client/{productDetail-7hIcGeae.mjs → productDetail-4SZCLhAf.mjs} +3 -3
  118. package/dist/client/{productList-T4Cii1ot.mjs → productList-D7AP4GNq.mjs} +3 -3
  119. package/dist/client/{propsDecoder-mB0aC_Fi.mjs → propsDecoder-pzBeCh14.mjs} +94 -24
  120. package/dist/client/rendering/client.mjs +758 -464
  121. package/dist/client/rendering/islands.mjs +17 -17
  122. package/dist/client/rendering.mjs +2126 -1244
  123. package/dist/client/{scrollToBlock-Du5mHgvL.mjs → scrollToBlock-CduAKf8T.mjs} +1 -1
  124. package/dist/client/{shop-B5zAcKZn.mjs → shop-Cp5p_kGe.mjs} +6 -6
  125. package/dist/client/{shop-commerce-BKBZB6l5.mjs → shop-commerce-DicXYaYX.mjs} +5 -5
  126. package/dist/client/{shop-commerce-store-Cq4qlNtQ.mjs → shop-commerce-store-CGWnpY4K.mjs} +1 -1
  127. package/dist/client/{shopShared-DYGzEs9D.mjs → shopShared-BDf9ljkm.mjs} +3 -3
  128. package/dist/client/{useEventFilters-Bphkda8m.mjs → useEventFilters-DeeyGYuk.mjs} +3 -3
  129. package/dist/preview-next/before-render.mjs +7 -0
  130. package/dist/preview-next/client/runtime.mjs +4 -4
  131. package/dist/preview-next/keepAlive.mjs +7 -0
  132. package/dist/preview-next/middleware.mjs +7 -0
  133. package/dist/{previewAuthStore-C7ksxt5b.mjs → previewAuthStore-DbqBol0V.mjs} +7 -0
  134. package/dist/{sdk-runtime-BbIC8G4J.mjs → sdk-runtime-19MO27F0.mjs} +2 -2
  135. package/dist/{separator-CadhAtI7.mjs → separator-DaPLtJ1f.mjs} +1 -1
  136. package/dist/server/components.mjs +1527 -893
  137. package/dist/server/config-validation.mjs +65 -113
  138. package/dist/server/config.mjs +65 -113
  139. package/dist/server/data.mjs +65 -112
  140. package/dist/server/index.mjs +122 -4
  141. package/dist/server/manifest.mjs +0 -1
  142. package/dist/server/next.mjs +1432 -708
  143. package/dist/server/page-converter.mjs +58 -91
  144. package/dist/server/prebuild.mjs +1 -1
  145. package/dist/server/rendering/server.mjs +1682 -915
  146. package/dist/server/rendering.mjs +1694 -1020
  147. package/dist/server/routing.mjs +3230 -1843
  148. package/dist/server/server.mjs +21710 -19779
  149. package/dist/server/theme-bridge.mjs +656 -264
  150. package/dist/server/theme.mjs +2 -17
  151. package/dist/styles/index.css +609 -181
  152. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  "use client";
2
2
  import { D as clsx } from "./colorStyles-CrxJrPjJ.mjs";
3
- import { At as assertNever, B as formatEventPrice, G as getContainerClass, H as formatEventTeacherLine, J as resolveEventLinkProps, K as groupEventsByDate, L as formatDate, M as buildEventRuntimeFilters, N as getEventRuntimeFiltersKey, U as formatTime, W as getCardOrientation, X as getEventAvailability, st as themeButtonClassName } from "./propsDecoder-mB0aC_Fi.mjs";
4
- import { a as EventCardClient, i as EventPaginatedListView, n as useEventPagination, o as EventFilters, r as toError, t as useEventFilters } from "./useEventFilters-Bphkda8m.mjs";
5
- import { n as useBlockApi } from "./context-DljQn8L5.mjs";
3
+ import { At as assertNever, B as formatEventPrice, G as getContainerClass, Gt as getLocalScheduleDate, H as formatEventTeacherLine, J as resolveEventLinkProps, K as groupEventsByDate, L as formatDate, M as buildEventRuntimeFilters, N as getEventRuntimeFiltersKey, Rt as buildBookingUtcDateWindow, U as formatTime, Ut as formatLocalScheduleDate, W as getCardOrientation, X as getEventAvailability, st as themeButtonClassName } from "./propsDecoder-pzBeCh14.mjs";
4
+ import { a as EventCardClient, i as EventPaginatedListView, n as useEventPagination, o as EventFilters, r as toError, t as useEventFilters } from "./useEventFilters-DeeyGYuk.mjs";
5
+ import { n as useBlockApi } from "./context-BImarOAq.mjs";
6
6
  import { t as createBodyThemePortalRoot } from "./themePortalRoot-AGs4cE7t.mjs";
7
7
  import { t as ModalShell } from "./ModalShell-CqkBvBIC.mjs";
8
8
  import React, { createContext, useCallback, useContext, useEffect, useId, useMemo, useReducer, useRef, useState } from "react";
@@ -31,111 +31,73 @@ const MONTH_NAMES = [
31
31
  "November",
32
32
  "December"
33
33
  ];
34
- /** Format a date as YYYY-MM-DD using the runtime's local timezone. */
35
34
  function formatDateKey(date) {
36
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
35
+ return `${String(date.year).padStart(4, "0")}-${String(date.month).padStart(2, "0")}-${String(date.day).padStart(2, "0")}`;
37
36
  }
38
- /**
39
- * True when `date` and `now` are the same local calendar day.
40
- * `now` defaults to `new Date()` so casual callers don't need to thread it,
41
- * but tests and snapshot-rendering should pass an explicit value.
42
- */
43
- function isToday(date, now = /* @__PURE__ */ new Date()) {
44
- return isSameLocalDay(date, now);
37
+ function isToday(date, today) {
38
+ return isSameCalendarDay(date, today);
45
39
  }
46
- /** True when two dates fall on the same local calendar day. */
47
- function isSameLocalDay(left, right) {
48
- return left.getFullYear() === right.getFullYear() && left.getMonth() === right.getMonth() && left.getDate() === right.getDate();
40
+ function isSameCalendarDay(left, right) {
41
+ return left.year === right.year && left.month === right.month && left.day === right.day;
49
42
  }
50
- /**
51
- * Add (or subtract) months to a date, clamping the day-of-month to the
52
- * target month's last day. Avoids JS Date overflow (Jan 29 + 1 month → Mar 1
53
- * in non-leap years).
54
- */
55
- function addMonths(date, months) {
56
- const year = date.getFullYear();
57
- const month = date.getMonth();
58
- const day = date.getDate();
59
- const hours = date.getHours();
60
- const minutes = date.getMinutes();
61
- const seconds = date.getSeconds();
62
- const ms = date.getMilliseconds();
63
- const base = new Date(year, month + months, 1, hours, minutes, seconds, ms);
64
- const lastDayOfTargetMonth = new Date(base.getFullYear(), base.getMonth() + 1, 0).getDate();
65
- base.setDate(Math.min(day, lastDayOfTargetMonth));
66
- return base;
43
+ function getStartOfMonth(date) {
44
+ return {
45
+ year: date.year,
46
+ month: date.month,
47
+ day: 1
48
+ };
67
49
  }
68
- /** Add (or subtract) days while preserving local time-of-day fields. */
69
- function addDays(date, days) {
70
- const result = new Date(date);
71
- result.setDate(result.getDate() + days);
72
- return result;
50
+ function getEndOfMonth(date) {
51
+ return addDays(addMonths(getStartOfMonth(date), 1), -1);
73
52
  }
74
- /** Shift a calendar anchor by the natural unit for a viewport kind. */
75
- function shiftCalendarAnchorDate(date, view, steps) {
76
- if (view === "week") return addDays(date, steps * 7);
77
- return addMonths(date, steps);
53
+ function addMonths(date, months) {
54
+ const target = new Date(Date.UTC(date.year, date.month - 1 + months, 1, 12));
55
+ const year = target.getUTCFullYear();
56
+ const month = target.getUTCMonth() + 1;
57
+ const lastDay = new Date(Date.UTC(year, month, 0, 12)).getUTCDate();
58
+ return {
59
+ year,
60
+ month,
61
+ day: Math.min(date.day, lastDay)
62
+ };
78
63
  }
79
- /**
80
- * Get an inclusive 3-month window around `date`, returned as ISO strings
81
- * with UTC midnight bounds. Suitable for prefetching event windows when
82
- * the consumer handles timezone conversion downstream.
83
- */
84
- function getThreeMonthRange(date) {
85
- const year = date.getFullYear();
86
- const month = date.getMonth();
87
- const prevStart = new Date(year, month - 1, 1);
88
- const nextEnd = new Date(year, month + 2, 0);
64
+ function addDays(date, days) {
65
+ const result = new Date(Date.UTC(date.year, date.month - 1, date.day + days, 12));
89
66
  return {
90
- from: `${formatDateKey(prevStart)}T00:00:00Z`,
91
- to: `${formatDateKey(nextEnd)}T23:59:59Z`
67
+ year: result.getUTCFullYear(),
68
+ month: result.getUTCMonth() + 1,
69
+ day: result.getUTCDate()
92
70
  };
93
71
  }
94
- /**
95
- * Build the calendar days for a month view. Returns 42 dates (6 rows × 7
96
- * days) including padding from prior/next months for a stable grid.
97
- */
72
+ function shiftCalendarAnchorDate(date, view, steps) {
73
+ return view === "week" ? addDays(date, steps * 7) : addMonths(date, steps);
74
+ }
98
75
  function getMonthCalendarDays(year, month, startOfWeek) {
99
- const firstDayOfMonth = new Date(year, month, 1);
100
- const lastDayOfMonth = new Date(year, month + 1, 0);
101
- let startOffset = firstDayOfMonth.getDay();
102
- if (startOfWeek === "monday") startOffset = startOffset === 0 ? 6 : startOffset - 1;
103
- const days = [];
104
- for (let i = startOffset - 1; i >= 0; i--) days.push(new Date(year, month, -i));
105
- for (let day = 1; day <= lastDayOfMonth.getDate(); day++) days.push(new Date(year, month, day));
106
- while (days.length < 42) {
107
- const nextDay = days.length - startOffset - lastDayOfMonth.getDate() + 1;
108
- days.push(new Date(year, month + 1, nextDay));
109
- }
110
- return days;
76
+ const firstDay = {
77
+ year,
78
+ month,
79
+ day: 1
80
+ };
81
+ const dayOfWeek = getDayOfWeek(firstDay);
82
+ const gridStart = addDays(firstDay, -(startOfWeek === "monday" ? dayOfWeek === 0 ? 6 : dayOfWeek - 1 : dayOfWeek));
83
+ return Array.from({ length: 42 }, (_, index) => addDays(gridStart, index));
111
84
  }
112
- /** Build the 7 dates of the week containing `baseDate`. */
113
85
  function getWeekCalendarDays(baseDate, startOfWeek) {
114
- const days = [];
115
- const dayOfWeek = baseDate.getDay();
116
- const daysToStart = startOfWeek === "monday" ? dayOfWeek === 0 ? 6 : dayOfWeek - 1 : dayOfWeek;
117
- const weekStart = new Date(baseDate);
118
- weekStart.setDate(baseDate.getDate() - daysToStart);
119
- for (let i = 0; i < 7; i++) {
120
- const date = new Date(weekStart);
121
- date.setDate(weekStart.getDate() + i);
122
- days.push(date);
123
- }
124
- return days;
86
+ const dayOfWeek = getDayOfWeek(baseDate);
87
+ const weekStart = addDays(baseDate, -(startOfWeek === "monday" ? dayOfWeek === 0 ? 6 : dayOfWeek - 1 : dayOfWeek));
88
+ return Array.from({ length: 7 }, (_, index) => addDays(weekStart, index));
89
+ }
90
+ function getDayOfWeek(date) {
91
+ return new Date(Date.UTC(date.year, date.month - 1, date.day, 12)).getUTCDay();
125
92
  }
126
- /** Build the 7 dates of the week containing `baseDate` as a fixed-width tuple. */
127
93
  function getWeekCalendarDayTuple(baseDate, startOfWeek) {
128
94
  const days = getWeekCalendarDays(baseDate, startOfWeek);
129
95
  assertWeekCalendarDays(days);
130
96
  return days;
131
97
  }
132
98
  function assertWeekCalendarDays(days) {
133
- if (days.length !== 7) throw new Error("Expected week calendar helper to return exactly 7 days");
99
+ if (days.length !== 7) throw new Error("Expected exactly 7 calendar days");
134
100
  }
135
- /**
136
- * Day-name labels reordered for the chosen week start. Pass a custom
137
- * `dayNames` array (length 7, Sunday-first) to localize.
138
- */
139
101
  function getOrderedDayNames(startOfWeek, dayNames = DAY_NAMES) {
140
102
  if (startOfWeek === "monday") {
141
103
  const sunday = dayNames[0] ?? "Sun";
@@ -143,22 +105,17 @@ function getOrderedDayNames(startOfWeek, dayNames = DAY_NAMES) {
143
105
  }
144
106
  return [...dayNames];
145
107
  }
146
- /**
147
- * Header title for a calendar view.
148
- * - month: "January 2025"
149
- * - week: "January 5 - 11, 2025" or "December 30 - January 5, 2025"
150
- */
151
108
  function formatCalendarTitle(viewDate, view, days, monthNames = MONTH_NAMES) {
152
109
  if (view === "week") {
153
110
  const weekStart = days[0];
154
111
  const weekEnd = days[6];
155
- if (weekStart === void 0 || weekEnd === void 0) return `${monthNames[viewDate.getMonth()] ?? ""} ${viewDate.getFullYear()}`;
156
- const startMonth = monthNames[weekStart.getMonth()] ?? "";
157
- const endMonth = monthNames[weekEnd.getMonth()] ?? "";
158
- if (weekStart.getMonth() === weekEnd.getMonth()) return `${startMonth} ${weekStart.getDate()} - ${weekEnd.getDate()}, ${weekEnd.getFullYear()}`;
159
- return `${startMonth} ${weekStart.getDate()} - ${endMonth} ${weekEnd.getDate()}, ${weekEnd.getFullYear()}`;
112
+ if (weekStart === void 0 || weekEnd === void 0) return `${monthNames[viewDate.month - 1] ?? ""} ${viewDate.year}`;
113
+ const startMonth = monthNames[weekStart.month - 1] ?? "";
114
+ const endMonth = monthNames[weekEnd.month - 1] ?? "";
115
+ if (weekStart.month === weekEnd.month) return `${startMonth} ${weekStart.day} - ${weekEnd.day}, ${weekEnd.year}`;
116
+ return `${startMonth} ${weekStart.day} - ${endMonth} ${weekEnd.day}, ${weekEnd.year}`;
160
117
  }
161
- return `${monthNames[viewDate.getMonth()] ?? ""} ${viewDate.getFullYear()}`;
118
+ return `${monthNames[viewDate.month - 1] ?? ""} ${viewDate.year}`;
162
119
  }
163
120
  function buildCalendarViewport(input) {
164
121
  const monthNames = input.monthNames ?? MONTH_NAMES;
@@ -168,10 +125,10 @@ function buildCalendarViewport(input) {
168
125
  kind: "week",
169
126
  anchorDate: input.anchorDate,
170
127
  days,
171
- title: formatCalendarTitle(input.anchorDate, "week", [...days], monthNames)
128
+ title: formatCalendarTitle(input.anchorDate, "week", days, monthNames)
172
129
  };
173
130
  }
174
- const days = getMonthCalendarDays(input.anchorDate.getFullYear(), input.anchorDate.getMonth(), input.startOfWeek);
131
+ const days = getMonthCalendarDays(input.anchorDate.year, input.anchorDate.month, input.startOfWeek);
175
132
  return {
176
133
  kind: "month",
177
134
  anchorDate: input.anchorDate,
@@ -250,25 +207,34 @@ const TabBar = ({ tabs, activeTab, onTabChange, className }) => {
250
207
  };
251
208
  //#endregion
252
209
  //#region ../blocks/src/system/runtime/hooks/useCalendarEvents.state.ts
253
- function calendarEventCacheLoadReducer(_state, action) {
210
+ function calendarEventCacheLoadReducer(state, action) {
254
211
  switch (action.type) {
255
- case "started": return { kind: "loading" };
256
- case "succeeded": return { kind: "idle" };
257
- case "failed": return {
212
+ case "started": return {
213
+ kind: "loading",
214
+ scope: action.scope
215
+ };
216
+ case "succeeded": return sameCalendarLoadScope(state, action.scope) ? { kind: "idle" } : state;
217
+ case "failed": return sameCalendarLoadScope(state, action.scope) ? {
258
218
  kind: "error",
219
+ scope: action.scope,
259
220
  error: action.error
260
- };
221
+ } : state;
261
222
  default: return assertNever(action);
262
223
  }
263
224
  }
264
- function toCalendarEventCacheLoadError(error) {
265
- return toError(error, "Unknown error");
225
+ function projectCalendarLoadState(state, scope) {
226
+ if (state.kind === "idle" || !sameCalendarLoadScope(state, scope)) return { kind: "idle" };
227
+ return state.kind === "loading" ? { kind: "loading" } : {
228
+ kind: "error",
229
+ error: state.error
230
+ };
266
231
  }
267
- function isCalendarEventCacheLoading(state) {
268
- return state.kind === "loading";
232
+ function sameCalendarLoadScope(state, scope) {
233
+ if (state.kind === "idle") return false;
234
+ return state.scope.filtersKey === scope.filtersKey && state.scope.anchorDate.year === scope.anchorDate.year && state.scope.anchorDate.month === scope.anchorDate.month && state.scope.anchorDate.day === scope.anchorDate.day;
269
235
  }
270
- function getCalendarEventCacheError(state) {
271
- return state.kind === "error" ? state.error : null;
236
+ function toCalendarEventCacheLoadError(error) {
237
+ return toError(error, "Unknown error");
272
238
  }
273
239
  //#endregion
274
240
  //#region ../blocks/src/system/runtime/hooks/useCalendarEvents.ts
@@ -280,18 +246,35 @@ function getCalendarEventCacheError(state) {
280
246
  */
281
247
  /** Maximum events to fetch per calendar request (covers 3 months of events) */
282
248
  const CALENDAR_FETCH_LIMIT = 200;
249
+ async function loadCalendarEventPages(loadPage, request, isCurrent) {
250
+ const events = [];
251
+ let afterStartsAt;
252
+ let afterId;
253
+ for (;;) {
254
+ const page = await loadPage({
255
+ ...request,
256
+ afterStartsAt,
257
+ afterId,
258
+ limit: CALENDAR_FETCH_LIMIT
259
+ });
260
+ if (!isCurrent()) return null;
261
+ events.push(...page);
262
+ if (page.length < CALENDAR_FETCH_LIMIT) return events;
263
+ const last = page[page.length - 1];
264
+ if (!last) return events;
265
+ if (last.startsAt === afterStartsAt && last.occurrenceId === afterId) throw new Error("Calendar event pagination cursor did not advance");
266
+ afterStartsAt = last.startsAt;
267
+ afterId = last.occurrenceId;
268
+ }
269
+ }
283
270
  /**
284
271
  * Generate a cache key for a month
285
272
  */
286
273
  function getMonthKey(date) {
287
- return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}`;
274
+ return `${date.year}-${String(date.month).padStart(2, "0")}`;
288
275
  }
289
- /**
290
- * Owns calendar viewport state only: selected anchor date, derived visible
291
- * period, and navigation by the natural unit for the active view.
292
- */
293
- function useCalendarViewport({ view = "month", startOfWeek = "monday", initialDate } = {}) {
294
- const [viewDate, setViewDate] = useState(() => initialDate ?? /* @__PURE__ */ new Date());
276
+ function useCalendarViewport({ view = "month", startOfWeek = "monday", initialDate }) {
277
+ const [viewDate, setViewDate] = useState(initialDate);
295
278
  const viewport = useMemo(() => buildCalendarViewport({
296
279
  view,
297
280
  anchorDate: viewDate,
@@ -316,15 +299,44 @@ function useCalendarViewport({ view = "month", startOfWeek = "monday", initialDa
316
299
  goToPrevious,
317
300
  goToNext,
318
301
  goToToday: useCallback(() => {
319
- setViewDate(/* @__PURE__ */ new Date());
320
- }, [])
302
+ setViewDate(initialDate);
303
+ }, [initialDate])
321
304
  };
322
305
  }
306
+ function addEventsToCalendarCache(cache, events, timeZone) {
307
+ for (const event of events) {
308
+ const monthKey = getMonthKey(getLocalScheduleDate(new Date(event.startsAt), timeZone));
309
+ const existing = cache.get(monthKey) ?? [];
310
+ if (!existing.some((cachedEvent) => cachedEvent.id === event.id)) cache.set(monthKey, [...existing, event]);
311
+ }
312
+ }
313
+ function useInitiallySeededCalendarCache(initialEvents, timeZone) {
314
+ const cacheRef = useRef(/* @__PURE__ */ new Map());
315
+ const seededRef = useRef(false);
316
+ if (!seededRef.current) {
317
+ addEventsToCalendarCache(cacheRef.current, initialEvents, timeZone);
318
+ seededRef.current = true;
319
+ }
320
+ return cacheRef;
321
+ }
322
+ function readEventsFromCalendarCache(cache, viewDate) {
323
+ const allEvents = [];
324
+ for (let offset = -1; offset <= 1; offset += 1) {
325
+ const monthEvents = cache.get(getMonthKey(addMonths(viewDate, offset))) ?? [];
326
+ allEvents.push(...monthEvents);
327
+ }
328
+ const seen = /* @__PURE__ */ new Set();
329
+ return allEvents.filter((event) => {
330
+ if (seen.has(event.id)) return false;
331
+ seen.add(event.id);
332
+ return true;
333
+ }).sort((left, right) => new Date(left.startsAt).getTime() - new Date(right.startsAt).getTime());
334
+ }
323
335
  /**
324
336
  * Owns event loading and month-window caching for a supplied viewport anchor.
325
337
  * It does not decide navigation semantics or visible calendar days.
326
338
  */
327
- function useCalendarEventCache({ viewDate, initialEvents = [], preloadMonths = 1, filters, stage }) {
339
+ function useCalendarEventCache({ viewDate, initialEvents = [], preloadMonths = 1, filters, stage, timeZone }) {
328
340
  const { getPublicEvents } = useBlockApi();
329
341
  const [loadState, dispatchLoadState] = useReducer(calendarEventCacheLoadReducer, { kind: "idle" });
330
342
  const [cacheVersion, setCacheVersion] = useState(0);
@@ -336,7 +348,7 @@ function useCalendarEventCache({ viewDate, initialEvents = [], preloadMonths = 1
336
348
  filters?.staffMemberId,
337
349
  filters?.venueId
338
350
  ]);
339
- const cacheRef = useRef(/* @__PURE__ */ new Map());
351
+ const cacheRef = useInitiallySeededCalendarCache(initialEvents, timeZone);
340
352
  const loadedMonthsRef = useRef(/* @__PURE__ */ new Set());
341
353
  const fetchingRef = useRef(/* @__PURE__ */ new Set());
342
354
  const requestIdRef = useRef(0);
@@ -348,24 +360,26 @@ function useCalendarEventCache({ viewDate, initialEvents = [], preloadMonths = 1
348
360
  loadedMonthsRef.current = /* @__PURE__ */ new Set();
349
361
  fetchingRef.current = /* @__PURE__ */ new Set();
350
362
  requestIdRef.current += 1;
351
- if (initialEvents.length > 0) for (const event of initialEvents) {
352
- const monthKey = getMonthKey(new Date(event.startsAt));
353
- const existing = cacheRef.current.get(monthKey) || [];
354
- if (!existing.some((e) => e.id === event.id)) cacheRef.current.set(monthKey, [...existing, event]);
355
- }
363
+ addEventsToCalendarCache(cacheRef.current, initialEvents, timeZone);
356
364
  setCacheVersion((v) => v + 1);
357
- }, [filtersKey, initialEvents]);
358
- const fetchEventsForRange = useCallback(async (from, to, targetMonths) => {
365
+ }, [
366
+ filtersKey,
367
+ initialEvents,
368
+ timeZone
369
+ ]);
370
+ const fetchEventsForRange = useCallback(async (from, to, targetMonths, scope) => {
359
371
  const monthsToFetch = targetMonths.filter((m) => !loadedMonthsRef.current.has(m) && !fetchingRef.current.has(m));
360
372
  if (monthsToFetch.length === 0) return;
361
373
  monthsToFetch.forEach((m) => fetchingRef.current.add(m));
362
374
  const currentRequestId = ++requestIdRef.current;
363
- dispatchLoadState({ type: "started" });
375
+ dispatchLoadState({
376
+ type: "started",
377
+ scope
378
+ });
364
379
  try {
365
- const result = await getPublicEvents({
380
+ const result = await loadCalendarEventPages(getPublicEvents, {
366
381
  from,
367
382
  to,
368
- limit: CALENDAR_FETCH_LIMIT,
369
383
  stage,
370
384
  detailLevel: "listing",
371
385
  eventSurface: filters?.eventSurface,
@@ -374,23 +388,27 @@ function useCalendarEventCache({ viewDate, initialEvents = [], preloadMonths = 1
374
388
  categoryIds: filters?.categoryIds,
375
389
  staffMemberId: filters?.staffMemberId,
376
390
  venueId: filters?.venueId
377
- });
378
- if (currentRequestId === requestIdRef.current) {
379
- for (const event of result) {
380
- const monthKey = getMonthKey(new Date(event.startsAt));
381
- const existing = cacheRef.current.get(monthKey) || [];
382
- if (!existing.some((e) => e.id === event.id)) cacheRef.current.set(monthKey, [...existing, event]);
383
- }
384
- for (const month of monthsToFetch) {
385
- loadedMonthsRef.current.add(month);
386
- if (!cacheRef.current.has(month)) cacheRef.current.set(month, []);
387
- }
388
- setCacheVersion((v) => v + 1);
389
- dispatchLoadState({ type: "succeeded" });
391
+ }, () => currentRequestId === requestIdRef.current);
392
+ if (result === null) return;
393
+ for (const event of result) {
394
+ const monthKey = getMonthKey(getLocalScheduleDate(new Date(event.startsAt), timeZone));
395
+ const existing = cacheRef.current.get(monthKey) || [];
396
+ if (!existing.some((e) => e.id === event.id)) cacheRef.current.set(monthKey, [...existing, event]);
390
397
  }
398
+ for (const month of monthsToFetch) {
399
+ loadedMonthsRef.current.add(month);
400
+ if (!cacheRef.current.has(month)) cacheRef.current.set(month, []);
401
+ }
402
+ setCacheVersion((v) => v + 1);
403
+ dispatchLoadState({
404
+ type: "succeeded",
405
+ scope
406
+ });
391
407
  } catch (err) {
408
+ monthsToFetch.forEach((m) => fetchingRef.current.delete(m));
392
409
  if (currentRequestId === requestIdRef.current) dispatchLoadState({
393
410
  type: "failed",
411
+ scope,
394
412
  error: toCalendarEventCacheLoadError(err)
395
413
  });
396
414
  } finally {
@@ -404,7 +422,8 @@ function useCalendarEventCache({ viewDate, initialEvents = [], preloadMonths = 1
404
422
  filters?.scheduleScope,
405
423
  filters?.staffMemberId,
406
424
  filters?.venueId,
407
- stage
425
+ stage,
426
+ timeZone
408
427
  ]);
409
428
  const ensureEventsLoaded = useCallback((date) => {
410
429
  const targetMonths = [];
@@ -414,70 +433,66 @@ function useCalendarEventCache({ viewDate, initialEvents = [], preloadMonths = 1
414
433
  }
415
434
  const unloadedMonths = targetMonths.filter((m) => !loadedMonthsRef.current.has(m) && !fetchingRef.current.has(m));
416
435
  if (unloadedMonths.length > 0) {
417
- const range = getThreeMonthRange(date);
418
- fetchEventsForRange(range.from, range.to, unloadedMonths);
436
+ const startDate = getStartOfMonth(addMonths(date, -preloadMonths));
437
+ const endDate = getEndOfMonth(addMonths(date, preloadMonths));
438
+ const range = buildBookingUtcDateWindow({
439
+ startDate: formatLocalScheduleDate(startDate),
440
+ endDate: formatLocalScheduleDate(endDate),
441
+ timeZone
442
+ });
443
+ const scope = {
444
+ anchorDate: date,
445
+ filtersKey
446
+ };
447
+ fetchEventsForRange(range.startAt.toISOString(), (/* @__PURE__ */ new Date(range.endExclusive.getTime() - 1)).toISOString(), unloadedMonths, scope);
419
448
  }
420
- }, [preloadMonths, fetchEventsForRange]);
449
+ }, [
450
+ preloadMonths,
451
+ fetchEventsForRange,
452
+ filtersKey,
453
+ timeZone
454
+ ]);
421
455
  useEffect(() => {
422
456
  ensureEventsLoaded(viewDate);
423
457
  }, [viewDate, ensureEventsLoaded]);
458
+ const retryCurrentView = useCallback(() => {
459
+ ensureEventsLoaded(viewDate);
460
+ }, [ensureEventsLoaded, viewDate]);
424
461
  return {
425
- events: useMemo(() => {
426
- const allEvents = [];
427
- for (let i = -1; i <= 1; i++) {
428
- const monthKey = getMonthKey(addMonths(viewDate, i));
429
- const monthEvents = cacheRef.current.get(monthKey) || [];
430
- allEvents.push(...monthEvents);
431
- }
432
- const seen = /* @__PURE__ */ new Set();
433
- return allEvents.filter((e) => {
434
- if (seen.has(e.id)) return false;
435
- seen.add(e.id);
436
- return true;
437
- }).sort((a, b) => new Date(a.startsAt).getTime() - new Date(b.startsAt).getTime());
438
- }, [viewDate, cacheVersion]),
439
- loading: isCalendarEventCacheLoading(loadState),
440
- error: getCalendarEventCacheError(loadState)
462
+ events: useMemo(() => readEventsFromCalendarCache(cacheRef.current, viewDate), [viewDate, cacheVersion]),
463
+ loadState: projectCalendarLoadState(loadState, useMemo(() => ({
464
+ anchorDate: viewDate,
465
+ filtersKey
466
+ }), [filtersKey, viewDate])),
467
+ retryCurrentView
441
468
  };
442
469
  }
443
- /**
444
- * Hook for calendar event management with month-based caching.
445
- *
446
- * Pre-fetches 3 months (previous, current, next) and caches by month.
447
- * Navigation within cached range is instant; fetches at boundaries.
448
- *
449
- * @example
450
- * ```tsx
451
- * const { events, viewDate, loading, goToPrevious, goToNext } = useCalendarEvents({
452
- * siteId: 'site-123',
453
- * initialEvents: serverEvents,
454
- * });
455
- * ```
456
- */
457
- function useCalendarEvents({ siteId: _siteId, initialEvents = [], view = "month", startOfWeek = "monday", preloadMonths = 1, filters, stage }) {
470
+ function useCalendarEvents({ siteId: _siteId, initialEvents = [], view = "month", startOfWeek = "monday", preloadMonths = 1, filters, stage, calendarContext }) {
458
471
  const { viewDate, viewport, goToDate, goToPrevious, goToNext, goToToday } = useCalendarViewport({
459
472
  view,
460
- startOfWeek
473
+ startOfWeek,
474
+ initialDate: calendarContext.initialToday
461
475
  });
462
- const { events, loading, error } = useCalendarEventCache({
476
+ const { events, loadState, retryCurrentView } = useCalendarEventCache({
463
477
  viewDate,
464
478
  initialEvents,
465
479
  preloadMonths,
466
480
  filters,
467
- stage
481
+ stage,
482
+ timeZone: calendarContext.timeZone
468
483
  });
469
484
  return {
470
485
  events,
471
486
  viewDate,
472
487
  viewport,
473
- loading,
474
- error,
488
+ loadState,
475
489
  setViewDate: useCallback((date) => {
476
490
  goToDate(date);
477
491
  }, [goToDate]),
478
492
  goToPrevious,
479
493
  goToNext,
480
- goToToday
494
+ goToToday,
495
+ retryCurrentView
481
496
  };
482
497
  }
483
498
  //#endregion
@@ -544,9 +559,9 @@ function useEventModal() {
544
559
  * Clicking an event opens the EventDetailModal.
545
560
  * Clicking "+N more" opens the DayEventsModal.
546
561
  */
547
- const CalendarDayCell = ({ date, events, isCurrentMonth }) => {
562
+ const CalendarDayCell = ({ date, events, isCurrentMonth, today: currentDate }) => {
548
563
  const { openEventModal, openDayModal } = useEventModal();
549
- const today = isToday(date);
564
+ const today = isToday(date, currentDate);
550
565
  const dayClasses = [
551
566
  "event-calendar-day",
552
567
  !isCurrentMonth && "event-calendar-day--other-month",
@@ -562,7 +577,7 @@ const CalendarDayCell = ({ date, events, isCurrentMonth }) => {
562
577
  className: dayClasses,
563
578
  children: [/* @__PURE__ */ jsx("div", {
564
579
  className: "event-calendar-day-number",
565
- children: date.getDate()
580
+ children: date.day
566
581
  }), /* @__PURE__ */ jsxs("div", {
567
582
  className: "event-calendar-events",
568
583
  children: [events.slice(0, 3).map((event) => {
@@ -694,9 +709,9 @@ const FULL_DAY_NAMES = [
694
709
  * @returns "Monday, January 13"
695
710
  */
696
711
  function formatAgendaDayHeader(date) {
697
- const dayName = FULL_DAY_NAMES[date.getDay()];
698
- const monthName = MONTH_NAMES[date.getMonth()];
699
- return `${dayName ?? "Day"}, ${monthName ?? "Month"} ${date.getDate()}`;
712
+ const dayName = FULL_DAY_NAMES[getDayOfWeek(date)];
713
+ const monthName = MONTH_NAMES[date.month - 1];
714
+ return `${dayName ?? "Day"}, ${monthName ?? "Month"} ${date.day}`;
700
715
  }
701
716
  /**
702
717
  * WeekAgendaView Component
@@ -704,14 +719,14 @@ function formatAgendaDayHeader(date) {
704
719
  * Displays a week of events in an agenda/list style with rich event details.
705
720
  * Shows all 7 days with date headers, empty days show "No events scheduled".
706
721
  */
707
- const WeekAgendaView = ({ days, events, showCapacity, emptyMessage = "No events scheduled" }) => {
708
- const eventsByDate = groupEventsByDate(events);
722
+ const WeekAgendaView = ({ days, events, showCapacity, emptyMessage = "No events scheduled", calendarTimeZone, today: currentDate }) => {
723
+ const eventsByDate = groupEventsByDate(events, calendarTimeZone);
709
724
  return /* @__PURE__ */ jsx("div", {
710
725
  className: "event-agenda-week",
711
726
  children: days.map((date) => {
712
727
  const dateKey = formatDateKey(date);
713
728
  const dayEvents = eventsByDate.get(dateKey) || [];
714
- const today = isToday(date);
729
+ const today = isToday(date, currentDate);
715
730
  return /* @__PURE__ */ jsxs("div", {
716
731
  className: `event-agenda-day ${today ? "event-agenda-day--today" : ""}`,
717
732
  children: [/* @__PURE__ */ jsx("div", {
@@ -810,7 +825,7 @@ function EventDetailModal({ event, showCapacity, onClose, portalRoot, cardRole =
810
825
  * Clicking an event triggers onSelectEvent (typically opens EventDetailModal).
811
826
  */
812
827
  function DayEventsModal({ date, events, showCapacity, onClose, onSelectEvent, portalRoot }) {
813
- const formattedDate = formatDate(date.toISOString());
828
+ const formattedDate = formatDate(`${formatLocalScheduleDate(date)}T12:00:00Z`);
814
829
  return /* @__PURE__ */ jsxs(ModalShell, {
815
830
  title: formattedDate,
816
831
  titleId: "ec-day-modal-title",
@@ -950,7 +965,8 @@ function toEventCombinedControllerProps(props) {
950
965
  buttonVariant: props.render.display.buttonVariant,
951
966
  buttonText: props.render.display.buttonText,
952
967
  emptyMessage: props.render.display.emptyMessage,
953
- className: props.render.display.className ?? void 0
968
+ className: props.render.display.className ?? void 0,
969
+ calendarContext: props.render.hydration.calendarContext
954
970
  };
955
971
  }
956
972
  /**
@@ -962,7 +978,7 @@ function toEventCombinedControllerProps(props) {
962
978
  const EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout = "stack", listColumns = "3", eventsPerPage = 12, paginationAction = {
963
979
  kind: "loadMore",
964
980
  label: "Load more events"
965
- }, startOfWeek = "monday", calendarTabViews = "both", defaultCalendarView, showFilters, showCategoryFilter = "auto", showVenueFilter, showStaffFilter, eventSurface, filterEventPresets, scheduleScope, filterCategoryIds, filterStaffMemberId, filterVenueId, showVenue, showMap, showCapacity, cardRole, buttonVariant = "primary", buttonText = "Book", emptyMessage = "No upcoming events scheduled.", className }) => {
981
+ }, startOfWeek = "monday", calendarTabViews = "both", defaultCalendarView, showFilters, showCategoryFilter = "auto", showVenueFilter, showStaffFilter, eventSurface, filterEventPresets, scheduleScope, filterCategoryIds, filterStaffMemberId, filterVenueId, showVenue, showMap, showCapacity, cardRole, buttonVariant = "primary", buttonText = "Book", emptyMessage = "No upcoming events scheduled.", className, calendarContext }) => {
966
982
  const fetchInitialEventsOnMount = initialEvents == null;
967
983
  const resolvedShowFilters = showFilters ?? true;
968
984
  const resolvedShowVenueFilter = showVenueFilter ?? false;
@@ -1020,7 +1036,7 @@ const EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout
1020
1036
  pageSize,
1021
1037
  stage
1022
1038
  });
1023
- const { events: calendarEventsRaw, viewDate, viewport, loading: calendarLoading, goToPrevious, goToNext, goToToday } = useCalendarEvents({
1039
+ const { events: calendarEventsRaw, viewDate, viewport, loadState: calendarLoadState, goToPrevious, goToNext, goToToday } = useCalendarEvents({
1024
1040
  siteId,
1025
1041
  initialEvents: useMemo(() => {
1026
1042
  return getEventRuntimeFiltersKey(initialListFilters) === getEventRuntimeFiltersKey(listFilters) ? initialEvents ?? [] : [];
@@ -1033,9 +1049,10 @@ const EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout
1033
1049
  startOfWeek,
1034
1050
  preloadMonths: 1,
1035
1051
  filters: listFilters,
1036
- stage
1052
+ stage,
1053
+ calendarContext
1037
1054
  });
1038
- const eventsByDate = useMemo(() => groupEventsByDate(calendarEventsRaw), [calendarEventsRaw]);
1055
+ const eventsByDate = useMemo(() => groupEventsByDate(calendarEventsRaw, calendarContext.timeZone), [calendarContext.timeZone, calendarEventsRaw]);
1039
1056
  const dayNames = useMemo(() => getOrderedDayNames(startOfWeek), [startOfWeek]);
1040
1057
  const tabs = [{
1041
1058
  id: "list",
@@ -1137,7 +1154,7 @@ const EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout
1137
1154
  }),
1138
1155
  /* @__PURE__ */ jsxs("h3", {
1139
1156
  className: "event-calendar-title",
1140
- children: [viewport.title, calendarLoading && /* @__PURE__ */ jsx("span", {
1157
+ children: [viewport.title, calendarLoadState.kind === "loading" && /* @__PURE__ */ jsx("span", {
1141
1158
  className: "rb-ml-2 rb-caption status-muted",
1142
1159
  children: "(loading...)"
1143
1160
  })]
@@ -1176,7 +1193,9 @@ const EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout
1176
1193
  days: viewport.days,
1177
1194
  events: calendarEventsRaw,
1178
1195
  emptyMessage: "No events scheduled",
1179
- showCapacity: resolvedShowCapacity
1196
+ showCapacity: resolvedShowCapacity,
1197
+ calendarTimeZone: calendarContext.timeZone,
1198
+ today: calendarContext.initialToday
1180
1199
  }) : /* @__PURE__ */ jsxs("div", {
1181
1200
  className: "event-calendar-container",
1182
1201
  children: [/* @__PURE__ */ jsx("div", {
@@ -1192,12 +1211,13 @@ const EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout
1192
1211
  return /* @__PURE__ */ jsx(CalendarDayCell, {
1193
1212
  date,
1194
1213
  events: eventsByDate.get(dateKey) || [],
1195
- isCurrentMonth: date.getMonth() === viewDate.getMonth()
1214
+ isCurrentMonth: date.month === viewDate.month,
1215
+ today: calendarContext.initialToday
1196
1216
  }, dateKey);
1197
1217
  })
1198
1218
  })]
1199
1219
  }),
1200
- calendarEventsRaw.length === 0 && !calendarLoading && /* @__PURE__ */ jsx("p", {
1220
+ calendarEventsRaw.length === 0 && calendarLoadState.kind === "idle" && /* @__PURE__ */ jsx("p", {
1201
1221
  className: "event-calendar-empty",
1202
1222
  children: emptyMessage
1203
1223
  })
@@ -1213,4 +1233,4 @@ const EventCombinedClient = ({ events: initialEvents, siteId, stage, listLayout
1213
1233
  };
1214
1234
  const EventCombinedIslandClient = (props) => /* @__PURE__ */ jsx(EventCombinedClient, { ...toEventCombinedControllerProps(props) });
1215
1235
  //#endregion
1216
- export { CalendarDayCell as a, useCalendarEvents as c, getOrderedDayNames as d, getWeekCalendarDayTuple as f, isToday as h, WeekAgendaView as i, MONTH_NAMES as l, isSameLocalDay as m, EventCombinedIslandClient as n, EventModalProvider as o, getWeekCalendarDays as p, EventModals as r, useEventModal as s, EventCombinedClient as t, formatDateKey as u };
1236
+ export { CalendarDayCell as a, useCalendarEvents as c, formatDateKey as d, getDayOfWeek as f, isToday as g, isSameCalendarDay as h, WeekAgendaView as i, MONTH_NAMES as l, getWeekCalendarDays as m, EventCombinedIslandClient as n, EventModalProvider as o, getOrderedDayNames as p, EventModals as r, useEventModal as s, EventCombinedClient as t, addDays as u };