@withpotter/pages-bookings 0.13.0-next.101

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 (270) hide show
  1. package/dist/dashboard/(bookings)/attendees/page.js +8 -0
  2. package/dist/dashboard/(bookings)/attendees/page.js.map +1 -0
  3. package/dist/dashboard/(bookings)/availability/_components/availability-screen.js +714 -0
  4. package/dist/dashboard/(bookings)/availability/_components/availability-screen.js.map +1 -0
  5. package/dist/dashboard/(bookings)/availability/_components/month-availability.js +130 -0
  6. package/dist/dashboard/(bookings)/availability/_components/month-availability.js.map +1 -0
  7. package/dist/dashboard/(bookings)/availability/page.js +10 -0
  8. package/dist/dashboard/(bookings)/availability/page.js.map +1 -0
  9. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/assign-resource-modal.js +133 -0
  10. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/assign-resource-modal.js.map +1 -0
  11. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-constants.js +26 -0
  12. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-constants.js.map +1 -0
  13. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-desktop-layout.js +194 -0
  14. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-desktop-layout.js.map +1 -0
  15. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-layout-props.js +1 -0
  16. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-layout-props.js.map +1 -0
  17. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-lede.js +189 -0
  18. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-lede.js.map +1 -0
  19. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-meta.js +38 -0
  20. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-meta.js.map +1 -0
  21. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-layout.js +315 -0
  22. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-layout.js.map +1 -0
  23. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-screen.js +94 -0
  24. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-mobile-screen.js.map +1 -0
  25. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-money.js +54 -0
  26. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-money.js.map +1 -0
  27. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-split.js +71 -0
  28. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/booking-split.js.map +1 -0
  29. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancel-booking-modal.js +102 -0
  30. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancel-booking-modal.js.map +1 -0
  31. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancellation-notice.js +33 -0
  32. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/cancellation-notice.js.map +1 -0
  33. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/customer-info-card.js +65 -0
  34. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/customer-info-card.js.map +1 -0
  35. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/index.js +23 -0
  36. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/index.js.map +1 -0
  37. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/intake-answers-card.js +19 -0
  38. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/intake-answers-card.js.map +1 -0
  39. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/refund-booking-modal.js +156 -0
  40. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/refund-booking-modal.js.map +1 -0
  41. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/reschedule-booking-modal.js +120 -0
  42. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/reschedule-booking-modal.js.map +1 -0
  43. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/security-deposit-card.js +63 -0
  44. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/security-deposit-card.js.map +1 -0
  45. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/settle-deposit-modal.js +141 -0
  46. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/settle-deposit-modal.js.map +1 -0
  47. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/ticket-row-actions.js +49 -0
  48. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/ticket-row-actions.js.map +1 -0
  49. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/waiting-queue-notice.js +42 -0
  50. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components/waiting-queue-notice.js.map +1 -0
  51. package/dist/dashboard/(bookings)/bookings/[bookingId]/_components.js +1 -0
  52. package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/index.js +19 -0
  53. package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/index.js.map +1 -0
  54. package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/use-booking-detail-data.js +352 -0
  55. package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks/use-booking-detail-data.js.map +1 -0
  56. package/dist/dashboard/(bookings)/bookings/[bookingId]/_hooks.js +1 -0
  57. package/dist/dashboard/(bookings)/bookings/[bookingId]/layout.js +33 -0
  58. package/dist/dashboard/(bookings)/bookings/[bookingId]/layout.js.map +1 -0
  59. package/dist/dashboard/(bookings)/bookings/[bookingId]/page.js +356 -0
  60. package/dist/dashboard/(bookings)/bookings/[bookingId]/page.js.map +1 -0
  61. package/dist/dashboard/(bookings)/bookings/_components/appointment-calendar-layout.js +34 -0
  62. package/dist/dashboard/(bookings)/bookings/_components/appointment-calendar-layout.js.map +1 -0
  63. package/dist/dashboard/(bookings)/bookings/_components/booking-constants.js +92 -0
  64. package/dist/dashboard/(bookings)/bookings/_components/booking-constants.js.map +1 -0
  65. package/dist/dashboard/(bookings)/bookings/_components/booking-tab-hints.js +32 -0
  66. package/dist/dashboard/(bookings)/bookings/_components/booking-tab-hints.js.map +1 -0
  67. package/dist/dashboard/(bookings)/bookings/_components/bookings-filter-bar.js +131 -0
  68. package/dist/dashboard/(bookings)/bookings/_components/bookings-filter-bar.js.map +1 -0
  69. package/dist/dashboard/(bookings)/bookings/_components/bookings-mobile-controls.js +119 -0
  70. package/dist/dashboard/(bookings)/bookings/_components/bookings-mobile-controls.js.map +1 -0
  71. package/dist/dashboard/(bookings)/bookings/_components/bookings-screen.js +414 -0
  72. package/dist/dashboard/(bookings)/bookings/_components/bookings-screen.js.map +1 -0
  73. package/dist/dashboard/(bookings)/bookings/_components/bookings-table.js +192 -0
  74. package/dist/dashboard/(bookings)/bookings/_components/bookings-table.js.map +1 -0
  75. package/dist/dashboard/(bookings)/bookings/_components/cannot-take-bookings.js +34 -0
  76. package/dist/dashboard/(bookings)/bookings/_components/cannot-take-bookings.js.map +1 -0
  77. package/dist/dashboard/(bookings)/bookings/_components/demo-data.js +176 -0
  78. package/dist/dashboard/(bookings)/bookings/_components/demo-data.js.map +1 -0
  79. package/dist/dashboard/(bookings)/bookings/_components/index.js +9 -0
  80. package/dist/dashboard/(bookings)/bookings/_components/index.js.map +1 -0
  81. package/dist/dashboard/(bookings)/bookings/_components/today/booking-card.js +126 -0
  82. package/dist/dashboard/(bookings)/bookings/_components/today/booking-card.js.map +1 -0
  83. package/dist/dashboard/(bookings)/bookings/_components/today/demo-data.js +142 -0
  84. package/dist/dashboard/(bookings)/bookings/_components/today/demo-data.js.map +1 -0
  85. package/dist/dashboard/(bookings)/bookings/_components/today/handover.js +128 -0
  86. package/dist/dashboard/(bookings)/bookings/_components/today/handover.js.map +1 -0
  87. package/dist/dashboard/(bookings)/bookings/_components/today/index.js +17 -0
  88. package/dist/dashboard/(bookings)/bookings/_components/today/index.js.map +1 -0
  89. package/dist/dashboard/(bookings)/bookings/_components/today/past-band.js +69 -0
  90. package/dist/dashboard/(bookings)/bookings/_components/today/past-band.js.map +1 -0
  91. package/dist/dashboard/(bookings)/bookings/_components/today/resource-board.js +111 -0
  92. package/dist/dashboard/(bookings)/bookings/_components/today/resource-board.js.map +1 -0
  93. package/dist/dashboard/(bookings)/bookings/_components/today/today-band.js +61 -0
  94. package/dist/dashboard/(bookings)/bookings/_components/today/today-band.js.map +1 -0
  95. package/dist/dashboard/(bookings)/bookings/_components/today/upcoming-band.js +113 -0
  96. package/dist/dashboard/(bookings)/bookings/_components/today/upcoming-band.js.map +1 -0
  97. package/dist/dashboard/(bookings)/bookings/_components/today/waiting-queue.js +62 -0
  98. package/dist/dashboard/(bookings)/bookings/_components/today/waiting-queue.js.map +1 -0
  99. package/dist/dashboard/(bookings)/bookings/_components/today-board.js +192 -0
  100. package/dist/dashboard/(bookings)/bookings/_components/today-board.js.map +1 -0
  101. package/dist/dashboard/(bookings)/bookings/_components/today.js +1 -0
  102. package/dist/dashboard/(bookings)/bookings/_components.js +1 -0
  103. package/dist/dashboard/(bookings)/bookings/_hooks/index.js +5 -0
  104. package/dist/dashboard/(bookings)/bookings/_hooks/index.js.map +1 -0
  105. package/dist/dashboard/(bookings)/bookings/_hooks/use-bookings-data.js +331 -0
  106. package/dist/dashboard/(bookings)/bookings/_hooks/use-bookings-data.js.map +1 -0
  107. package/dist/dashboard/(bookings)/bookings/_hooks/use-today-data.js +309 -0
  108. package/dist/dashboard/(bookings)/bookings/_hooks/use-today-data.js.map +1 -0
  109. package/dist/dashboard/(bookings)/bookings/_hooks.js +1 -0
  110. package/dist/dashboard/(bookings)/bookings/_lib/booking-link.js +13 -0
  111. package/dist/dashboard/(bookings)/bookings/_lib/booking-link.js.map +1 -0
  112. package/dist/dashboard/(bookings)/bookings/attendees/_components/attendee-cards.js +60 -0
  113. package/dist/dashboard/(bookings)/bookings/attendees/_components/attendee-cards.js.map +1 -0
  114. package/dist/dashboard/(bookings)/bookings/attendees/_components/qr-scanner-modal.js +225 -0
  115. package/dist/dashboard/(bookings)/bookings/attendees/_components/qr-scanner-modal.js.map +1 -0
  116. package/dist/dashboard/(bookings)/bookings/attendees/demo-data.js +195 -0
  117. package/dist/dashboard/(bookings)/bookings/attendees/demo-data.js.map +1 -0
  118. package/dist/dashboard/(bookings)/bookings/attendees/page.js +341 -0
  119. package/dist/dashboard/(bookings)/bookings/attendees/page.js.map +1 -0
  120. package/dist/dashboard/(bookings)/bookings/new/page.js +129 -0
  121. package/dist/dashboard/(bookings)/bookings/new/page.js.map +1 -0
  122. package/dist/dashboard/(bookings)/bookings/page.js +10 -0
  123. package/dist/dashboard/(bookings)/bookings/page.js.map +1 -0
  124. package/dist/dashboard/(bookings)/bookings/sessions/new/_components/save-buttons.js +36 -0
  125. package/dist/dashboard/(bookings)/bookings/sessions/new/_components/save-buttons.js.map +1 -0
  126. package/dist/dashboard/(bookings)/bookings/sessions/new/_components/session-creator.js +386 -0
  127. package/dist/dashboard/(bookings)/bookings/sessions/new/_components/session-creator.js.map +1 -0
  128. package/dist/dashboard/(bookings)/bookings/sessions/new/_lib/session-payload.js +62 -0
  129. package/dist/dashboard/(bookings)/bookings/sessions/new/_lib/session-payload.js.map +1 -0
  130. package/dist/dashboard/(bookings)/bookings/sessions/new/page.js +10 -0
  131. package/dist/dashboard/(bookings)/bookings/sessions/new/page.js.map +1 -0
  132. package/dist/dashboard/(bookings)/calendar/_components/calendar-nav.js +84 -0
  133. package/dist/dashboard/(bookings)/calendar/_components/calendar-nav.js.map +1 -0
  134. package/dist/dashboard/(bookings)/calendar/_components/calendar-range.js +84 -0
  135. package/dist/dashboard/(bookings)/calendar/_components/calendar-range.js.map +1 -0
  136. package/dist/dashboard/(bookings)/calendar/_components/day-board-view.js +279 -0
  137. package/dist/dashboard/(bookings)/calendar/_components/day-board-view.js.map +1 -0
  138. package/dist/dashboard/(bookings)/calendar/_components/event-detail-modal.js +113 -0
  139. package/dist/dashboard/(bookings)/calendar/_components/event-detail-modal.js.map +1 -0
  140. package/dist/dashboard/(bookings)/calendar/_components/format.js +22 -0
  141. package/dist/dashboard/(bookings)/calendar/_components/format.js.map +1 -0
  142. package/dist/dashboard/(bookings)/calendar/_components/month-grid.js +109 -0
  143. package/dist/dashboard/(bookings)/calendar/_components/month-grid.js.map +1 -0
  144. package/dist/dashboard/(bookings)/calendar/_components/resource-day-grid.js +325 -0
  145. package/dist/dashboard/(bookings)/calendar/_components/resource-day-grid.js.map +1 -0
  146. package/dist/dashboard/(bookings)/calendar/_components/slot-action-sheet.js +209 -0
  147. package/dist/dashboard/(bookings)/calendar/_components/slot-action-sheet.js.map +1 -0
  148. package/dist/dashboard/(bookings)/calendar/_components/use-block-drag.js +77 -0
  149. package/dist/dashboard/(bookings)/calendar/_components/use-block-drag.js.map +1 -0
  150. package/dist/dashboard/(bookings)/calendar/_components/use-calendar-nav.js +69 -0
  151. package/dist/dashboard/(bookings)/calendar/_components/use-calendar-nav.js.map +1 -0
  152. package/dist/dashboard/(bookings)/calendar/_components/week-grid.js +202 -0
  153. package/dist/dashboard/(bookings)/calendar/_components/week-grid.js.map +1 -0
  154. package/dist/dashboard/(bookings)/calendar/_components/year-grid.js +111 -0
  155. package/dist/dashboard/(bookings)/calendar/_components/year-grid.js.map +1 -0
  156. package/dist/dashboard/(bookings)/calendar/page.js +8 -0
  157. package/dist/dashboard/(bookings)/calendar/page.js.map +1 -0
  158. package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feed-modal.js +126 -0
  159. package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feed-modal.js.map +1 -0
  160. package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feeds-section.js +99 -0
  161. package/dist/dashboard/(bookings)/calendar-sync/_components/channel-feeds-section.js.map +1 -0
  162. package/dist/dashboard/(bookings)/calendar-sync/demo-data.js +64 -0
  163. package/dist/dashboard/(bookings)/calendar-sync/demo-data.js.map +1 -0
  164. package/dist/dashboard/(bookings)/calendar-sync/page.js +15 -0
  165. package/dist/dashboard/(bookings)/calendar-sync/page.js.map +1 -0
  166. package/dist/dashboard/(bookings)/check-in/page.js +252 -0
  167. package/dist/dashboard/(bookings)/check-in/page.js.map +1 -0
  168. package/dist/dashboard/(bookings)/events/[eventId]/_components/event-attendees.js +108 -0
  169. package/dist/dashboard/(bookings)/events/[eventId]/_components/event-attendees.js.map +1 -0
  170. package/dist/dashboard/(bookings)/events/[eventId]/_components/event-share.js +73 -0
  171. package/dist/dashboard/(bookings)/events/[eventId]/_components/event-share.js.map +1 -0
  172. package/dist/dashboard/(bookings)/events/[eventId]/layout.js +10 -0
  173. package/dist/dashboard/(bookings)/events/[eventId]/layout.js.map +1 -0
  174. package/dist/dashboard/(bookings)/events/[eventId]/page.js +247 -0
  175. package/dist/dashboard/(bookings)/events/[eventId]/page.js.map +1 -0
  176. package/dist/dashboard/(bookings)/events/_components/event-grid.js +44 -0
  177. package/dist/dashboard/(bookings)/events/_components/event-grid.js.map +1 -0
  178. package/dist/dashboard/(bookings)/events/_components/event-poster.js +17 -0
  179. package/dist/dashboard/(bookings)/events/_components/event-poster.js.map +1 -0
  180. package/dist/dashboard/(bookings)/events/_hooks/use-events-data.js +55 -0
  181. package/dist/dashboard/(bookings)/events/_hooks/use-events-data.js.map +1 -0
  182. package/dist/dashboard/(bookings)/events/_lib/event-facts.js +68 -0
  183. package/dist/dashboard/(bookings)/events/_lib/event-facts.js.map +1 -0
  184. package/dist/dashboard/(bookings)/events/new/_components/event-composer.js +295 -0
  185. package/dist/dashboard/(bookings)/events/new/_components/event-composer.js.map +1 -0
  186. package/dist/dashboard/(bookings)/events/new/_components/event-poster.js +65 -0
  187. package/dist/dashboard/(bookings)/events/new/_components/event-poster.js.map +1 -0
  188. package/dist/dashboard/(bookings)/events/new/_components/ticket-tiers.js +75 -0
  189. package/dist/dashboard/(bookings)/events/new/_components/ticket-tiers.js.map +1 -0
  190. package/dist/dashboard/(bookings)/events/new/page.js +10 -0
  191. package/dist/dashboard/(bookings)/events/new/page.js.map +1 -0
  192. package/dist/dashboard/(bookings)/events/page.js +214 -0
  193. package/dist/dashboard/(bookings)/events/page.js.map +1 -0
  194. package/dist/dashboard/(bookings)/resources/[resourceId]/layout.js +36 -0
  195. package/dist/dashboard/(bookings)/resources/[resourceId]/layout.js.map +1 -0
  196. package/dist/dashboard/(bookings)/resources/[resourceId]/page.js +351 -0
  197. package/dist/dashboard/(bookings)/resources/[resourceId]/page.js.map +1 -0
  198. package/dist/dashboard/(bookings)/resources/_components/block-time-modal.js +130 -0
  199. package/dist/dashboard/(bookings)/resources/_components/block-time-modal.js.map +1 -0
  200. package/dist/dashboard/(bookings)/resources/_components/category-card.js +74 -0
  201. package/dist/dashboard/(bookings)/resources/_components/category-card.js.map +1 -0
  202. package/dist/dashboard/(bookings)/resources/_components/category-form-dialog.js +197 -0
  203. package/dist/dashboard/(bookings)/resources/_components/category-form-dialog.js.map +1 -0
  204. package/dist/dashboard/(bookings)/resources/_components/day-editor.js +194 -0
  205. package/dist/dashboard/(bookings)/resources/_components/day-editor.js.map +1 -0
  206. package/dist/dashboard/(bookings)/resources/_components/group-dialog.js +170 -0
  207. package/dist/dashboard/(bookings)/resources/_components/group-dialog.js.map +1 -0
  208. package/dist/dashboard/(bookings)/resources/_components/group-header.js +90 -0
  209. package/dist/dashboard/(bookings)/resources/_components/group-header.js.map +1 -0
  210. package/dist/dashboard/(bookings)/resources/_components/index.js +22 -0
  211. package/dist/dashboard/(bookings)/resources/_components/index.js.map +1 -0
  212. package/dist/dashboard/(bookings)/resources/_components/mobile-category-form-sheet.js +256 -0
  213. package/dist/dashboard/(bookings)/resources/_components/mobile-category-form-sheet.js.map +1 -0
  214. package/dist/dashboard/(bookings)/resources/_components/resource-form.js +420 -0
  215. package/dist/dashboard/(bookings)/resources/_components/resource-form.js.map +1 -0
  216. package/dist/dashboard/(bookings)/resources/_components/resource-picker.js +144 -0
  217. package/dist/dashboard/(bookings)/resources/_components/resource-picker.js.map +1 -0
  218. package/dist/dashboard/(bookings)/resources/_components/resource-type-picker-empty.js +109 -0
  219. package/dist/dashboard/(bookings)/resources/_components/resource-type-picker-empty.js.map +1 -0
  220. package/dist/dashboard/(bookings)/resources/_components/roster-empty.js +103 -0
  221. package/dist/dashboard/(bookings)/resources/_components/roster-empty.js.map +1 -0
  222. package/dist/dashboard/(bookings)/resources/_components/roster-grid.js +160 -0
  223. package/dist/dashboard/(bookings)/resources/_components/roster-grid.js.map +1 -0
  224. package/dist/dashboard/(bookings)/resources/_components/schedule-editor.js +244 -0
  225. package/dist/dashboard/(bookings)/resources/_components/schedule-editor.js.map +1 -0
  226. package/dist/dashboard/(bookings)/resources/_components/schedule-timezone-field.js +25 -0
  227. package/dist/dashboard/(bookings)/resources/_components/schedule-timezone-field.js.map +1 -0
  228. package/dist/dashboard/(bookings)/resources/_components/solo-schedule-view.js +146 -0
  229. package/dist/dashboard/(bookings)/resources/_components/solo-schedule-view.js.map +1 -0
  230. package/dist/dashboard/(bookings)/resources/_components/team-onboarding-dialog.js +161 -0
  231. package/dist/dashboard/(bookings)/resources/_components/team-onboarding-dialog.js.map +1 -0
  232. package/dist/dashboard/(bookings)/resources/_components/week-grid.js +175 -0
  233. package/dist/dashboard/(bookings)/resources/_components/week-grid.js.map +1 -0
  234. package/dist/dashboard/(bookings)/resources/_components.js +1 -0
  235. package/dist/dashboard/(bookings)/resources/_hooks/index.js +8 -0
  236. package/dist/dashboard/(bookings)/resources/_hooks/index.js.map +1 -0
  237. package/dist/dashboard/(bookings)/resources/_hooks/use-resource-categories-data.js +86 -0
  238. package/dist/dashboard/(bookings)/resources/_hooks/use-resource-categories-data.js.map +1 -0
  239. package/dist/dashboard/(bookings)/resources/_hooks/use-roster-page.js +138 -0
  240. package/dist/dashboard/(bookings)/resources/_hooks/use-roster-page.js.map +1 -0
  241. package/dist/dashboard/(bookings)/resources/_hooks/use-roster.js +182 -0
  242. package/dist/dashboard/(bookings)/resources/_hooks/use-roster.js.map +1 -0
  243. package/dist/dashboard/(bookings)/resources/_hooks.js +1 -0
  244. package/dist/dashboard/(bookings)/resources/_lib/presets.js +147 -0
  245. package/dist/dashboard/(bookings)/resources/_lib/presets.js.map +1 -0
  246. package/dist/dashboard/(bookings)/resources/_lib/schedule-timezone.js +17 -0
  247. package/dist/dashboard/(bookings)/resources/_lib/schedule-timezone.js.map +1 -0
  248. package/dist/dashboard/(bookings)/resources/_lib/shapes.js +105 -0
  249. package/dist/dashboard/(bookings)/resources/_lib/shapes.js.map +1 -0
  250. package/dist/dashboard/(bookings)/resources/_lib/week.js +122 -0
  251. package/dist/dashboard/(bookings)/resources/_lib/week.js.map +1 -0
  252. package/dist/dashboard/(bookings)/resources/page.js +391 -0
  253. package/dist/dashboard/(bookings)/resources/page.js.map +1 -0
  254. package/dist/dashboard/(bookings)/schedule/page.js +8 -0
  255. package/dist/dashboard/(bookings)/schedule/page.js.map +1 -0
  256. package/dist/dashboard/(bookings)/today/page.js +14 -0
  257. package/dist/dashboard/(bookings)/today/page.js.map +1 -0
  258. package/dist/dashboard/(bookings)/waitlist/_components/demo-data.js +99 -0
  259. package/dist/dashboard/(bookings)/waitlist/_components/demo-data.js.map +1 -0
  260. package/dist/dashboard/(bookings)/waitlist/_components/offer-spot-modal.js +71 -0
  261. package/dist/dashboard/(bookings)/waitlist/_components/offer-spot-modal.js.map +1 -0
  262. package/dist/dashboard/(bookings)/waitlist/_components/waitlist-entry-editor.js +150 -0
  263. package/dist/dashboard/(bookings)/waitlist/_components/waitlist-entry-editor.js.map +1 -0
  264. package/dist/dashboard/(bookings)/waitlist/new/page.js +59 -0
  265. package/dist/dashboard/(bookings)/waitlist/new/page.js.map +1 -0
  266. package/dist/dashboard/(bookings)/waitlist/page.js +317 -0
  267. package/dist/dashboard/(bookings)/waitlist/page.js.map +1 -0
  268. package/dist/index.js +1 -0
  269. package/dist/index.js.map +1 -0
  270. package/package.json +60 -0
