@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 @@
1
+ {"version":3,"sources":["../../../../../src/dashboard/%28bookings%29/availability/_components/availability-screen.tsx"],"sourcesContent":["'use client';\n\nimport { useMemo, useState } from 'react';\nimport Link from 'next/link';\nimport { useQueryClient } from '@tanstack/react-query';\nimport { CalendarClock, Plus } from 'lucide-react';\nimport {\n ListPage,\n ListStates,\n StateView,\n Card,\n Field,\n Select,\n Button,\n useToast,\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n OptionButton,\n} from '@withpotter/ui-kit';\nimport { useApiQuery } from '@withpotter/hooks/use-api-query';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { bookingsApi } from '@withpotter/lib/api/bookings';\nimport { bookingCalendarApi } from '@withpotter/lib/api/booking-calendar';\nimport { ApiRequestError } from '@withpotter/lib/api/core';\nimport { resourcesApi } from '@withpotter/lib/api/resources';\nimport { inventoryApi } from '@withpotter/lib/api/inventory';\nimport { BlockTimeModal } from '@withpotter/pages-bookings/dashboard/(bookings)/resources/_components/block-time-modal';\nimport {\n ScheduleEditor,\n getDefaultSchedule,\n} from '@withpotter/pages-bookings/dashboard/(bookings)/resources/_components/schedule-editor';\nimport { timezoneOptions } from '@withpotter/pages-bookings/dashboard/(bookings)/resources/_lib/schedule-timezone';\nimport type { WeeklySchedule } from '@withpotter/lib/resource-types';\nimport type { AvailableSlot } from '@withpotter/lib/api/types';\nimport { MonthAvailability } from './month-availability';\nconst DURATIONS = [10, 15, 20, 30, 45, 60, 90, 120];\n\ninterface DayBooking {\n startTime: string;\n title: string;\n}\n\nfunction isoDate(d: Date): string {\n const month = String(d.getMonth() + 1).padStart(2, '0');\n const day = String(d.getDate()).padStart(2, '0');\n return `${d.getFullYear()}-${month}-${day}`;\n}\n\nfunction formatSelectedDateRange(dates: string[]): string {\n const sorted = [...dates].sort();\n const format = (date: string) =>\n new Date(`${date}T00:00:00`).toLocaleDateString(undefined, {\n month: 'short',\n day: 'numeric',\n });\n if (sorted.length <= 1) return format(sorted[0]);\n return `${format(sorted[0])}–${format(sorted[sorted.length - 1])}`;\n}\n\nfunction formatBlockedRange(startValue: string, endValue: string): string {\n const start = new Date(startValue);\n const end = new Date(endValue);\n const date = start.toLocaleDateString(undefined, {\n day: 'numeric',\n month: 'short',\n });\n const time = (value: Date) =>\n value.toLocaleTimeString(undefined, {\n hour: 'numeric',\n minute: '2-digit',\n });\n return `${date} · ${time(start)}–${time(end)}`;\n}\n\nfunction validateSchedule(schedule: WeeklySchedule): string | null {\n for (let day = 0; day < 7; day++) {\n const entry = schedule[day];\n if (!entry?.available) continue;\n if (!entry.slots?.length)\n return 'Every open day needs at least one time slot.';\n\n const slots = [...entry.slots].sort((a, b) =>\n a.start.localeCompare(b.start),\n );\n for (const slot of slots) {\n if (\n !/^\\d{2}:\\d{2}$/.test(slot.start) ||\n !/^\\d{2}:\\d{2}$/.test(slot.end)\n ) {\n return 'Enter a valid opening and closing time.';\n }\n if (slot.end <= slot.start) {\n return 'A closing time must be later than its opening time.';\n }\n }\n for (let index = 1; index < slots.length; index++) {\n if (slots[index].start < slots[index - 1].end) {\n return 'Time slots on the same day cannot overlap.';\n }\n }\n }\n return null;\n}\n\nexport function AvailabilityScreen({\n embedded = false,\n}: {\n embedded?: boolean;\n}) {\n const { tenant } = useAuth();\n const { toast } = useToast();\n const queryClient = useQueryClient();\n const availabilityQueryKey = (\n resource: 'resources' | 'services' | 'slots' | 'events',\n ) => (tenant?.slug ? (['availability', resource] as const) : null);\n\n function invalidateAvailability(\n resource: 'resources' | 'services' | 'slots' | 'events',\n ) {\n const queryKey = availabilityQueryKey(resource);\n return queryKey\n ? queryClient.invalidateQueries({ queryKey })\n : Promise.resolve();\n }\n\n const [savingDuration, setSavingDuration] = useState(false);\n const [savingTimezone, setSavingTimezone] = useState(false);\n const [savingWeek, setSavingWeek] = useState(false);\n const [draftSchedule, setDraftSchedule] = useState<WeeklySchedule | null>(\n null,\n );\n const [selectedResourceId, setSelectedResourceId] = useState('');\n const [showBlockModal, setShowBlockModal] = useState(false);\n const [savingBlock, setSavingBlock] = useState(false);\n const [blockError, setBlockError] = useState<string | null>(null);\n const [unblockingEventId, setUnblockingEventId] = useState<string | null>(\n null,\n );\n const [selectedDates, setSelectedDates] = useState<string[]>([]);\n const [showBlockCalendar, setShowBlockCalendar] = useState(false);\n const [blockDate, setBlockDate] = useState<string | null>(null);\n const [savingOpen, setSavingOpen] = useState(false);\n const [previewMonth, setPreviewMonth] = useState(() => {\n const today = new Date();\n return new Date(today.getFullYear(), today.getMonth(), 1);\n });\n\n const { from, to } = useMemo(() => {\n const end = new Date(\n previewMonth.getFullYear(),\n previewMonth.getMonth() + 1,\n 0,\n );\n return { from: isoDate(previewMonth), to: isoDate(end) };\n }, [previewMonth]);\n\n const resources = useApiQuery(\n ['availability', 'resources'],\n (slug) => resourcesApi.list(slug),\n { live: true },\n );\n const activeResources = useMemo(\n () => (resources.data?.data ?? []).filter((r) => r.status === 'active'),\n [resources.data],\n );\n const resource =\n activeResources.find((r) => r.id === selectedResourceId) ??\n activeResources[0];\n\n const services = useApiQuery(\n ['availability', 'services'],\n (slug) =>\n inventoryApi.list(\n slug,\n { behavior: 'bookable' },\n { assignedOnly: false },\n ),\n { live: true },\n );\n const [selectedServiceId, setSelectedServiceId] = useState('');\n const service =\n services.data?.items.find((item) => item.id === selectedServiceId) ??\n services.data?.items[0];\n const duration =\n (\n service?.behaviors as\n { bookable?: { durationMinutes?: number } } | undefined\n )?.bookable?.durationMinutes ??\n resource?.defaultDurationMinutes ??\n 30;\n\n const availability = useApiQuery(\n ['availability', 'slots', resource?.id ?? '', from, to, duration],\n (slug) =>\n bookingsApi.availability(slug, {\n resourceId: resource!.id,\n dateFrom: from,\n dateTo: to,\n duration,\n }),\n { enabled: Boolean(resource?.id), live: true },\n );\n\n const events = useApiQuery(\n ['availability', 'events', from, to],\n (slug) => bookingCalendarApi.getEvents(slug, from, to),\n { enabled: Boolean(resource?.id), live: true },\n );\n\n const days = useMemo(() => {\n const byDate = new Map<string, AvailableSlot[]>();\n for (const slot of availability.data?.slots ?? []) {\n const list = byDate.get(slot.date) ?? [];\n list.push(slot);\n byDate.set(slot.date, list);\n }\n\n const bookedByDate = new Map<string, DayBooking[]>();\n for (const ev of events.data ?? []) {\n const start = new Date(ev.start);\n const key = isoDate(start);\n const list = bookedByDate.get(key) ?? [];\n list.push({\n startTime: start.toTimeString().slice(0, 5),\n title: ev.title,\n });\n bookedByDate.set(key, list);\n }\n\n const out = [];\n const cursor = new Date(`${from}T00:00:00`);\n const end = new Date(`${to}T00:00:00`);\n while (cursor <= end) {\n const key = isoDate(cursor);\n const slots = byDate.get(key) ?? [];\n out.push({\n date: key,\n weekday: cursor.toLocaleDateString(undefined, { weekday: 'short' }),\n label: cursor.toLocaleDateString(undefined, {\n day: 'numeric',\n month: 'long',\n }),\n slots,\n bookings: bookedByDate.get(key) ?? [],\n closed: slots.length === 0,\n });\n cursor.setDate(cursor.getDate() + 1);\n }\n return out;\n }, [availability.data, events.data, from, to]);\n\n const blockedEvents = useMemo(\n () =>\n (events.data ?? [])\n .filter((event) => event.type === 'block')\n .sort((a, b) => a.start.localeCompare(b.start)),\n [events.data],\n );\n\n const schedule =\n draftSchedule ??\n (resource?.schedule as WeeklySchedule | undefined) ??\n getDefaultSchedule();\n\n function selectDate(date: string) {\n if (date < isoDate(new Date())) {\n toast({\n title: 'Past dates cannot be changed',\n variant: 'destructive',\n });\n return;\n }\n setSelectedDates((current) => {\n if (current.includes(date))\n return current.filter((item) => item !== date);\n if (current.length === 0) return [date];\n const first = new Date(`${current[0]}T00:00:00`);\n const last = new Date(`${date}T00:00:00`);\n const start = first < last ? first : last;\n const end = first < last ? last : first;\n const range: string[] = [];\n for (const cursor = new Date(start); cursor <= end;) {\n range.push(isoDate(cursor));\n cursor.setDate(cursor.getDate() + 1);\n }\n return range;\n });\n }\n\n async function openSelectedDates() {\n if (!tenant?.slug || !resource || selectedDates.length === 0) return;\n setSavingOpen(true);\n try {\n const sorted = [...selectedDates].sort();\n const alreadyOpen = sorted.filter(\n (date) =>\n days\n .find((day) => day.date === date)\n ?.slots.some((slot) => slot.available) ?? false,\n );\n const blockedDates = new Set(\n blockedEvents.map((event) => isoDate(new Date(event.start))),\n );\n const datesToUnblock = sorted.filter(\n (date) => !alreadyOpen.includes(date) && blockedDates.has(date),\n );\n\n if (datesToUnblock.length === 0 && alreadyOpen.length > 0) {\n const label =\n alreadyOpen.length === sorted.length\n ? 'These dates are already open for bookings.'\n : `${alreadyOpen.length} selected date${alreadyOpen.length === 1 ? '' : 's'} already have booking slots.`;\n toast({\n title: 'Availability already open',\n description: label,\n });\n return;\n }\n if (datesToUnblock.length === 0) {\n toast({\n title: 'No availability block found',\n description:\n 'This date is controlled by the weekly schedule. Update the schedule to open it.',\n });\n return;\n }\n await Promise.all(\n datesToUnblock.map((date) =>\n bookingCalendarApi.unblockTime(\n tenant.slug,\n resource.id,\n date,\n '00:00',\n ),\n ),\n );\n await Promise.all([\n invalidateAvailability('slots'),\n invalidateAvailability('events'),\n ]);\n setSelectedDates([]);\n setShowBlockCalendar(false);\n toast({\n title:\n alreadyOpen.length > 0\n ? 'Availability updated'\n : 'Availability added',\n });\n } catch (error) {\n toast({\n title: 'Could not add availability',\n description:\n error instanceof ApiRequestError\n ? error.message\n : 'Please try again. If the problem continues, check the service and provider setup.',\n variant: 'destructive',\n });\n } finally {\n setSavingOpen(false);\n }\n }\n\n async function saveDuration(minutes: number) {\n if (!tenant?.slug || (!service && !resource)) return;\n setSavingDuration(true);\n try {\n if (service) {\n const behaviors = (service.behaviors ?? {}) as Record<string, unknown>;\n const bookable = (behaviors.bookable ?? {}) as Record<string, unknown>;\n const data = (service.data ?? {}) as Record<string, unknown>;\n await inventoryApi.update(tenant.slug, service.id, {\n ...service,\n behaviors: {\n ...behaviors,\n bookable: { ...bookable, durationMinutes: minutes },\n },\n // The data blob's own copy wins at save time; write both to agree.\n data: { ...data, durationMinutes: minutes },\n });\n await Promise.all([\n invalidateAvailability('services'),\n invalidateAvailability('slots'),\n ]);\n } else {\n await resourcesApi.update(tenant.slug, resource!.id, {\n defaultDurationMinutes: minutes,\n });\n await invalidateAvailability('resources');\n }\n toast({ title: 'Appointment length updated' });\n } catch {\n toast({\n title: 'Could not update the appointment length',\n variant: 'destructive',\n });\n } finally {\n setSavingDuration(false);\n }\n }\n\n async function saveTimezone(timezone: string) {\n if (!tenant?.slug || !resource) return;\n setSavingTimezone(true);\n try {\n await resourcesApi.update(tenant.slug, resource.id, { timezone });\n await Promise.all([\n invalidateAvailability('resources'),\n invalidateAvailability('slots'),\n ]);\n toast({ title: 'Timezone updated' });\n } catch {\n toast({ title: 'Could not update timezone', variant: 'destructive' });\n } finally {\n setSavingTimezone(false);\n }\n }\n\n async function saveWeek() {\n if (!tenant?.slug || !resource || !draftSchedule) return;\n const validationError = validateSchedule(draftSchedule);\n if (validationError) {\n toast({ title: validationError, variant: 'destructive' });\n return;\n }\n setSavingWeek(true);\n try {\n await resourcesApi.update(tenant.slug, resource.id, {\n schedule: draftSchedule,\n });\n await invalidateAvailability('resources');\n setDraftSchedule(null);\n toast({ title: 'Availability updated' });\n } catch {\n toast({ title: 'Could not update availability', variant: 'destructive' });\n } finally {\n setSavingWeek(false);\n }\n }\n\n async function blockTime(data: {\n resourceId: string;\n date: string;\n endDate?: string;\n startTime: string;\n endTime: string;\n reason?: string;\n }) {\n if (!tenant?.slug) return;\n setSavingBlock(true);\n setBlockError(null);\n try {\n await bookingCalendarApi.blockTime(tenant.slug, data);\n await Promise.all([\n invalidateAvailability('slots'),\n invalidateAvailability('events'),\n ]);\n setShowBlockModal(false);\n setBlockDate(null);\n setSelectedDates([]);\n setShowBlockCalendar(false);\n toast({ title: 'Time blocked' });\n } catch (error) {\n setBlockError(\n error instanceof Error ? error.message : 'Could not block that time',\n );\n } finally {\n setSavingBlock(false);\n }\n }\n\n async function unblockTime(event: {\n id: string;\n resourceId?: string;\n start: string;\n end: string;\n }) {\n if (!tenant?.slug || !resource?.id) return;\n setUnblockingEventId(event.id);\n try {\n const start = new Date(event.start);\n const end = new Date(event.end);\n await bookingCalendarApi.unblockTime(\n tenant.slug,\n event.resourceId ?? resource.id,\n isoDate(start),\n start.toTimeString().slice(0, 5),\n isoDate(end) !== isoDate(start) ? isoDate(end) : undefined,\n );\n await Promise.all([\n invalidateAvailability('slots'),\n invalidateAvailability('events'),\n ]);\n toast({ title: 'Time block removed' });\n } catch {\n toast({ title: 'Could not remove time block', variant: 'destructive' });\n } finally {\n setUnblockingEventId(null);\n }\n }\n\n const loading = resources.isLoading || services.isLoading;\n const pageError =\n resources.error?.message ??\n services.error?.message ??\n availability.error?.message ??\n events.error?.message ??\n null;\n\n const content = (\n <>\n <ListStates\n loading={loading}\n isEmpty={!loading && !resource}\n error={pageError}\n errorPlacement=\"bottom\"\n onRetry={() => {\n void resources.refetch();\n void services.refetch();\n void availability.refetch();\n void events.refetch();\n }}\n empty={\n <StateView\n kind=\"empty\"\n icon={CalendarClock}\n title=\"Nobody takes bookings yet\"\n description=\"Add the person or space customers book, and their week shows up here.\"\n action={{ label: 'Add staff', href: '/dashboard/resources' }}\n />\n }\n >\n <div className=\"space-y-4\">\n <Card variant=\"soft\">\n {service ? (\n <div className=\"mb-4 border-b border-[var(--border-subtle)] pb-4\">\n <div className=\"mb-2\">\n <h3 className=\"text-sm font-semibold text-[var(--text-primary)]\">\n Service\n </h3>\n <p className=\"mt-0.5 text-xs text-[var(--text-secondary)]\">\n Choose a service to view its booking availability.\n </p>\n </div>\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {(services.data?.items ?? []).map((item) => {\n const itemDuration = (\n item.behaviors as\n { bookable?: { durationMinutes?: number } } | undefined\n )?.bookable?.durationMinutes;\n return (\n <OptionButton\n key={item.id}\n shape=\"card\"\n selected={item.id === service.id}\n onClick={() => setSelectedServiceId(item.id)}\n className=\"text-left\"\n >\n <span className=\"flex min-w-0 flex-col\">\n <span className=\"truncate font-medium\">\n {item.title}\n </span>\n <span className=\"mt-0.5 text-xs text-[var(--text-secondary)]\">\n {itemDuration\n ? `${itemDuration} minutes`\n : 'Duration not set'}\n </span>\n </span>\n </OptionButton>\n );\n })}\n </div>\n </div>\n ) : null}\n <div className=\"flex flex-wrap items-center justify-between gap-4\">\n <div>\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">\n Appointment details\n </h2>\n {!service && (\n <Button\n variant=\"primary\"\n className=\"mt-3 max-md:!min-h-9\"\n asChild\n >\n <Link href=\"/dashboard/catalog/new?intent=take-bookings\">\n Create a service\n </Link>\n </Button>\n )}\n </div>\n <div className=\"grid w-full grid-cols-2 gap-3 sm:w-auto\">\n {activeResources.length > 1 ? (\n <Field label=\"Provider\">\n <Select\n value={resource?.id ?? ''}\n onChange={(value) => {\n setSelectedResourceId(value);\n setDraftSchedule(null);\n setSelectedDates([]);\n }}\n disabled={activeResources.length === 0}\n ariaLabel=\"Provider\"\n triggerClassName=\"!min-h-11 !bg-[var(--bg-base)] !shadow-none !border-[var(--border-default)]\"\n options={activeResources.map((item) => ({\n value: item.id,\n label: item.name,\n }))}\n />\n </Field>\n ) : null}\n <Field label=\"Duration\">\n <Select\n value={String(duration)}\n onChange={(v) => void saveDuration(Number(v))}\n disabled={savingDuration || (!service && !resource)}\n ariaLabel=\"Duration\"\n triggerClassName=\"!min-h-11 !bg-[var(--bg-base)] !shadow-none !border-[var(--border-default)]\"\n options={DURATIONS.map((m) => ({\n value: String(m),\n label: `${m} minutes`,\n }))}\n />\n </Field>\n <Field label=\"Timezone\">\n <Select\n value={resource?.timezone ?? 'Africa/Lagos'}\n onChange={(value) => void saveTimezone(value)}\n disabled={savingTimezone || !resource}\n ariaLabel=\"Resource timezone\"\n triggerClassName=\"!min-h-11 !bg-[var(--bg-base)] !shadow-none !border-[var(--border-default)]\"\n options={timezoneOptions(\n resource?.timezone ?? 'Africa/Lagos',\n ).map((option) => ({\n value: option.value,\n label: option.label,\n }))}\n />\n </Field>\n </div>\n </div>\n </Card>\n\n {schedule ? (\n <Card variant=\"soft\">\n <div className=\"mb-3\">\n <div>\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">\n Weekly hours\n </h2>\n </div>\n </div>\n <ScheduleEditor\n schedule={schedule}\n onChange={setDraftSchedule}\n title={null}\n layout=\"week-grid\"\n />\n {draftSchedule ? (\n <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\">\n <div>\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\n Weekly hours changed\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button\n variant=\"secondary\"\n onClick={() => setDraftSchedule(null)}\n >\n Discard\n </Button>\n <Button\n onClick={() => void saveWeek()}\n disabled={savingWeek}\n >\n {savingWeek ? 'Saving…' : 'Save hours'}\n </Button>\n </div>\n </div>\n ) : null}\n </Card>\n ) : null}\n\n <Card variant=\"soft\">\n <div className=\"flex items-center justify-between gap-3\">\n <div>\n <h2 className=\"text-base font-semibold text-[var(--text-primary)]\">\n Booking schedule\n </h2>\n </div>\n <Button\n variant=\"secondary\"\n onClick={() => setShowBlockCalendar(true)}\n disabled={!resource}\n >\n Manage schedule\n </Button>\n </div>\n {blockedEvents.length > 0 ? (\n <div className=\"mt-3 space-y-2 border-t border-[var(--border-subtle)] pt-3\">\n {blockedEvents.map((event) => (\n <div\n key={event.id}\n className=\"surface-inset flex items-center justify-between gap-3 p-3\"\n >\n <div className=\"min-w-0\">\n <p className=\"text-sm font-medium text-[var(--text-primary)]\">\n {formatBlockedRange(event.start, event.end)}\n </p>\n <p className=\"mt-0.5 truncate text-xs text-[var(--text-muted)]\">\n {event.title || 'Blocked time'}\n </p>\n </div>\n <Button\n variant=\"ghostDanger\"\n size=\"sm\"\n onClick={() => void unblockTime(event)}\n loading={unblockingEventId === event.id}\n >\n Remove\n </Button>\n </div>\n ))}\n </div>\n ) : (\n <div className=\"mt-3 flex items-center justify-between gap-3 border-t border-[var(--border-subtle)] pt-3\">\n <p className=\"text-sm text-[var(--text-secondary)]\">\n No blocked time this month.\n </p>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n className=\"max-md:!p-3\"\n aria-label=\"Add blocked time\"\n title=\"Add blocked time\"\n onClick={() => setShowBlockCalendar(true)}\n disabled={!resource}\n >\n <Plus />\n </Button>\n </div>\n )}\n </Card>\n </div>\n </ListStates>\n <Dialog\n open={showBlockCalendar}\n onOpenChange={(open) => {\n setShowBlockCalendar(open);\n if (!open) {\n setSelectedDates([]);\n setShowBlockModal(false);\n setBlockDate(null);\n setBlockError(null);\n }\n }}\n >\n <DialogContent className=\"max-w-lg !gap-2 !p-4\">\n <DialogHeader>\n <DialogTitle className=\"text-xl\">\n Manage booking schedule\n </DialogTitle>\n </DialogHeader>\n <Card variant=\"soft\" padding=\"sm\" className=\"mt-2\">\n <MonthAvailability\n key={`${previewMonth.getFullYear()}-${previewMonth.getMonth()}`}\n month={previewMonth}\n days={days}\n selectedDates={selectedDates}\n onSelectDate={selectDate}\n onPrevious={() =>\n setPreviewMonth(\n (month) =>\n new Date(month.getFullYear(), month.getMonth() - 1, 1),\n )\n }\n onNext={() =>\n setPreviewMonth(\n (month) =>\n new Date(month.getFullYear(), month.getMonth() + 1, 1),\n )\n }\n />\n </Card>\n {selectedDates.length > 0 ? (\n showBlockModal && resource ? (\n <BlockTimeModal\n embedded\n resources={activeResources}\n defaultResourceId={resource.id}\n resourceLabel=\"Provider\"\n defaultDate={blockDate ?? selectedDates[0]}\n defaultEndDate={selectedDates[selectedDates.length - 1]}\n dateRange={selectedDates.length > 1}\n saving={savingBlock}\n error={blockError}\n onBlock={(data) => void blockTime(data)}\n onClose={() => {\n if (!savingBlock) {\n setShowBlockModal(false);\n setBlockDate(null);\n setBlockError(null);\n }\n }}\n />\n ) : (\n <div\n className=\"availability-selection-enter border-t border-[var(--border-subtle)] pt-4\"\n aria-live=\"polite\"\n >\n <div className=\"mb-3 flex items-center justify-between gap-3\">\n <div>\n <span className=\"text-ink block text-sm font-medium\">\n {selectedDates.length === 1\n ? formatSelectedDateRange(selectedDates)\n : `${formatSelectedDateRange(selectedDates)} selected`}\n </span>\n </div>\n <Button variant=\"ghost\" onClick={() => setSelectedDates([])}>\n Clear\n </Button>\n </div>\n <p className=\"text-ink-muted mt-3 text-sm\">\n Opening uses the resource&apos;s weekly hours. Existing\n date-specific blocks will be removed.\n </p>\n <div className=\"mt-3 grid grid-cols-2 gap-2\">\n <Button\n onClick={() => void openSelectedDates()}\n loading={savingOpen}\n >\n {selectedDates.length === 1\n ? 'Open this date'\n : 'Open these dates'}\n </Button>\n <Button\n variant=\"secondary\"\n onClick={() => {\n setBlockDate(selectedDates[0] ?? null);\n setShowBlockModal(true);\n }}\n >\n Block this time\n </Button>\n </div>\n </div>\n )\n ) : null}\n </DialogContent>\n </Dialog>\n </>\n );\n\n if (embedded) return content;\n return (\n <ListPage largeTitle title=\"Availability\">\n {content}\n </ListPage>\n );\n}\n"],"mappings":"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","names":["resource"]}
@@ -0,0 +1,130 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { ChevronLeft, ChevronRight } from "lucide-react";
4
+ const WEEKDAYS = ["M", "T", "W", "T", "F", "S", "S"];
5
+ function isoDate(date) {
6
+ return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, "0")}-${String(date.getDate()).padStart(2, "0")}`;
7
+ }
8
+ function MonthAvailability({
9
+ month,
10
+ days,
11
+ selectedDates,
12
+ onSelectDate,
13
+ onPrevious,
14
+ onNext
15
+ }) {
16
+ const today = isoDate(/* @__PURE__ */ new Date());
17
+ const isCurrentMonth = month.getFullYear() === (/* @__PURE__ */ new Date()).getFullYear() && month.getMonth() === (/* @__PURE__ */ new Date()).getMonth();
18
+ const firstDay = new Date(month.getFullYear(), month.getMonth(), 1);
19
+ const leadingDays = (firstDay.getDay() + 6) % 7;
20
+ const daysInMonth = new Date(
21
+ month.getFullYear(),
22
+ month.getMonth() + 1,
23
+ 0
24
+ ).getDate();
25
+ const daysByDate = new Map(days.map((day) => [day.date, day]));
26
+ const cells = Array.from(
27
+ { length: leadingDays + daysInMonth },
28
+ (_, index) => {
29
+ if (index < leadingDays) return null;
30
+ const date = new Date(
31
+ month.getFullYear(),
32
+ month.getMonth(),
33
+ index - leadingDays + 1
34
+ );
35
+ return {
36
+ date,
37
+ data: daysByDate.get(isoDate(date))
38
+ };
39
+ }
40
+ );
41
+ return /* @__PURE__ */ jsxs("div", { className: "availability-month-enter", children: [
42
+ /* @__PURE__ */ jsxs("div", { className: "mb-2 flex items-center justify-between", children: [
43
+ /* @__PURE__ */ jsx(
44
+ "button",
45
+ {
46
+ type: "button",
47
+ "aria-label": "Previous month",
48
+ onClick: onPrevious,
49
+ className: "rounded-lg p-2 text-[var(--text-secondary)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--interactive-hover)]",
50
+ children: /* @__PURE__ */ jsx(ChevronLeft, { className: "size-4" })
51
+ }
52
+ ),
53
+ /* @__PURE__ */ jsxs("div", { className: "text-center", "aria-live": "polite", children: [
54
+ /* @__PURE__ */ jsx("h2", { className: "text-ink text-sm font-medium", children: month.toLocaleDateString(void 0, {
55
+ month: "long",
56
+ year: "numeric"
57
+ }) }),
58
+ /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-3xs text-[var(--text-muted)]", children: isCurrentMonth ? "Your current month" : "Plan ahead" })
59
+ ] }),
60
+ /* @__PURE__ */ jsx(
61
+ "button",
62
+ {
63
+ type: "button",
64
+ "aria-label": "Next month",
65
+ onClick: onNext,
66
+ className: "rounded-lg p-2 text-[var(--text-secondary)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--interactive-hover)]",
67
+ children: /* @__PURE__ */ jsx(ChevronRight, { className: "size-4" })
68
+ }
69
+ )
70
+ ] }),
71
+ /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-7 gap-1", children: [
72
+ WEEKDAYS.map((day, index) => /* @__PURE__ */ jsx(
73
+ "span",
74
+ {
75
+ className: "pb-1 text-center text-3xs text-[var(--text-muted)]",
76
+ children: day
77
+ },
78
+ `${day}-${index}`
79
+ )),
80
+ cells.map(
81
+ (cell, index) => cell ? /* @__PURE__ */ jsxs(
82
+ "button",
83
+ {
84
+ type: "button",
85
+ "aria-pressed": selectedDates.includes(isoDate(cell.date)),
86
+ disabled: isoDate(cell.date) < today,
87
+ onClick: () => onSelectDate(isoDate(cell.date)),
88
+ "aria-label": `${cell.date.toLocaleDateString(void 0, {
89
+ dateStyle: "full"
90
+ })}, ${cell.data?.closed ? "closed" : `${cell.data?.slots.length ?? 0} slots available`}`,
91
+ className: `group relative min-h-9 rounded-lg border p-2 text-left transition-[background-color,border-color,box-shadow,transform] duration-[var(--motion-fast)] ${isoDate(cell.date) < today ? "cursor-not-allowed border-[var(--border-subtle)] bg-[var(--bg-muted)]/20 opacity-60" : selectedDates.includes(isoDate(cell.date)) ? "border-brand-500 bg-brand-50" : cell.date.toDateString() === (/* @__PURE__ */ new Date()).toDateString() ? "border-brand-500 bg-[var(--accent-secondary)]/30" : cell.data?.closed ? "border-[var(--border-subtle)] bg-[var(--bg-muted)]/30" : "border-[var(--border-subtle)] bg-[var(--bg-base)] hover:-translate-y-px hover:border-brand-500 hover:bg-[var(--accent-secondary)]/20"}`,
92
+ children: [
93
+ /* @__PURE__ */ jsxs("span", { className: "flex items-center justify-between", children: [
94
+ /* @__PURE__ */ jsx("span", { className: "text-ink text-xs font-medium", children: cell.date.getDate() }),
95
+ isoDate(cell.date) === today ? /* @__PURE__ */ jsx(
96
+ "span",
97
+ {
98
+ "aria-label": "Today",
99
+ title: "Today",
100
+ className: "size-1.5 rounded-full bg-brand-500"
101
+ }
102
+ ) : null
103
+ ] }),
104
+ /* @__PURE__ */ jsxs(
105
+ "span",
106
+ {
107
+ className: `mt-1 block text-3xs ${cell.data?.closed ? "text-[var(--text-muted)]" : "text-brand-600 group-hover:text-brand-700"}`,
108
+ children: [
109
+ /* @__PURE__ */ jsx(
110
+ "span",
111
+ {
112
+ className: `mr-1 inline-block size-1.5 rounded-full ${cell.data?.closed ? "bg-[var(--border-strong)]" : "bg-brand-500"}`
113
+ }
114
+ ),
115
+ cell.data?.closed ? "Closed" : `${cell.data?.slots.length ?? 0} slots`
116
+ ]
117
+ }
118
+ )
119
+ ]
120
+ },
121
+ isoDate(cell.date)
122
+ ) : /* @__PURE__ */ jsx("span", {}, `empty-${index}`)
123
+ )
124
+ ] })
125
+ ] });
126
+ }
127
+ export {
128
+ MonthAvailability
129
+ };
130
+ //# sourceMappingURL=month-availability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/dashboard/%28bookings%29/availability/_components/month-availability.tsx"],"sourcesContent":["'use client';\n\nimport { ChevronLeft, ChevronRight } from 'lucide-react';\nimport type { AvailableSlot } from '@withpotter/lib/api/types';\n\ninterface MonthDay {\n date: string;\n slots: AvailableSlot[];\n closed: boolean;\n}\n\ninterface MonthAvailabilityProps {\n month: Date;\n days: MonthDay[];\n selectedDates: string[];\n onSelectDate: (date: string) => void;\n onPrevious: () => void;\n onNext: () => void;\n}\n\nconst WEEKDAYS = ['M', 'T', 'W', 'T', 'F', 'S', 'S'];\n\nfunction isoDate(date: Date): string {\n return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;\n}\n\nexport function MonthAvailability({\n month,\n days,\n selectedDates,\n onSelectDate,\n onPrevious,\n onNext,\n}: MonthAvailabilityProps) {\n const today = isoDate(new Date());\n const isCurrentMonth =\n month.getFullYear() === new Date().getFullYear() &&\n month.getMonth() === new Date().getMonth();\n const firstDay = new Date(month.getFullYear(), month.getMonth(), 1);\n const leadingDays = (firstDay.getDay() + 6) % 7;\n const daysInMonth = new Date(\n month.getFullYear(),\n month.getMonth() + 1,\n 0,\n ).getDate();\n const daysByDate = new Map(days.map((day) => [day.date, day]));\n const cells = Array.from(\n { length: leadingDays + daysInMonth },\n (_, index) => {\n if (index < leadingDays) return null;\n const date = new Date(\n month.getFullYear(),\n month.getMonth(),\n index - leadingDays + 1,\n );\n return {\n date,\n data: daysByDate.get(isoDate(date)),\n };\n },\n );\n\n return (\n <div className=\"availability-month-enter\">\n <div className=\"mb-2 flex items-center justify-between\">\n <button\n type=\"button\"\n aria-label=\"Previous month\"\n onClick={onPrevious}\n className=\"rounded-lg p-2 text-[var(--text-secondary)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--interactive-hover)]\"\n >\n <ChevronLeft className=\"size-4\" />\n </button>\n <div className=\"text-center\" aria-live=\"polite\">\n <h2 className=\"text-ink text-sm font-medium\">\n {month.toLocaleDateString(undefined, {\n month: 'long',\n year: 'numeric',\n })}\n </h2>\n <p className=\"mt-0.5 text-3xs text-[var(--text-muted)]\">\n {isCurrentMonth ? 'Your current month' : 'Plan ahead'}\n </p>\n </div>\n <button\n type=\"button\"\n aria-label=\"Next month\"\n onClick={onNext}\n className=\"rounded-lg p-2 text-[var(--text-secondary)] transition-colors duration-[var(--motion-fast)] hover:bg-[var(--interactive-hover)]\"\n >\n <ChevronRight className=\"size-4\" />\n </button>\n </div>\n\n <div className=\"grid grid-cols-7 gap-1\">\n {WEEKDAYS.map((day, index) => (\n <span\n key={`${day}-${index}`}\n className=\"pb-1 text-center text-3xs text-[var(--text-muted)]\"\n >\n {day}\n </span>\n ))}\n {cells.map((cell, index) =>\n cell ? (\n <button\n type=\"button\"\n aria-pressed={selectedDates.includes(isoDate(cell.date))}\n disabled={isoDate(cell.date) < today}\n onClick={() => onSelectDate(isoDate(cell.date))}\n key={isoDate(cell.date)}\n aria-label={`${cell.date.toLocaleDateString(undefined, {\n dateStyle: 'full',\n })}, ${\n cell.data?.closed\n ? 'closed'\n : `${cell.data?.slots.length ?? 0} slots available`\n }`}\n className={`group relative min-h-9 rounded-lg border p-2 text-left transition-[background-color,border-color,box-shadow,transform] duration-[var(--motion-fast)] ${\n isoDate(cell.date) < today\n ? 'cursor-not-allowed border-[var(--border-subtle)] bg-[var(--bg-muted)]/20 opacity-60'\n : selectedDates.includes(isoDate(cell.date))\n ? 'border-brand-500 bg-brand-50'\n : cell.date.toDateString() === new Date().toDateString()\n ? 'border-brand-500 bg-[var(--accent-secondary)]/30'\n : cell.data?.closed\n ? 'border-[var(--border-subtle)] bg-[var(--bg-muted)]/30'\n : 'border-[var(--border-subtle)] bg-[var(--bg-base)] hover:-translate-y-px hover:border-brand-500 hover:bg-[var(--accent-secondary)]/20'\n }`}\n >\n <span className=\"flex items-center justify-between\">\n <span className=\"text-ink text-xs font-medium\">\n {cell.date.getDate()}\n </span>\n {isoDate(cell.date) === today ? (\n <span\n aria-label=\"Today\"\n title=\"Today\"\n className=\"size-1.5 rounded-full bg-brand-500\"\n />\n ) : null}\n </span>\n <span\n className={`mt-1 block text-3xs ${\n cell.data?.closed\n ? 'text-[var(--text-muted)]'\n : 'text-brand-600 group-hover:text-brand-700'\n }`}\n >\n <span\n className={`mr-1 inline-block size-1.5 rounded-full ${\n cell.data?.closed\n ? 'bg-[var(--border-strong)]'\n : 'bg-brand-500'\n }`}\n />\n {cell.data?.closed\n ? 'Closed'\n : `${cell.data?.slots.length ?? 0} slots`}\n </span>\n </button>\n ) : (\n <span key={`empty-${index}`} />\n ),\n )}\n </div>\n </div>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,10 @@
1
+ import { redirect } from "next/navigation";
2
+ const metadata = { title: "Availability" };
3
+ function AvailabilityPage() {
4
+ redirect("/dashboard/bookings?view=availability");
5
+ }
6
+ export {
7
+ AvailabilityPage as default,
8
+ metadata
9
+ };
10
+ //# sourceMappingURL=page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/dashboard/%28bookings%29/availability/page.tsx"],"sourcesContent":["import { redirect } from 'next/navigation';\n\nexport const metadata = { title: 'Availability' };\n\nexport default function AvailabilityPage() {\n redirect('/dashboard/bookings?view=availability');\n}\n"],"mappings":"AAAA,SAAS,gBAAgB;AAElB,MAAM,WAAW,EAAE,OAAO,eAAe;AAEjC,SAAR,mBAAoC;AACzC,WAAS,uCAAuC;AAClD;","names":[]}
@@ -0,0 +1,133 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { useAuth } from "@withpotter/lib/auth-context";
5
+ import { useApiQuery } from "@withpotter/hooks/use-api-query";
6
+ import { bookingsApi } from "@withpotter/lib/api/bookings";
7
+ import { resourcesApi } from "@withpotter/lib/api/resources";
8
+ import { FormDialog } from "@withpotter/ui-kit/form-dialog";
9
+ import { Button } from "@withpotter/ui-kit/button";
10
+ import { OptionButton } from "@withpotter/ui-kit/option-button";
11
+ import { Avatar } from "@withpotter/ui-kit";
12
+ function AssignResourceModal({
13
+ booking,
14
+ open,
15
+ onClose,
16
+ onAssigned
17
+ }) {
18
+ const { tenant } = useAuth();
19
+ const [picked, setPicked] = useState(
20
+ booking.resourceId ?? null
21
+ );
22
+ const [saving, setSaving] = useState(false);
23
+ const [error, setError] = useState(null);
24
+ const { data: requirements } = useApiQuery(
25
+ [
26
+ "eligible-resources",
27
+ booking.contentId ?? "",
28
+ booking.date ?? "",
29
+ booking.startTime ?? ""
30
+ ],
31
+ (slug) => bookingsApi.eligibleResources(slug, {
32
+ contentId: booking.contentId,
33
+ date: (booking.date ?? "").slice(0, 10),
34
+ ...booking.startTime ? { startTime: booking.startTime } : {},
35
+ ...booking.endTime ? { endTime: booking.endTime } : {}
36
+ }).catch(() => []),
37
+ { enabled: open && Boolean(booking.contentId && booking.date) }
38
+ );
39
+ const { data: roster } = useApiQuery(
40
+ ["resources"],
41
+ (slug) => resourcesApi.list(slug).catch(() => ({ data: [] })),
42
+ { enabled: open }
43
+ );
44
+ const eligible = (requirements ?? []).flatMap(
45
+ (req) => req.eligibleResources ?? []
46
+ );
47
+ const options = eligible.length ? eligible : roster?.data ?? [];
48
+ useEffect(() => {
49
+ if (open) {
50
+ setPicked(booking.resourceId ?? null);
51
+ setError(null);
52
+ }
53
+ }, [open, booking.resourceId]);
54
+ const save = async () => {
55
+ if (!tenant?.slug) return;
56
+ setSaving(true);
57
+ setError(null);
58
+ try {
59
+ await bookingsApi.update(tenant.slug, booking.id, {
60
+ // `null` unassigns; the API leaves the field alone when it is absent,
61
+ // so this is the only way to take somebody off.
62
+ resourceId: picked
63
+ });
64
+ onAssigned();
65
+ onClose();
66
+ } catch (err) {
67
+ setError(
68
+ err instanceof Error ? err.message : "Could not change who this is with."
69
+ );
70
+ } finally {
71
+ setSaving(false);
72
+ }
73
+ };
74
+ return /* @__PURE__ */ jsx(
75
+ FormDialog,
76
+ {
77
+ open,
78
+ title: booking.resourceId ? "Change who this is with" : "Assign someone",
79
+ onClose,
80
+ description: "Only this booking. The customer is not told it moved, because it has not.",
81
+ footer: /* @__PURE__ */ jsxs(Fragment, { children: [
82
+ /* @__PURE__ */ jsx(Button, { variant: "secondary", onClick: onClose, disabled: saving, children: "Cancel" }),
83
+ /* @__PURE__ */ jsx(
84
+ Button,
85
+ {
86
+ onClick: save,
87
+ loading: saving,
88
+ disabled: saving || picked === (booking.resourceId ?? null),
89
+ children: "Save"
90
+ }
91
+ )
92
+ ] }),
93
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
94
+ error && /* @__PURE__ */ jsx("p", { className: "rounded-lg bg-[var(--error-bg)] px-3 py-2 text-sm text-[var(--error)]", children: error }),
95
+ options.length === 0 ? /* @__PURE__ */ jsx("p", { className: "text-sm text-[var(--text-secondary)]", children: "Nobody on the roster can take this. Add a resource first, or check the service accepts one." }) : /* @__PURE__ */ jsx("div", { className: "grid gap-2 sm:grid-cols-2", children: options.map((resource) => /* @__PURE__ */ jsxs(
96
+ OptionButton,
97
+ {
98
+ shape: "card",
99
+ selected: picked === resource.id,
100
+ onClick: () => setPicked(resource.id),
101
+ className: "w-full justify-start gap-3 py-2 pl-3 text-left",
102
+ children: [
103
+ /* @__PURE__ */ jsx(
104
+ Avatar,
105
+ {
106
+ name: resource.name,
107
+ src: resource.photo?.url,
108
+ size: "xs"
109
+ }
110
+ ),
111
+ /* @__PURE__ */ jsx("span", { className: "min-w-0 truncate text-[var(--text-primary)]", children: resource.name })
112
+ ]
113
+ },
114
+ resource.id
115
+ )) }),
116
+ booking.resourceId && /* @__PURE__ */ jsx(
117
+ OptionButton,
118
+ {
119
+ shape: "card",
120
+ selected: picked === null,
121
+ onClick: () => setPicked(null),
122
+ className: "w-full justify-start py-2 pl-3 text-left",
123
+ children: "Nobody yet"
124
+ }
125
+ )
126
+ ] })
127
+ }
128
+ );
129
+ }
130
+ export {
131
+ AssignResourceModal
132
+ };
133
+ //# sourceMappingURL=assign-resource-modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../src/dashboard/%28bookings%29/bookings/%5BbookingId%5D/_components/assign-resource-modal.tsx"],"sourcesContent":["'use client';\n\nimport { useEffect, useState } from 'react';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { useApiQuery } from '@withpotter/hooks/use-api-query';\nimport { bookingsApi } from '@withpotter/lib/api/bookings';\nimport { resourcesApi } from '@withpotter/lib/api/resources';\nimport type { BookingItem, ResourceItem } from '@withpotter/lib/api/types';\nimport { FormDialog } from '@withpotter/ui-kit/form-dialog';\nimport { Button } from '@withpotter/ui-kit/button';\nimport { OptionButton } from '@withpotter/ui-kit/option-button';\nimport { Avatar } from '@withpotter/ui-kit';\n\n/**\n * Who serves a booking that already exists.\n *\n * IT COULD ONLY BE DECIDED ONCE. The create form asks — a service can require\n * a person, a room, a bay, a court — and after that the answer was frozen: a\n * booking taken with nobody on it could never be given a therapist, and one\n * taken against the wrong one could never be corrected. The record showed the\n * name as a fact with nothing to press, which is how a desk ends up keeping\n * the real rota in a notebook.\n *\n * Nothing here is a reschedule. The API grew `resourceId` on the booking's own\n * PUT for this, deliberately rather than reusing the reschedule route that\n * already accepted one: that route emits `booking.rescheduled`, and a resource\n * swap through it tells the customer their appointment moved from 9:05 to\n * 9:05. The desk changing who is on it is an edit, and the eligibility and\n * double-booking checks are the same either way.\n *\n * WHO IS OFFERED. `eligible-resources` answers \"who can serve THIS service at\n * THIS time\" — the right list, and the one the create form uses — but it only\n * fills `eligibleResources` where the strategy actually asks a human. On a\n * service that assigns by itself it comes back decided, with no list, and the\n * desk still needs to override it. So the roster is the fallback: fewer\n * guarantees, and the API refuses an ineligible one anyway, which is a better\n * failure than a dialog with nothing in it.\n */\nexport function AssignResourceModal({\n booking,\n open,\n onClose,\n onAssigned,\n}: {\n booking: BookingItem;\n open: boolean;\n onClose: () => void;\n onAssigned: () => void;\n}) {\n const { tenant } = useAuth();\n const [picked, setPicked] = useState<string | null>(\n booking.resourceId ?? null,\n );\n const [saving, setSaving] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const { data: requirements } = useApiQuery(\n [\n 'eligible-resources',\n booking.contentId ?? '',\n booking.date ?? '',\n booking.startTime ?? '',\n ],\n (slug) =>\n bookingsApi\n .eligibleResources(slug, {\n contentId: booking.contentId as string,\n date: (booking.date ?? '').slice(0, 10),\n ...(booking.startTime ? { startTime: booking.startTime } : {}),\n ...(booking.endTime ? { endTime: booking.endTime } : {}),\n })\n .catch(() => []),\n { enabled: open && Boolean(booking.contentId && booking.date) },\n );\n\n const { data: roster } = useApiQuery(\n ['resources'],\n (slug) => resourcesApi.list(slug).catch(() => ({ data: [] })),\n { enabled: open },\n );\n\n const eligible = (requirements ?? []).flatMap(\n (req) => req.eligibleResources ?? [],\n );\n const options: ResourceItem[] = eligible.length\n ? eligible\n : (roster?.data ?? []);\n\n // Re-seeded on open: this stays mounted so the close can animate, and\n // mount-time state would show the previous answer the second time round.\n useEffect(() => {\n if (open) {\n setPicked(booking.resourceId ?? null);\n setError(null);\n }\n }, [open, booking.resourceId]);\n\n const save = async () => {\n if (!tenant?.slug) return;\n setSaving(true);\n setError(null);\n try {\n await bookingsApi.update(tenant.slug, booking.id, {\n // `null` unassigns; the API leaves the field alone when it is absent,\n // so this is the only way to take somebody off.\n resourceId: picked,\n } as Partial<BookingItem>);\n onAssigned();\n onClose();\n } catch (err) {\n setError(\n err instanceof Error\n ? err.message\n : 'Could not change who this is with.',\n );\n } finally {\n setSaving(false);\n }\n };\n\n return (\n <FormDialog\n open={open}\n title={booking.resourceId ? 'Change who this is with' : 'Assign someone'}\n onClose={onClose}\n description=\"Only this booking. The customer is not told it moved, because it has not.\"\n footer={\n <>\n <Button variant=\"secondary\" onClick={onClose} disabled={saving}>\n Cancel\n </Button>\n <Button\n onClick={save}\n loading={saving}\n disabled={saving || picked === (booking.resourceId ?? null)}\n >\n Save\n </Button>\n </>\n }\n >\n <div className=\"space-y-3\">\n {error && (\n <p className=\"rounded-lg bg-[var(--error-bg)] px-3 py-2 text-sm text-[var(--error)]\">\n {error}\n </p>\n )}\n\n {options.length === 0 ? (\n <p className=\"text-sm text-[var(--text-secondary)]\">\n Nobody on the roster can take this. Add a resource first, or check\n the service accepts one.\n </p>\n ) : (\n <div className=\"grid gap-2 sm:grid-cols-2\">\n {options.map((resource) => (\n <OptionButton\n key={resource.id}\n shape=\"card\"\n selected={picked === resource.id}\n onClick={() => setPicked(resource.id)}\n className=\"w-full justify-start gap-3 py-2 pl-3 text-left\"\n >\n <Avatar\n name={resource.name}\n src={resource.photo?.url}\n size=\"xs\"\n />\n <span className=\"min-w-0 truncate text-[var(--text-primary)]\">\n {resource.name}\n </span>\n </OptionButton>\n ))}\n </div>\n )}\n\n {/* Taking somebody off is a real answer, and the only route to it.\n Offered only when there is somebody to take off. */}\n {booking.resourceId && (\n <OptionButton\n shape=\"card\"\n selected={picked === null}\n onClick={() => setPicked(null)}\n className=\"w-full justify-start py-2 pl-3 text-left\"\n >\n Nobody yet\n </OptionButton>\n )}\n </div>\n </FormDialog>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,26 @@
1
+ const BOOKING_TYPE_LABELS = {
2
+ appointment: "Appointment",
3
+ class: "Class",
4
+ table: "Table reservation",
5
+ room: "Room booking",
6
+ event: "Event",
7
+ resource: "Resource booking"
8
+ };
9
+ const BOOKING_MODE_LABELS = {
10
+ scheduled: "Scheduled",
11
+ check_in: "Check-in",
12
+ pickup_dropoff: "Pickup / drop-off",
13
+ reservation: "Reservation",
14
+ walk_in_staff_created: "Walk-in"
15
+ };
16
+ const BOOKING_ORIGIN_LABELS = {
17
+ storefront: "Storefront",
18
+ dashboard: "Dashboard",
19
+ api: "API"
20
+ };
21
+ export {
22
+ BOOKING_MODE_LABELS,
23
+ BOOKING_ORIGIN_LABELS,
24
+ BOOKING_TYPE_LABELS
25
+ };
26
+ //# sourceMappingURL=booking-constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../../src/dashboard/%28bookings%29/bookings/%5BbookingId%5D/_components/booking-constants.ts"],"sourcesContent":["// Display LABELS for booking type / mode / origin. Shared by the desktop and\n// mobile booking-detail layouts (and the page's mobile-screen fact list).\n//\n// The colour maps that used to live here are gone. Mode and origin are facts\n// about a booking, not states of one — how it was made, where it came from —\n// and painting each of them a hue put four coloured pills in one header, where\n// the only one that ranks anything is the status. They render as plain Badge\n// now, which is what \"colour marks attention, not state\" means when it is\n// applied to something that is not a state at all.\n\nexport const BOOKING_TYPE_LABELS: Record<string, string> = {\n appointment: 'Appointment',\n class: 'Class',\n table: 'Table reservation',\n room: 'Room booking',\n event: 'Event',\n resource: 'Resource booking',\n};\n\nexport const BOOKING_MODE_LABELS: Record<string, string> = {\n scheduled: 'Scheduled',\n check_in: 'Check-in',\n pickup_dropoff: 'Pickup / drop-off',\n reservation: 'Reservation',\n walk_in_staff_created: 'Walk-in',\n};\n\nexport const BOOKING_ORIGIN_LABELS: Record<string, string> = {\n storefront: 'Storefront',\n dashboard: 'Dashboard',\n api: 'API',\n};\n"],"mappings":"AAUO,MAAM,sBAA8C;AAAA,EACzD,aAAa;AAAA,EACb,OAAO;AAAA,EACP,OAAO;AAAA,EACP,MAAM;AAAA,EACN,OAAO;AAAA,EACP,UAAU;AACZ;AAEO,MAAM,sBAA8C;AAAA,EACzD,WAAW;AAAA,EACX,UAAU;AAAA,EACV,gBAAgB;AAAA,EAChB,aAAa;AAAA,EACb,uBAAuB;AACzB;AAEO,MAAM,wBAAgD;AAAA,EAC3D,YAAY;AAAA,EACZ,WAAW;AAAA,EACX,KAAK;AACP;","names":[]}