@@ -0,0 +1,714 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useMemo, useState } from "react";
4
+ import Link from "next/link";
5
+ import { useQueryClient } from "@tanstack/react-query";
6
+ import { CalendarClock, Plus } from "lucide-react";
7
+ import {
8
+ ListPage,
9
+ ListStates,
10
+ StateView,
11
+ Card,
12
+ Field,
13
+ Select,
14
+ Button,
15
+ useToast,
16
+ Dialog,
17
+ DialogContent,
18
+ DialogHeader,
19
+ DialogTitle,
20
+ OptionButton
21
+ } from "@withpotter/ui-kit";
22
+ import { useApiQuery } from "@withpotter/hooks/use-api-query";
23
+ import { useAuth } from "@withpotter/lib/auth-context";
24
+ import { bookingsApi } from "@withpotter/lib/api/bookings";
25
+ import { bookingCalendarApi } from "@withpotter/lib/api/booking-calendar";
26
+ import { ApiRequestError } from "@withpotter/lib/api/core";
27
+ import { resourcesApi } from "@withpotter/lib/api/resources";
28
+ import { inventoryApi } from "@withpotter/lib/api/inventory";
29
+ import { BlockTimeModal } from "@withpotter/pages-bookings/dashboard/(bookings)/resources/_components/block-time-modal";
30
+ import {
31
+ ScheduleEditor,
32
+ getDefaultSchedule
33
+ } from "@withpotter/pages-bookings/dashboard/(bookings)/resources/_components/schedule-editor";
34
+ import { timezoneOptions } from "@withpotter/pages-bookings/dashboard/(bookings)/resources/_lib/schedule-timezone";
35
+ import { MonthAvailability } from "./month-availability";
36
+ const DURATIONS = [10, 15, 20, 30, 45, 60, 90, 120];
37
+ function isoDate(d) {
38
+ const month = String(d.getMonth() + 1).padStart(2, "0");
39
+ const day = String(d.getDate()).padStart(2, "0");
40
+ return `${d.getFullYear()}-${month}-${day}`;
41
+ }
42
+ function formatSelectedDateRange(dates) {
43
+ const sorted = [...dates].sort();
44
+ const format = (date) => (/* @__PURE__ */ new Date(`${date}T00:00:00`)).toLocaleDateString(void 0, {
45
+ month: "short",
46
+ day: "numeric"
47
+ });
48
+ if (sorted.length <= 1) return format(sorted[0]);
49
+ return `${format(sorted[0])}\u2013${format(sorted[sorted.length - 1])}`;
50
+ }
51
+ function formatBlockedRange(startValue, endValue) {
52
+ const start = new Date(startValue);
53
+ const end = new Date(endValue);
54
+ const date = start.toLocaleDateString(void 0, {
55
+ day: "numeric",
56
+ month: "short"
57
+ });
58
+ const time = (value) => value.toLocaleTimeString(void 0, {
59
+ hour: "numeric",
60
+ minute: "2-digit"
61
+ });
62
+ return `${date} \xB7 ${time(start)}\u2013${time(end)}`;
63
+ }
64
+ function validateSchedule(schedule) {
65
+ for (let day = 0; day < 7; day++) {
66
+ const entry = schedule[day];
67
+ if (!entry?.available) continue;
68
+ if (!entry.slots?.length)
69
+ return "Every open day needs at least one time slot.";
70
+ const slots = [...entry.slots].sort(
71
+ (a, b) => a.start.localeCompare(b.start)
72
+ );
73
+ for (const slot of slots) {
74
+ if (!/^\d{2}:\d{2}$/.test(slot.start) || !/^\d{2}:\d{2}$/.test(slot.end)) {
75
+ return "Enter a valid opening and closing time.";
76
+ }
77
+ if (slot.end <= slot.start) {
78
+ return "A closing time must be later than its opening time.";
79
+ }
80
+ }
81
+ for (let index = 1; index < slots.length; index++) {
82
+ if (slots[index].start < slots[index - 1].end) {
83
+ return "Time slots on the same day cannot overlap.";
84
+ }
85
+ }
86
+ }
87
+ return null;
88
+ }
89
+ function AvailabilityScreen({
90
+ embedded = false
91
+ }) {
92
+ const { tenant } = useAuth();
93
+ const { toast } = useToast();
94
+ const queryClient = useQueryClient();
95
+ const availabilityQueryKey = (resource2) => tenant?.slug ? ["availability", resource2] : null;
96
+ function invalidateAvailability(resource2) {
97
+ const queryKey = availabilityQueryKey(resource2);
98
+ return queryKey ? queryClient.invalidateQueries({ queryKey }) : Promise.resolve();
99
+ }
100
+ const [savingDuration, setSavingDuration] = useState(false);
101
+ const [savingTimezone, setSavingTimezone] = useState(false);
102
+ const [savingWeek, setSavingWeek] = useState(false);
103
+ const [draftSchedule, setDraftSchedule] = useState(
104
+ null
105
+ );
106
+ const [selectedResourceId, setSelectedResourceId] = useState("");
107
+ const [showBlockModal, setShowBlockModal] = useState(false);
108
+ const [savingBlock, setSavingBlock] = useState(false);
109
+ const [blockError, setBlockError] = useState(null);
110
+ const [unblockingEventId, setUnblockingEventId] = useState(
111
+ null
112
+ );
113
+ const [selectedDates, setSelectedDates] = useState([]);
114
+ const [showBlockCalendar, setShowBlockCalendar] = useState(false);
115
+ const [blockDate, setBlockDate] = useState(null);
116
+ const [savingOpen, setSavingOpen] = useState(false);
117
+ const [previewMonth, setPreviewMonth] = useState(() => {
118
+ const today = /* @__PURE__ */ new Date();
119
+ return new Date(today.getFullYear(), today.getMonth(), 1);
120
+ });
121
+ const { from, to } = useMemo(() => {
122
+ const end = new Date(
123
+ previewMonth.getFullYear(),
124
+ previewMonth.getMonth() + 1,
125
+ 0
126
+ );
127
+ return { from: isoDate(previewMonth), to: isoDate(end) };
128
+ }, [previewMonth]);
129
+ const resources = useApiQuery(
130
+ ["availability", "resources"],
131
+ (slug) => resourcesApi.list(slug),
132
+ { live: true }
133
+ );
134
+ const activeResources = useMemo(
135
+ () => (resources.data?.data ?? []).filter((r) => r.status === "active"),
136
+ [resources.data]
137
+ );
138
+ const resource = activeResources.find((r) => r.id === selectedResourceId) ?? activeResources[0];
139
+ const services = useApiQuery(
140
+ ["availability", "services"],
141
+ (slug) => inventoryApi.list(
142
+ slug,
143
+ { behavior: "bookable" },
144
+ { assignedOnly: false }
145
+ ),
146
+ { live: true }
147
+ );
148
+ const [selectedServiceId, setSelectedServiceId] = useState("");
149
+ const service = services.data?.items.find((item) => item.id === selectedServiceId) ?? services.data?.items[0];
150
+ const duration = service?.behaviors?.bookable?.durationMinutes ?? resource?.defaultDurationMinutes ?? 30;
151
+ const availability = useApiQuery(
152
+ ["availability", "slots", resource?.id ?? "", from, to, duration],
153
+ (slug) => bookingsApi.availability(slug, {
154
+ resourceId: resource.id,
155
+ dateFrom: from,
156
+ dateTo: to,
157
+ duration
158
+ }),
159
+ { enabled: Boolean(resource?.id), live: true }
160
+ );
161
+ const events = useApiQuery(
162
+ ["availability", "events", from, to],
163
+ (slug) => bookingCalendarApi.getEvents(slug, from, to),
164
+ { enabled: Boolean(resource?.id), live: true }
165
+ );
166
+ const days = useMemo(() => {
167
+ const byDate = /* @__PURE__ */ new Map();
168
+ for (const slot of availability.data?.slots ?? []) {
169
+ const list = byDate.get(slot.date) ?? [];
170
+ list.push(slot);
171
+ byDate.set(slot.date, list);
172
+ }
173
+ const bookedByDate = /* @__PURE__ */ new Map();
174
+ for (const ev of events.data ?? []) {
175
+ const start = new Date(ev.start);
176
+ const key = isoDate(start);
177
+ const list = bookedByDate.get(key) ?? [];
178
+ list.push({
179
+ startTime: start.toTimeString().slice(0, 5),
180
+ title: ev.title
181
+ });
182
+ bookedByDate.set(key, list);
183
+ }
184
+ const out = [];
185
+ const cursor = /* @__PURE__ */ new Date(`${from}T00:00:00`);
186
+ const end = /* @__PURE__ */ new Date(`${to}T00:00:00`);
187
+ while (cursor <= end) {
188
+ const key = isoDate(cursor);
189
+ const slots = byDate.get(key) ?? [];
190
+ out.push({
191
+ date: key,
192
+ weekday: cursor.toLocaleDateString(void 0, { weekday: "short" }),
193
+ label: cursor.toLocaleDateString(void 0, {
194
+ day: "numeric",
195
+ month: "long"
196
+ }),
197
+ slots,
198
+ bookings: bookedByDate.get(key) ?? [],
199
+ closed: slots.length === 0
200
+ });
201
+ cursor.setDate(cursor.getDate() + 1);
202
+ }
203
+ return out;
204
+ }, [availability.data, events.data, from, to]);
205
+ const blockedEvents = useMemo(
206
+ () => (events.data ?? []).filter((event) => event.type === "block").sort((a, b) => a.start.localeCompare(b.start)),
207
+ [events.data]
208
+ );
209
+ const schedule = draftSchedule ?? resource?.schedule ?? getDefaultSchedule();
210
+ function selectDate(date) {
211
+ if (date < isoDate(/* @__PURE__ */ new Date())) {
212
+ toast({
213
+ title: "Past dates cannot be changed",
214
+ variant: "destructive"
215
+ });
216
+ return;
217
+ }
218
+ setSelectedDates((current) => {
219
+ if (current.includes(date))
220
+ return current.filter((item) => item !== date);
221
+ if (current.length === 0) return [date];
222
+ const first = /* @__PURE__ */ new Date(`${current[0]}T00:00:00`);
223
+ const last = /* @__PURE__ */ new Date(`${date}T00:00:00`);
224
+ const start = first < last ? first : last;
225
+ const end = first < last ? last : first;
226
+ const range = [];
227
+ for (const cursor = new Date(start); cursor <= end; ) {
228
+ range.push(isoDate(cursor));
229
+ cursor.setDate(cursor.getDate() + 1);
230
+ }
231
+ return range;
232
+ });
233
+ }
234
+ async function openSelectedDates() {
235
+ if (!tenant?.slug || !resource || selectedDates.length === 0) return;
236
+ setSavingOpen(true);
237
+ try {
238
+ const sorted = [...selectedDates].sort();
239
+ const alreadyOpen = sorted.filter(
240
+ (date) => days.find((day) => day.date === date)?.slots.some((slot) => slot.available) ?? false
241
+ );
242
+ const blockedDates = new Set(
243
+ blockedEvents.map((event) => isoDate(new Date(event.start)))
244
+ );
245
+ const datesToUnblock = sorted.filter(
246
+ (date) => !alreadyOpen.includes(date) && blockedDates.has(date)
247
+ );
248
+ if (datesToUnblock.length === 0 && alreadyOpen.length > 0) {
249
+ const label = alreadyOpen.length === sorted.length ? "These dates are already open for bookings." : `${alreadyOpen.length} selected date${alreadyOpen.length === 1 ? "" : "s"} already have booking slots.`;
250
+ toast({
251
+ title: "Availability already open",
252
+ description: label
253
+ });
254
+ return;
255
+ }
256
+ if (datesToUnblock.length === 0) {
257
+ toast({
258
+ title: "No availability block found",
259
+ description: "This date is controlled by the weekly schedule. Update the schedule to open it."
260
+ });
261
+ return;
262
+ }
263
+ await Promise.all(
264
+ datesToUnblock.map(
265
+ (date) => bookingCalendarApi.unblockTime(
266
+ tenant.slug,
267
+ resource.id,
268
+ date,
269
+ "00:00"
270
+ )
271
+ )
272
+ );
273
+ await Promise.all([
274
+ invalidateAvailability("slots"),
275
+ invalidateAvailability("events")
276
+ ]);
277
+ setSelectedDates([]);
278
+ setShowBlockCalendar(false);
279
+ toast({
280
+ title: alreadyOpen.length > 0 ? "Availability updated" : "Availability added"
281
+ });
282
+ } catch (error) {
283
+ toast({
284
+ title: "Could not add availability",
285
+ description: error instanceof ApiRequestError ? error.message : "Please try again. If the problem continues, check the service and provider setup.",
286
+ variant: "destructive"
287
+ });
288
+ } finally {
289
+ setSavingOpen(false);
290
+ }
291
+ }
292
+ async function saveDuration(minutes) {
293
+ if (!tenant?.slug || !service && !resource) return;
294
+ setSavingDuration(true);
295
+ try {
296
+ if (service) {
297
+ const behaviors = service.behaviors ?? {};
298
+ const bookable = behaviors.bookable ?? {};
299
+ const data = service.data ?? {};
300
+ await inventoryApi.update(tenant.slug, service.id, {
301
+ ...service,
302
+ behaviors: {
303
+ ...behaviors,
304
+ bookable: { ...bookable, durationMinutes: minutes }
305
+ },
306
+ // The data blob's own copy wins at save time; write both to agree.
307
+ data: { ...data, durationMinutes: minutes }
308
+ });
309
+ await Promise.all([
310
+ invalidateAvailability("services"),
311
+ invalidateAvailability("slots")
312
+ ]);
313
+ } else {
314
+ await resourcesApi.update(tenant.slug, resource.id, {
315
+ defaultDurationMinutes: minutes
316
+ });
317
+ await invalidateAvailability("resources");
318
+ }
319
+ toast({ title: "Appointment length updated" });
320
+ } catch {
321
+ toast({
322
+ title: "Could not update the appointment length",
323
+ variant: "destructive"
324
+ });
325
+ } finally {
326
+ setSavingDuration(false);
327
+ }
328
+ }
329
+ async function saveTimezone(timezone) {
330
+ if (!tenant?.slug || !resource) return;
331
+ setSavingTimezone(true);
332
+ try {
333
+ await resourcesApi.update(tenant.slug, resource.id, { timezone });
334
+ await Promise.all([
335
+ invalidateAvailability("resources"),
336
+ invalidateAvailability("slots")
337
+ ]);
338
+ toast({ title: "Timezone updated" });
339
+ } catch {
340
+ toast({ title: "Could not update timezone", variant: "destructive" });
341
+ } finally {
342
+ setSavingTimezone(false);
343
+ }
344
+ }
345
+ async function saveWeek() {
346
+ if (!tenant?.slug || !resource || !draftSchedule) return;
347
+ const validationError = validateSchedule(draftSchedule);
348
+ if (validationError) {
349
+ toast({ title: validationError, variant: "destructive" });
350
+ return;
351
+ }
352
+ setSavingWeek(true);
353
+ try {
354
+ await resourcesApi.update(tenant.slug, resource.id, {
355
+ schedule: draftSchedule
356
+ });
357
+ await invalidateAvailability("resources");
358
+ setDraftSchedule(null);
359
+ toast({ title: "Availability updated" });
360
+ } catch {
361
+ toast({ title: "Could not update availability", variant: "destructive" });
362
+ } finally {
363
+ setSavingWeek(false);
364
+ }
365
+ }
366
+ async function blockTime(data) {
367
+ if (!tenant?.slug) return;
368
+ setSavingBlock(true);
369
+ setBlockError(null);
370
+ try {
371
+ await bookingCalendarApi.blockTime(tenant.slug, data);
372
+ await Promise.all([
373
+ invalidateAvailability("slots"),
374
+ invalidateAvailability("events")
375
+ ]);
376
+ setShowBlockModal(false);
377
+ setBlockDate(null);
378
+ setSelectedDates([]);
379
+ setShowBlockCalendar(false);
380
+ toast({ title: "Time blocked" });
381
+ } catch (error) {
382
+ setBlockError(
383
+ error instanceof Error ? error.message : "Could not block that time"
384
+ );
385
+ } finally {
386
+ setSavingBlock(false);
387
+ }
388
+ }
389
+ async function unblockTime(event) {
390
+ if (!tenant?.slug || !resource?.id) return;
391
+ setUnblockingEventId(event.id);
392
+ try {
393
+ const start = new Date(event.start);
394
+ const end = new Date(event.end);
395
+ await bookingCalendarApi.unblockTime(
396
+ tenant.slug,
397
+ event.resourceId ?? resource.id,
398
+ isoDate(start),
399
+ start.toTimeString().slice(0, 5),
400
+ isoDate(end) !== isoDate(start) ? isoDate(end) : void 0
401
+ );
402
+ await Promise.all([
403
+ invalidateAvailability("slots"),
404
+ invalidateAvailability("events")
405
+ ]);
406
+ toast({ title: "Time block removed" });
407
+ } catch {
408
+ toast({ title: "Could not remove time block", variant: "destructive" });
409
+ } finally {
410
+ setUnblockingEventId(null);
411
+ }
412
+ }
413
+ const loading = resources.isLoading || services.isLoading;
414
+ const pageError = resources.error?.message ?? services.error?.message ?? availability.error?.message ?? events.error?.message ?? null;
415
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
416
+ /* @__PURE__ */ jsx(
417
+ ListStates,
418
+ {
419
+ loading,
420
+ isEmpty: !loading && !resource,
421
+ error: pageError,
422
+ errorPlacement: "bottom",
423
+ onRetry: () => {
424
+ void resources.refetch();
425
+ void services.refetch();
426
+ void availability.refetch();
427
+ void events.refetch();
428
+ },
429
+ empty: /* @__PURE__ */ jsx(
430
+ StateView,
431
+ {
432
+ kind: "empty",
433
+ icon: CalendarClock,
434
+ title: "Nobody takes bookings yet",
435
+ description: "Add the person or space customers book, and their week shows up here.",
436
+ action: { label: "Add staff", href: "/dashboard/resources" }
437
+ }
438
+ ),
439
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
440
+ /* @__PURE__ */ jsxs(Card, { variant: "soft", children: [
441
+ service ? /* @__PURE__ */ jsxs("div", { className: "mb-4 border-b border-[var(--border-subtle)] pb-4", children: [
442
+ /* @__PURE__ */ jsxs("div", { className: "mb-2", children: [
443
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold text-[var(--text-primary)]", children: "Service" }),
444
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-xs text-[var(--text-secondary)]", children: "Choose a service to view its booking availability." })
445
+ ] }),
446
+ /* @__PURE__ */ jsx("div", { className: "grid gap-2 sm:grid-cols-2", children: (services.data?.items ?? []).map((item) => {
447
+ const itemDuration = item.behaviors?.bookable?.durationMinutes;
448
+ return /* @__PURE__ */ jsx(
449
+ OptionButton,
450
+ {
451
+ shape: "card",
452
+ selected: item.id === service.id,
453
+ onClick: () => setSelectedServiceId(item.id),
454
+ className: "text-left",
455
+ children: /* @__PURE__ */ jsxs("span", { className: "flex min-w-0 flex-col", children: [
456
+ /* @__PURE__ */ jsx("span", { className: "truncate font-medium", children: item.title }),
457
+ /* @__PURE__ */ jsx("span", { className: "mt-0.5 text-xs text-[var(--text-secondary)]", children: itemDuration ? `${itemDuration} minutes` : "Duration not set" })
458
+ ] })
459
+ },
460
+ item.id
461
+ );
462
+ }) })
463
+ ] }) : null,
464
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center justify-between gap-4", children: [
465
+ /* @__PURE__ */ jsxs("div", { children: [
466
+ /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-[var(--text-primary)]", children: "Appointment details" }),
467
+ !service && /* @__PURE__ */ jsx(
468
+ Button,
469
+ {
470
+ variant: "primary",
471
+ className: "mt-3 max-md:!min-h-9",
472
+ asChild: true,
473
+ children: /* @__PURE__ */ jsx(Link, { href: "/dashboard/catalog/new?intent=take-bookings", children: "Create a service" })
474
+ }
475
+ )
476
+ ] }),
477
+ /* @__PURE__ */ jsxs("div", { className: "grid w-full grid-cols-2 gap-3 sm:w-auto", children: [
478
+ activeResources.length > 1 ? /* @__PURE__ */ jsx(Field, { label: "Provider", children: /* @__PURE__ */ jsx(
479
+ Select,
480
+ {
481
+ value: resource?.id ?? "",
482
+ onChange: (value) => {
483
+ setSelectedResourceId(value);
484
+ setDraftSchedule(null);
485
+ setSelectedDates([]);
486
+ },
487
+ disabled: activeResources.length === 0,
488
+ ariaLabel: "Provider",
489
+ triggerClassName: "!min-h-11 !bg-[var(--bg-base)] !shadow-none !border-[var(--border-default)]",
490
+ options: activeResources.map((item) => ({
491
+ value: item.id,
492
+ label: item.name
493
+ }))
494
+ }
495
+ ) }) : null,
496
+ /* @__PURE__ */ jsx(Field, { label: "Duration", children: /* @__PURE__ */ jsx(
497
+ Select,
498
+ {
499
+ value: String(duration),
500
+ onChange: (v) => void saveDuration(Number(v)),
501
+ disabled: savingDuration || !service && !resource,
502
+ ariaLabel: "Duration",
503
+ triggerClassName: "!min-h-11 !bg-[var(--bg-base)] !shadow-none !border-[var(--border-default)]",
504
+ options: DURATIONS.map((m) => ({
505
+ value: String(m),
506
+ label: `${m} minutes`
507
+ }))
508
+ }
509
+ ) }),
510
+ /* @__PURE__ */ jsx(Field, { label: "Timezone", children: /* @__PURE__ */ jsx(
511
+ Select,
512
+ {
513
+ value: resource?.timezone ?? "Africa/Lagos",
514
+ onChange: (value) => void saveTimezone(value),
515
+ disabled: savingTimezone || !resource,
516
+ ariaLabel: "Resource timezone",
517
+ triggerClassName: "!min-h-11 !bg-[var(--bg-base)] !shadow-none !border-[var(--border-default)]",
518
+ options: timezoneOptions(
519
+ resource?.timezone ?? "Africa/Lagos"
520
+ ).map((option) => ({
521
+ value: option.value,
522
+ label: option.label
523
+ }))
524
+ }
525
+ ) })
526
+ ] })
527
+ ] })
528
+ ] }),
529
+ schedule ? /* @__PURE__ */ jsxs(Card, { variant: "soft", children: [
530
+ /* @__PURE__ */ jsx("div", { className: "mb-3", children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-[var(--text-primary)]", children: "Weekly hours" }) }) }),
531
+ /* @__PURE__ */ jsx(
532
+ ScheduleEditor,
533
+ {
534
+ schedule,
535
+ onChange: setDraftSchedule,
536
+ title: null,
537
+ layout: "week-grid"
538
+ }
539
+ ),
540
+ draftSchedule ? /* @__PURE__ */ jsxs("div", { className: "mt-4 flex flex-col gap-3 rounded-lg border border-[var(--border-default)] bg-[var(--bg-subtle)] p-4 sm:flex-row sm:items-center sm:justify-between", children: [
541
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--text-primary)]", children: "Weekly hours changed" }) }),
542
+ /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
543
+ /* @__PURE__ */ jsx(
544
+ Button,
545
+ {
546
+ variant: "secondary",
547
+ onClick: () => setDraftSchedule(null),
548
+ children: "Discard"
549
+ }
550
+ ),
551
+ /* @__PURE__ */ jsx(
552
+ Button,
553
+ {
554
+ onClick: () => void saveWeek(),
555
+ disabled: savingWeek,
556
+ children: savingWeek ? "Saving\u2026" : "Save hours"
557
+ }
558
+ )
559
+ ] })
560
+ ] }) : null
561
+ ] }) : null,
562
+ /* @__PURE__ */ jsxs(Card, { variant: "soft", children: [
563
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-3", children: [
564
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("h2", { className: "text-base font-semibold text-[var(--text-primary)]", children: "Booking schedule" }) }),
565
+ /* @__PURE__ */ jsx(
566
+ Button,
567
+ {
568
+ variant: "secondary",
569
+ onClick: () => setShowBlockCalendar(true),
570
+ disabled: !resource,
571
+ children: "Manage schedule"
572
+ }
573
+ )
574
+ ] }),
575
+ blockedEvents.length > 0 ? /* @__PURE__ */ jsx("div", { className: "mt-3 space-y-2 border-t border-[var(--border-subtle)] pt-3", children: blockedEvents.map((event) => /* @__PURE__ */ jsxs(
576
+ "div",
577
+ {
578
+ className: "surface-inset flex items-center justify-between gap-3 p-3",
579
+ children: [
580
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
581
+ /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-[var(--text-primary)]", children: formatBlockedRange(event.start, event.end) }),
582
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 truncate text-xs text-[var(--text-muted)]", children: event.title || "Blocked time" })
583
+ ] }),
584
+ /* @__PURE__ */ jsx(
585
+ Button,
586
+ {
587
+ variant: "ghostDanger",
588
+ size: "sm",
589
+ onClick: () => void unblockTime(event),
590
+ loading: unblockingEventId === event.id,
591
+ children: "Remove"
592
+ }
593
+ )
594
+ ]
595
+ },
596
+ event.id
597
+ )) }) : /* @__PURE__ */ jsxs("div", { className: "mt-3 flex items-center justify-between gap-3 border-t border-[var(--border-subtle)] pt-3", children: [
598
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--text-secondary)]", children: "No blocked time this month." }),
599
+ /* @__PURE__ */ jsx(
600
+ Button,
601
+ {
602
+ variant: "ghost",
603
+ size: "icon",
604
+ className: "max-md:!p-3",
605
+ "aria-label": "Add blocked time",
606
+ title: "Add blocked time",
607
+ onClick: () => setShowBlockCalendar(true),
608
+ disabled: !resource,
609
+ children: /* @__PURE__ */ jsx(Plus, {})
610
+ }
611
+ )
612
+ ] })
613
+ ] })
614
+ ] })
615
+ }
616
+ ),
617
+ /* @__PURE__ */ jsx(
618
+ Dialog,
619
+ {
620
+ open: showBlockCalendar,
621
+ onOpenChange: (open) => {
622
+ setShowBlockCalendar(open);
623
+ if (!open) {
624
+ setSelectedDates([]);
625
+ setShowBlockModal(false);
626
+ setBlockDate(null);
627
+ setBlockError(null);
628
+ }
629
+ },
630
+ children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-lg !gap-2 !p-4", children: [
631
+ /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { className: "text-xl", children: "Manage booking schedule" }) }),
632
+ /* @__PURE__ */ jsx(Card, { variant: "soft", padding: "sm", className: "mt-2", children: /* @__PURE__ */ jsx(
633
+ MonthAvailability,
634
+ {
635
+ month: previewMonth,
636
+ days,
637
+ selectedDates,
638
+ onSelectDate: selectDate,
639
+ onPrevious: () => setPreviewMonth(
640
+ (month) => new Date(month.getFullYear(), month.getMonth() - 1, 1)
641
+ ),
642
+ onNext: () => setPreviewMonth(
643
+ (month) => new Date(month.getFullYear(), month.getMonth() + 1, 1)
644
+ )
645
+ },
646
+ `${previewMonth.getFullYear()}-${previewMonth.getMonth()}`
647
+ ) }),
648
+ selectedDates.length > 0 ? showBlockModal && resource ? /* @__PURE__ */ jsx(
649
+ BlockTimeModal,
650
+ {
651
+ embedded: true,
652
+ resources: activeResources,
653
+ defaultResourceId: resource.id,
654
+ resourceLabel: "Provider",
655
+ defaultDate: blockDate ?? selectedDates[0],
656
+ defaultEndDate: selectedDates[selectedDates.length - 1],
657
+ dateRange: selectedDates.length > 1,
658
+ saving: savingBlock,
659
+ error: blockError,
660
+ onBlock: (data) => void blockTime(data),
661
+ onClose: () => {
662
+ if (!savingBlock) {
663
+ setShowBlockModal(false);
664
+ setBlockDate(null);
665
+ setBlockError(null);
666
+ }
667
+ }
668
+ }
669
+ ) : /* @__PURE__ */ jsxs(
670
+ "div",
671
+ {
672
+ className: "availability-selection-enter border-t border-[var(--border-subtle)] pt-4",
673
+ "aria-live": "polite",
674
+ children: [
675
+ /* @__PURE__ */ jsxs("div", { className: "mb-3 flex items-center justify-between gap-3", children: [
676
+ /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx("span", { className: "text-ink block text-sm font-medium", children: selectedDates.length === 1 ? formatSelectedDateRange(selectedDates) : `${formatSelectedDateRange(selectedDates)} selected` }) }),
677
+ /* @__PURE__ */ jsx(Button, { variant: "ghost", onClick: () => setSelectedDates([]), children: "Clear" })
678
+ ] }),
679
+ /* @__PURE__ */ jsx("p", { className: "text-ink-muted mt-3 text-sm", children: "Opening uses the resource's weekly hours. Existing date-specific blocks will be removed." }),
680
+ /* @__PURE__ */ jsxs("div", { className: "mt-3 grid grid-cols-2 gap-2", children: [
681
+ /* @__PURE__ */ jsx(
682
+ Button,
683
+ {
684
+ onClick: () => void openSelectedDates(),
685
+ loading: savingOpen,
686
+ children: selectedDates.length === 1 ? "Open this date" : "Open these dates"
687
+ }
688
+ ),
689
+ /* @__PURE__ */ jsx(
690
+ Button,
691
+ {
692
+ variant: "secondary",
693
+ onClick: () => {
694
+ setBlockDate(selectedDates[0] ?? null);
695
+ setShowBlockModal(true);
696
+ },
697
+ children: "Block this time"
698
+ }
699
+ )
700
+ ] })
701
+ ]
702
+ }
703
+ ) : null
704
+ ] })
705
+ }
706
+ )
707
+ ] });
708
+ if (embedded) return content;
709
+ return /* @__PURE__ */ jsx(ListPage, { largeTitle: true, title: "Availability", children: content });
710
+ }
711
+ export {
712
+ AvailabilityScreen
713
+ };
714
+ //# sourceMappingURL=availability-screen.js.map