@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,214 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useItemLinks } from "@withpotter/lib/use-item-links";
4
+ import { FLAT_CONTROL, TOOLBAR_H } from "@withpotter/ui-kit/toolbar-parts";
5
+ import { useState } from "react";
6
+ import { useRouter } from "next/navigation";
7
+ import { CalendarDays, LayoutGrid, List, Plus, Users } from "lucide-react";
8
+ import {
9
+ ListPage,
10
+ ListFrame,
11
+ ListStates,
12
+ TableShell,
13
+ Th,
14
+ TableRow,
15
+ TablePagination,
16
+ Select,
17
+ Button,
18
+ ViewSwitch,
19
+ OverflowMenu,
20
+ OverflowItem,
21
+ StateView
22
+ } from "@withpotter/ui-kit";
23
+ import { StatusBadge } from "@withpotter/components/shared/status-badge";
24
+ import { MobilePageHeader } from "@withpotter/components/mobile/mobile-page-header";
25
+ import { useRegisterRefresh } from "@withpotter/components/mobile/pull-to-refresh-context";
26
+ import { LIST_PAGE_SIZE } from "@withpotter/lib/list-page-size";
27
+ import { useEventsData } from "./_hooks/use-events-data";
28
+ import { EventGrid } from "./_components/event-grid";
29
+ import { EventThumb } from "./_components/event-poster";
30
+ import {
31
+ eventFacts,
32
+ eventPublicationStatus,
33
+ whenLabel
34
+ } from "./_lib/event-facts";
35
+ function EventsPage() {
36
+ const router = useRouter();
37
+ const links = useItemLinks();
38
+ const [view, setView] = useState("list");
39
+ const {
40
+ events,
41
+ total,
42
+ totalPages,
43
+ page,
44
+ setPage,
45
+ window,
46
+ setWindow,
47
+ loading,
48
+ error,
49
+ refetch
50
+ } = useEventsData();
51
+ useRegisterRefresh(refetch);
52
+ return /* @__PURE__ */ jsx(
53
+ ListPage,
54
+ {
55
+ largeTitle: true,
56
+ title: "Events",
57
+ mobileHeader: /* @__PURE__ */ jsx(
58
+ MobilePageHeader,
59
+ {
60
+ title: "Events",
61
+ action: {
62
+ label: "New event",
63
+ icon: Plus,
64
+ onClick: () => router.push("/dashboard/events/new?intent=event-tickets")
65
+ }
66
+ }
67
+ ),
68
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [
69
+ /* @__PURE__ */ jsx(
70
+ Select,
71
+ {
72
+ size: "sm",
73
+ value: window,
74
+ onChange: (value) => setWindow(value),
75
+ ariaLabel: "Which events to show",
76
+ options: [
77
+ { value: "all", label: "All events" },
78
+ { value: "upcoming", label: "Upcoming" },
79
+ { value: "past", label: "Past" }
80
+ ]
81
+ }
82
+ ),
83
+ /* @__PURE__ */ jsx(
84
+ ViewSwitch,
85
+ {
86
+ className: `${TOOLBAR_H} ${FLAT_CONTROL}`,
87
+ value: view,
88
+ onChange: setView,
89
+ "aria-label": "Show events as a list or a grid",
90
+ options: [
91
+ { value: "list", label: "List", icon: List },
92
+ { value: "grid", label: "Grid", icon: LayoutGrid }
93
+ ]
94
+ }
95
+ ),
96
+ /* @__PURE__ */ jsx(
97
+ Button,
98
+ {
99
+ className: `${TOOLBAR_H} ${FLAT_CONTROL}`,
100
+ icon: /* @__PURE__ */ jsx(Plus, {}),
101
+ onClick: () => router.push("/dashboard/events/new?intent=event-tickets"),
102
+ children: "New event"
103
+ }
104
+ )
105
+ ] }),
106
+ children: /* @__PURE__ */ jsx(ListFrame, { children: /* @__PURE__ */ jsx(
107
+ ListStates,
108
+ {
109
+ framed: true,
110
+ loading: loading && events.length === 0,
111
+ isEmpty: events.length === 0,
112
+ error,
113
+ onRetry: () => refetch(),
114
+ empty: (
115
+ /* The first-run state carries the act that resolves it, even
116
+ though the header offers the same one: on an empty page the
117
+ header button is small and in the far corner and this is in the
118
+ middle of the screen, where the eye already is.
119
+
120
+ A NARROWED empty list says something else. Nobody arriving at
121
+ "no past events" wants to be sold a new one — they want the
122
+ window they came from. */
123
+ window === "all" ? /* @__PURE__ */ jsx(
124
+ StateView,
125
+ {
126
+ kind: "empty",
127
+ icon: CalendarDays,
128
+ title: "No events yet",
129
+ description: "Put on a night, sell the tickets, and see who is coming.",
130
+ action: {
131
+ label: "New event",
132
+ href: "/dashboard/events/new?intent=event-tickets"
133
+ }
134
+ }
135
+ ) : /* @__PURE__ */ jsx(
136
+ StateView,
137
+ {
138
+ kind: "empty",
139
+ icon: CalendarDays,
140
+ title: window === "upcoming" ? "Nothing coming up" : "Nothing has happened yet",
141
+ description: "Events with no date set are in All, which is where a half-written listing waits.",
142
+ action: {
143
+ label: "Show all events",
144
+ onClick: () => setWindow("all")
145
+ }
146
+ }
147
+ )
148
+ ),
149
+ children: view === "grid" ? /* @__PURE__ */ jsx("div", { className: "p-3", children: /* @__PURE__ */ jsx(EventGrid, { events }) }) : /* @__PURE__ */ jsx(
150
+ TableShell,
151
+ {
152
+ bare: true,
153
+ minWidth: 760,
154
+ footer: /* @__PURE__ */ jsx(
155
+ TablePagination,
156
+ {
157
+ page,
158
+ totalPages,
159
+ pageSize: LIST_PAGE_SIZE,
160
+ totalItems: total,
161
+ entityName: "events",
162
+ onPageChange: setPage
163
+ }
164
+ ),
165
+ head: /* @__PURE__ */ jsxs("tr", { className: "h-[44px]", children: [
166
+ /* @__PURE__ */ jsx(Th, { children: "Event" }),
167
+ /* @__PURE__ */ jsx(Th, { children: "When" }),
168
+ /* @__PURE__ */ jsx(Th, { children: "Tickets" }),
169
+ /* @__PURE__ */ jsx(Th, { children: "Status" }),
170
+ /* @__PURE__ */ jsx("th", { className: "w-12" })
171
+ ] }),
172
+ children: events.map((event) => {
173
+ const facts = eventFacts(event);
174
+ return /* @__PURE__ */ jsxs(
175
+ TableRow,
176
+ {
177
+ onClick: () => router.push(links.detail(event.id)),
178
+ children: [
179
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
180
+ /* @__PURE__ */ jsx(EventThumb, { event }),
181
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0", children: [
182
+ /* @__PURE__ */ jsx("div", { className: "text-sm font-medium text-[var(--text-primary)]", children: event.title }),
183
+ facts.venue && /* @__PURE__ */ jsx("div", { className: "text-xs text-[var(--text-tertiary)]", children: facts.venue })
184
+ ] })
185
+ ] }) }),
186
+ /* @__PURE__ */ jsx("td", { className: "text-sm text-[var(--text-secondary)]", children: whenLabel(facts) }),
187
+ /* @__PURE__ */ jsx("td", { className: "text-sm tabular-nums text-[var(--text-secondary)]", children: facts.capacity > 0 ? `${facts.sold} of ${facts.capacity}` : "\u2014" }),
188
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(StatusBadge, { status: eventPublicationStatus(event) }) }),
189
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(OverflowMenu, { children: /* @__PURE__ */ jsx(
190
+ OverflowItem,
191
+ {
192
+ icon: /* @__PURE__ */ jsx(Users, {}),
193
+ onClick: () => router.push(
194
+ `/dashboard/bookings/attendees?contentId=${event.id}`
195
+ ),
196
+ children: "Who is coming"
197
+ }
198
+ ) }) })
199
+ ]
200
+ },
201
+ event.id
202
+ );
203
+ })
204
+ }
205
+ )
206
+ }
207
+ ) })
208
+ }
209
+ );
210
+ }
211
+ export {
212
+ EventsPage as default
213
+ };
214
+ //# sourceMappingURL=page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/dashboard/%28bookings%29/events/page.tsx"],"sourcesContent":["'use client';\n\nimport { useItemLinks } from '@withpotter/lib/use-item-links';\nimport { FLAT_CONTROL, TOOLBAR_H } from '@withpotter/ui-kit/toolbar-parts';\nimport { useState } from 'react';\n\nimport { useRouter } from 'next/navigation';\nimport { CalendarDays, LayoutGrid, List, Plus, Users } from 'lucide-react';\nimport {\n ListPage,\n ListFrame,\n ListStates,\n TableShell,\n Th,\n TableRow,\n TablePagination,\n Select,\n Button,\n ViewSwitch,\n OverflowMenu,\n OverflowItem,\n StateView,\n} from '@withpotter/ui-kit';\nimport { StatusBadge } from '@withpotter/components/shared/status-badge';\nimport { MobilePageHeader } from '@withpotter/components/mobile/mobile-page-header';\nimport { useRegisterRefresh } from '@withpotter/components/mobile/pull-to-refresh-context';\nimport { LIST_PAGE_SIZE } from '@withpotter/lib/list-page-size';\nimport { useEventsData, type EventWindow } from './_hooks/use-events-data';\nimport { EventGrid } from './_components/event-grid';\nimport { EventThumb } from './_components/event-poster';\nimport {\n eventFacts,\n eventPublicationStatus,\n whenLabel,\n} from './_lib/event-facts';\n\n/**\n * EVERY EVENT THIS BUSINESS HAS PUT ON — John, 2026-09-03: *\"I need events I\n * have created, I need to be able to see all events I've created, so yes we\n * need a nav for that.\"*\n *\n * ── WHY THE CATALOGUE WAS NOT THIS ──\n *\n * An event IS a product with the `ticketed` behaviour, and the archetype's\n * catalogue row has always been called Event Listings, so on paper a ticket\n * business already had this page. Two things made it not one.\n *\n * The first is the axis. A shop reads its shelf by name and a venue reads its\n * diary by WHEN — what is on next, and what has been — and the catalogue could\n * not be asked either question: there was no event window in the API and no\n * sort by date on the screen. \"Show me past events\" meant scrolling the whole\n * catalogue.\n *\n * The second is the collapse. When a business runs tickets alongside anything\n * else, the sidebar folds the two catalogue rows into one — same destination,\n * so one row — and the merged row takes the generic noun. A shop that added\n * events got \"Products\", and its events stopped being nameable in the nav at\n * the moment it had two kinds of thing to tell apart. A separate destination\n * is what makes an Events row survive that, and the row is why this is a route\n * rather than a query parameter: `?intent=event-tickets` re-scopes the whole\n * shell, which is a different and much larger promise than \"show me my\n * events\".\n *\n * ── ATTENDEES ARE REACHED FROM AN EVENT ──\n *\n * Not from a global row of their own. An attendee is not a second kind of\n * person: it is a customer in relation to one night, and the identity belongs\n * in Customers where every other relationship this person has already lives.\n * What an operator needs on the door is the other thing entirely — this event's\n * 142, checked in or not — which is a view of an event and is where the row's\n * ⋯ sends you.\n */\nexport default function EventsPage() {\n const router = useRouter();\n const links = useItemLinks();\n /**\n * TABLE OR GRID — John, 2026-09-03: *\"the events page should have a grid\n * view not just list.\"*\n *\n * A shop's stock list is read by name and reads well as rows. An event is a\n * poster, and a promoter running six nights recognises theirs by the artwork\n * long before they finish reading a title — which is the same argument the\n * catalogue's own switch makes about products with photographs.\n *\n * `ViewSwitch`, because this is one set of records drawn two ways: the house\n * primitive for exactly that, and not `OptionButton`, which is for a choice\n * that narrows.\n */\n const [view, setView] = useState<'list' | 'grid'>('list');\n const {\n events,\n total,\n totalPages,\n page,\n setPage,\n window,\n setWindow,\n loading,\n error,\n refetch,\n } = useEventsData();\n\n useRegisterRefresh(refetch);\n\n return (\n <ListPage\n largeTitle\n title=\"Events\"\n mobileHeader={\n <MobilePageHeader\n title=\"Events\"\n action={{\n label: 'New event',\n icon: Plus,\n onClick: () =>\n router.push('/dashboard/events/new?intent=event-tickets'),\n }}\n />\n }\n actions={\n <>\n {/* The window narrows the list, so it sits with the controls that\n act on the list. Not a tab strip: the house rule is that a list\n narrows in its filters, and a page-scoped pill row under a title\n claims a line that belongs to the data. */}\n <Select\n size=\"sm\"\n value={window}\n onChange={(value) => setWindow(value as EventWindow)}\n ariaLabel=\"Which events to show\"\n options={[\n { value: 'all', label: 'All events' },\n { value: 'upcoming', label: 'Upcoming' },\n { value: 'past', label: 'Past' },\n ]}\n />\n {/* THE EDITOR, SCOPED TO EVENTS — not the plain product creator.\n John, 2026-09-03: *\"when I click on create it goes to create\n products.\"*\n\n `ProductEditorPage` decides what it is making from whichever\n archetype the workspace lists first, so a shop that later added\n events pressed New event and got a form headed Product — no date,\n no venue, no tiers. `?intent=event-tickets` is what\n `useIntentConfig` reads to narrow that, which is exactly the\n right promise on a create screen: this form is for one kind of\n thing, and you have just said which. */}\n <ViewSwitch\n className={`${TOOLBAR_H} ${FLAT_CONTROL}`}\n value={view}\n onChange={setView}\n aria-label=\"Show events as a list or a grid\"\n options={[\n { value: 'list', label: 'List', icon: List },\n { value: 'grid', label: 'Grid', icon: LayoutGrid },\n ]}\n />\n <Button\n className={`${TOOLBAR_H} ${FLAT_CONTROL}`}\n icon={<Plus />}\n onClick={() =>\n router.push('/dashboard/events/new?intent=event-tickets')\n }\n >\n New event\n </Button>\n </>\n }\n >\n <ListFrame>\n <ListStates\n framed\n loading={loading && events.length === 0}\n isEmpty={events.length === 0}\n error={error}\n onRetry={() => refetch()}\n empty={\n /* The first-run state carries the act that resolves it, even\n though the header offers the same one: on an empty page the\n header button is small and in the far corner and this is in the\n middle of the screen, where the eye already is.\n\n A NARROWED empty list says something else. Nobody arriving at\n \"no past events\" wants to be sold a new one — they want the\n window they came from. */\n window === 'all' ? (\n <StateView\n kind=\"empty\"\n icon={CalendarDays}\n title=\"No events yet\"\n description=\"Put on a night, sell the tickets, and see who is coming.\"\n action={{\n label: 'New event',\n href: '/dashboard/events/new?intent=event-tickets',\n }}\n />\n ) : (\n <StateView\n kind=\"empty\"\n icon={CalendarDays}\n title={\n window === 'upcoming'\n ? 'Nothing coming up'\n : 'Nothing has happened yet'\n }\n description=\"Events with no date set are in All, which is where a half-written listing waits.\"\n action={{\n label: 'Show all events',\n onClick: () => setWindow('all'),\n }}\n />\n )\n }\n >\n {view === 'grid' ? (\n <div className=\"p-3\">\n <EventGrid events={events} />\n </div>\n ) : (\n <TableShell\n bare\n minWidth={760}\n footer={\n <TablePagination\n page={page}\n totalPages={totalPages}\n pageSize={LIST_PAGE_SIZE}\n totalItems={total}\n entityName=\"events\"\n onPageChange={setPage}\n />\n }\n head={\n <tr className=\"h-[44px]\">\n <Th>Event</Th>\n <Th>When</Th>\n {/* Sold against what is on sale, which is the only number a\n venue is actually watching. A room's capacity is not it:\n seats held back were never for sale. */}\n <Th>Tickets</Th>\n <Th>Status</Th>\n <th className=\"w-12\" />\n </tr>\n }\n >\n {events.map((event) => {\n const facts = eventFacts(event);\n return (\n <TableRow\n key={event.id}\n onClick={() => router.push(links.detail(event.id))}\n >\n <td>\n <div className=\"flex items-center gap-3\">\n <EventThumb event={event} />\n <div className=\"min-w-0\">\n <div className=\"text-sm font-medium text-[var(--text-primary)]\">\n {event.title}\n </div>\n {facts.venue && (\n <div className=\"text-xs text-[var(--text-tertiary)]\">\n {facts.venue}\n </div>\n )}\n </div>\n </div>\n </td>\n <td className=\"text-sm text-[var(--text-secondary)]\">\n {whenLabel(facts)}\n </td>\n <td className=\"text-sm tabular-nums text-[var(--text-secondary)]\">\n {facts.capacity > 0\n ? `${facts.sold} of ${facts.capacity}`\n : '—'}\n </td>\n <td>\n <StatusBadge status={eventPublicationStatus(event)} />\n </td>\n <td>\n <OverflowMenu>\n <OverflowItem\n icon={<Users />}\n onClick={() =>\n router.push(\n `/dashboard/bookings/attendees?contentId=${event.id}`,\n )\n }\n >\n Who is coming\n </OverflowItem>\n </OverflowMenu>\n </td>\n </TableRow>\n );\n })}\n </TableShell>\n )}\n </ListStates>\n </ListFrame>\n </ListPage>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,36 @@
1
+ "use client";
2
+ import { Fragment, jsx } from "react/jsx-runtime";
3
+ import { useParams } from "next/navigation";
4
+ import { useAuth } from "@withpotter/lib/auth-context";
5
+ import { useApiQuery } from "@withpotter/hooks/use-api-query";
6
+ import { resourcesApi } from "@withpotter/lib/api/resources";
7
+ import { IntentScope } from "@withpotter/lib/intents/intent-scope";
8
+ import { INTENTS } from "@withpotter/components/intents";
9
+ import { ownerIntentOfResource } from "@withpotter/components/intents/item-owner";
10
+ import { scopeLabelsFor } from "@withpotter/components/intents/scope-labels";
11
+ function ResourceLayout({ children }) {
12
+ const { resourceId } = useParams();
13
+ const { tenant } = useAuth();
14
+ const { data: type } = useApiQuery(
15
+ ["resource", resourceId, "type"],
16
+ async (slug) => {
17
+ const res = await resourcesApi.get(slug, resourceId);
18
+ return res?.data?.type ?? res?.type ?? null;
19
+ },
20
+ { enabled: Boolean(resourceId && tenant?.slug) }
21
+ );
22
+ const owner = ownerIntentOfResource(type, INTENTS);
23
+ if (!owner) return /* @__PURE__ */ jsx(Fragment, { children });
24
+ return /* @__PURE__ */ jsx(
25
+ IntentScope,
26
+ {
27
+ intentKey: owner.key,
28
+ labels: scopeLabelsFor(owner, owner.nav.label),
29
+ children
30
+ }
31
+ );
32
+ }
33
+ export {
34
+ ResourceLayout as default
35
+ };
36
+ //# sourceMappingURL=layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../../src/dashboard/%28bookings%29/resources/%5BresourceId%5D/layout.tsx"],"sourcesContent":["'use client';\n\nimport { useParams } from 'next/navigation';\nimport type { ReactNode } from 'react';\nimport { useAuth } from '@withpotter/lib/auth-context';\nimport { useApiQuery } from '@withpotter/hooks/use-api-query';\nimport { resourcesApi } from '@withpotter/lib/api/resources';\nimport { IntentScope } from '@withpotter/lib/intents/intent-scope';\nimport { INTENTS } from '@withpotter/components/intents';\nimport { ownerIntentOfResource } from '@withpotter/components/intents/item-owner';\nimport { scopeLabelsFor } from '@withpotter/components/intents/scope-labels';\n\n/**\n * A resource's screen, spoken in the words of the intent that manages it: a\n * table is a restaurant's, a room a rental's, a staff member a booking\n * business's. Each intent declares the resource types it manages, and the\n * resource says which it is. It shares the page's own query key.\n */\nexport default function ResourceLayout({ children }: { children: ReactNode }) {\n const { resourceId } = useParams<{ resourceId: string }>();\n const { tenant } = useAuth();\n\n const { data: type } = useApiQuery<string | null>(\n ['resource', resourceId, 'type'],\n async (slug) => {\n const res = (await resourcesApi.get(slug, resourceId)) as unknown as {\n data?: { type?: string };\n type?: string;\n };\n return res?.data?.type ?? res?.type ?? null;\n },\n { enabled: Boolean(resourceId && tenant?.slug) },\n );\n\n const owner = ownerIntentOfResource(type, INTENTS);\n if (!owner) return <>{children}</>;\n\n return (\n <IntentScope\n intentKey={owner.key}\n labels={scopeLabelsFor(owner, owner.nav.label)}\n >\n {children}\n </IntentScope>\n );\n}\n"],"mappings":";AAmCqB;AAjCrB,SAAS,iBAAiB;AAE1B,SAAS,eAAe;AACxB,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,eAAe;AACxB,SAAS,6BAA6B;AACtC,SAAS,sBAAsB;AAQhB,SAAR,eAAgC,EAAE,SAAS,GAA4B;AAC5E,QAAM,EAAE,WAAW,IAAI,UAAkC;AACzD,QAAM,EAAE,OAAO,IAAI,QAAQ;AAE3B,QAAM,EAAE,MAAM,KAAK,IAAI;AAAA,IACrB,CAAC,YAAY,YAAY,MAAM;AAAA,IAC/B,OAAO,SAAS;AACd,YAAM,MAAO,MAAM,aAAa,IAAI,MAAM,UAAU;AAIpD,aAAO,KAAK,MAAM,QAAQ,KAAK,QAAQ;AAAA,IACzC;AAAA,IACA,EAAE,SAAS,QAAQ,cAAc,QAAQ,IAAI,EAAE;AAAA,EACjD;AAEA,QAAM,QAAQ,sBAAsB,MAAM,OAAO;AACjD,MAAI,CAAC,MAAO,QAAO,gCAAG,UAAS;AAE/B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,MAAM;AAAA,MACjB,QAAQ,eAAe,OAAO,MAAM,IAAI,KAAK;AAAA,MAE5C;AAAA;AAAA,EACH;AAEJ;","names":[]}
@@ -0,0 +1,351 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useItemLinks } from "@withpotter/lib/use-item-links";
4
+ import { useEffect, useState } from "react";
5
+ import { useParams, useRouter } from "next/navigation";
6
+ import { Power, Trash2, Boxes } from "lucide-react";
7
+ import { useAuth } from "@withpotter/lib/auth-context";
8
+ import { useApiQuery } from "@withpotter/hooks/use-api-query";
9
+ import { useBusinessLocations } from "@withpotter/lib/use-business-locations";
10
+ import { useDetailHeader } from "@withpotter/hooks/use-detail-header";
11
+ import { useEntityLabel } from "@withpotter/lib/intents/use-entity-label";
12
+ import { useModuleLabel } from "@withpotter/lib/use-module-label";
13
+ import { resourceCategoriesApi } from "@withpotter/lib/api/resource-categories";
14
+ import { resourcesApi } from "@withpotter/lib/api/resources";
15
+ import { Button } from "@withpotter/ui-kit/button";
16
+ import { DetailPage } from "@withpotter/ui-kit/detail-page";
17
+ import { DetailStates } from "@withpotter/ui-kit/detail-states";
18
+ import { EditorSection } from "@withpotter/ui-kit/editor-section";
19
+ import { ErrorBanner } from "@withpotter/ui-kit/error-banner";
20
+ import { Field } from "@withpotter/ui-kit/field";
21
+ import { Input, NumberField, Select, Textarea } from "@withpotter/ui-kit";
22
+ import { GeneratedAvatar } from "@withpotter/ui-kit/generated-avatar";
23
+ import { OverflowMenu, OverflowItem } from "@withpotter/ui-kit/overflow-menu";
24
+ import { StatusBadge } from "@withpotter/components/shared/status-badge";
25
+ import { useConfirm } from "@withpotter/ui-kit/confirm-dialog";
26
+ import { ImageUpload } from "@withpotter/components/image-upload";
27
+ import { ScheduleEditor, getDefaultSchedule } from "../_components";
28
+ import { availabilityWords } from "../_lib/shapes";
29
+ function ResourceRecordPage() {
30
+ const params = useParams();
31
+ const router = useRouter();
32
+ const back = useItemLinks().resources;
33
+ const { tenant } = useAuth();
34
+ const confirm = useConfirm();
35
+ const resourceId = params.resourceId;
36
+ const slug = tenant?.slug ?? "";
37
+ const { locations, isMultiSite } = useBusinessLocations();
38
+ const resourceLabel = useEntityLabel("resource");
39
+ const listTitle = useModuleLabel("resources", resourceLabel.plural);
40
+ const {
41
+ data: resource,
42
+ isLoading,
43
+ error: loadError,
44
+ refetch
45
+ } = useApiQuery(["resource", resourceId], async (s) => {
46
+ const res = await resourcesApi.get(s, resourceId);
47
+ return res?.data ?? res ?? null;
48
+ });
49
+ const { data: categories } = useApiQuery(
50
+ ["resource-categories"],
51
+ (s) => resourceCategoriesApi.list(s)
52
+ );
53
+ const [categoryId, setCategoryId] = useState("");
54
+ const [locationId, setLocationId] = useState("");
55
+ const [name, setName] = useState("");
56
+ const [description, setDescription] = useState("");
57
+ const [imageUrl, setImageUrl] = useState("");
58
+ const [skills, setSkills] = useState("");
59
+ const [schedule, setSchedule] = useState(getDefaultSchedule());
60
+ const [defaultDuration, setDefaultDuration] = useState(60);
61
+ const [bufferMinutes, setBufferMinutes] = useState(0);
62
+ const [advanceBookingDays, setAdvanceBookingDays] = useState(30);
63
+ const [maxBookingsPerSlot, setMaxBookingsPerSlot] = useState(1);
64
+ const [price, setPrice] = useState("");
65
+ const [saving, setSaving] = useState(false);
66
+ const [saved, setSaved] = useState(false);
67
+ const [error, setError] = useState(null);
68
+ const groups = Array.isArray(categories) ? categories : [];
69
+ const category = groups.find((c) => c.id === categoryId) ?? null;
70
+ const kind = category?.kind ?? "person";
71
+ const { byTheNight } = availabilityWords(kind);
72
+ useEffect(() => {
73
+ if (!resource) return;
74
+ setCategoryId(resource.categoryId ?? "");
75
+ setLocationId(resource.locationId ?? "");
76
+ setName(resource.name);
77
+ setDescription(resource.description || "");
78
+ setImageUrl(resource.imageUrl || "");
79
+ setSkills(resource.skills?.join(", ") || "");
80
+ setSchedule(resource.schedule || getDefaultSchedule());
81
+ setDefaultDuration(resource.defaultDurationMinutes || 60);
82
+ setBufferMinutes(resource.bufferMinutes || 0);
83
+ setAdvanceBookingDays(resource.advanceBookingDays || 30);
84
+ setMaxBookingsPerSlot(resource.maxBookingsPerSlot || 1);
85
+ setPrice(resource.price != null ? String(resource.price) : "");
86
+ }, [resource]);
87
+ useDetailHeader({
88
+ title: resource?.name || resourceLabel.singular,
89
+ onBack: () => router.push(back)
90
+ });
91
+ const handleSave = async () => {
92
+ if (!resource) return;
93
+ if (!name.trim()) {
94
+ setError("Give it a name.");
95
+ return;
96
+ }
97
+ setSaving(true);
98
+ setError(null);
99
+ try {
100
+ await resourcesApi.update(slug, resource.id, {
101
+ ...categoryId ? { categoryId } : {},
102
+ // Omitted rather than sent empty: the API reads absence as the main
103
+ // location, which is not the same instruction as an empty string.
104
+ ...locationId ? { locationId } : {},
105
+ name: name.trim(),
106
+ description: description.trim() || void 0,
107
+ imageUrl: imageUrl.trim() || void 0,
108
+ skills: skills.split(",").map((s) => s.trim()).filter(Boolean),
109
+ schedule,
110
+ defaultDurationMinutes: defaultDuration,
111
+ bufferMinutes,
112
+ advanceBookingDays,
113
+ maxBookingsPerSlot,
114
+ price: price ? Number(price) : void 0
115
+ });
116
+ await refetch();
117
+ setSaved(true);
118
+ setTimeout(() => setSaved(false), 2e3);
119
+ } catch (err) {
120
+ setError(err instanceof Error ? err.message : "That did not save.");
121
+ } finally {
122
+ setSaving(false);
123
+ }
124
+ };
125
+ const handleToggleStatus = async () => {
126
+ if (!resource) return;
127
+ setError(null);
128
+ try {
129
+ if (resource.status === "active") {
130
+ await resourcesApi.deactivate(slug, resource.id);
131
+ } else {
132
+ await resourcesApi.activate(slug, resource.id);
133
+ }
134
+ await refetch();
135
+ } catch {
136
+ setError("Could not change whether it can be booked.");
137
+ }
138
+ };
139
+ const handleDelete = async () => {
140
+ if (!resource) return;
141
+ const ok = await confirm({
142
+ title: `Delete ${resource.name}?`,
143
+ description: "Bookings already taken keep their record. This cannot be undone.",
144
+ confirmLabel: "Delete",
145
+ tone: "danger"
146
+ });
147
+ if (!ok) return;
148
+ try {
149
+ await resourcesApi.delete(slug, resource.id);
150
+ router.push(back);
151
+ } catch {
152
+ setError("Could not delete it.");
153
+ }
154
+ };
155
+ if (isLoading || loadError || !resource) {
156
+ return /* @__PURE__ */ jsx(
157
+ DetailStates,
158
+ {
159
+ loading: isLoading,
160
+ error: loadError?.message,
161
+ notFoundLabel: `That ${resourceLabel.singular.toLowerCase()} is not here.`,
162
+ back: { href: back, label: listTitle },
163
+ onRetry: refetch,
164
+ maxWidth: "max-w-4xl"
165
+ }
166
+ );
167
+ }
168
+ const inactive = resource.status !== "active";
169
+ return /* @__PURE__ */ jsx(
170
+ DetailPage,
171
+ {
172
+ maxWidth: "max-w-4xl",
173
+ breadcrumbs: [
174
+ { label: listTitle, href: back, icon: /* @__PURE__ */ jsx(Boxes, {}) },
175
+ { label: resource.name }
176
+ ],
177
+ leading: resource.imageUrl ? (
178
+ // eslint-disable-next-line @next/next/no-img-element
179
+ /* @__PURE__ */ jsx(
180
+ "img",
181
+ {
182
+ src: resource.imageUrl,
183
+ alt: "",
184
+ className: "size-10 squircle object-cover"
185
+ }
186
+ )
187
+ ) : /* @__PURE__ */ jsx(GeneratedAvatar, { name: resource.name, className: "size-10" }),
188
+ title: resource.name,
189
+ badges: /* @__PURE__ */ jsx(StatusBadge, { status: inactive ? "inactive" : "active" }),
190
+ actions: /* @__PURE__ */ jsxs(Fragment, { children: [
191
+ /* @__PURE__ */ jsxs(OverflowMenu, { children: [
192
+ /* @__PURE__ */ jsx(OverflowItem, { icon: /* @__PURE__ */ jsx(Power, {}), onClick: handleToggleStatus, children: inactive ? "Make bookable" : "Take off the board" }),
193
+ /* @__PURE__ */ jsx(OverflowItem, { destructive: true, icon: /* @__PURE__ */ jsx(Trash2, {}), onClick: handleDelete, children: "Delete" })
194
+ ] }),
195
+ /* @__PURE__ */ jsx(Button, { onClick: handleSave, loading: saving, children: saved ? "Saved" : "Save" })
196
+ ] }),
197
+ children: /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
198
+ /* @__PURE__ */ jsx(ErrorBanner, { children: error }),
199
+ /* @__PURE__ */ jsx(EditorSection, { title: "What a customer sees", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-1 gap-4 md:grid-cols-2", children: [
200
+ /* @__PURE__ */ jsxs("div", { className: "flex items-start gap-4", children: [
201
+ kind === "person" && /* @__PURE__ */ jsx(
202
+ ImageUpload,
203
+ {
204
+ value: imageUrl || void 0,
205
+ onChange: (url) => setImageUrl(url ?? ""),
206
+ label: "Photo",
207
+ aspectRatio: "square",
208
+ size: "avatar"
209
+ }
210
+ ),
211
+ /* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx(
212
+ Field,
213
+ {
214
+ label: kind === "person" ? "Full name" : "Name",
215
+ required: true,
216
+ children: /* @__PURE__ */ jsx(
217
+ Input,
218
+ {
219
+ value: name,
220
+ onChange: (e) => setName(e.target.value)
221
+ }
222
+ )
223
+ }
224
+ ) })
225
+ ] }),
226
+ groups.length > 0 && // Bottom-aligned with the name beside it: the photo makes that
227
+ // cell tall, and the name sits at its foot, so a top-aligned
228
+ // Group read a row higher than the field next to it.
229
+ /* @__PURE__ */ jsx("div", { className: kind === "person" ? "md:self-end" : void 0, children: /* @__PURE__ */ jsx(Field, { label: "Group", children: /* @__PURE__ */ jsx(
230
+ Select,
231
+ {
232
+ value: categoryId,
233
+ onChange: setCategoryId,
234
+ options: groups.map((g) => ({
235
+ value: g.id,
236
+ label: g.labelPlural
237
+ })),
238
+ placeholder: "In no group"
239
+ }
240
+ ) }) }),
241
+ isMultiSite && /* @__PURE__ */ jsx(Field, { label: "Where", children: /* @__PURE__ */ jsx(
242
+ Select,
243
+ {
244
+ value: locationId,
245
+ onChange: setLocationId,
246
+ options: locations.map((l) => ({
247
+ value: l.id,
248
+ label: l.name
249
+ })),
250
+ placeholder: "Main location"
251
+ }
252
+ ) }),
253
+ kind === "person" && /* @__PURE__ */ jsx(
254
+ Field,
255
+ {
256
+ label: "Skills",
257
+ hint: "Comma separated. A service can ask for one of these.",
258
+ children: /* @__PURE__ */ jsx(
259
+ Input,
260
+ {
261
+ value: skills,
262
+ onChange: (e) => setSkills(e.target.value),
263
+ placeholder: "e.g. Coloring, Braids, Styling"
264
+ }
265
+ )
266
+ }
267
+ ),
268
+ /* @__PURE__ */ jsx("div", { className: "md:col-span-2", children: /* @__PURE__ */ jsx(Field, { label: "Description", children: /* @__PURE__ */ jsx(
269
+ Textarea,
270
+ {
271
+ value: description,
272
+ onChange: (e) => setDescription(e.target.value),
273
+ rows: 3,
274
+ className: "resize-none"
275
+ }
276
+ ) }) }),
277
+ kind !== "person" && /* @__PURE__ */ jsx("div", { className: "md:col-span-2", children: /* @__PURE__ */ jsx(
278
+ ImageUpload,
279
+ {
280
+ value: imageUrl || void 0,
281
+ onChange: (url) => setImageUrl(url ?? ""),
282
+ label: "Image",
283
+ aspectRatio: "video"
284
+ }
285
+ ) })
286
+ ] }) }),
287
+ /* @__PURE__ */ jsx(EditorSection, { title: "How it is booked", children: /* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4 md:grid-cols-4", children: [
288
+ !byTheNight && /* @__PURE__ */ jsx(Field, { label: "Duration", hint: "Minutes", children: /* @__PURE__ */ jsx(
289
+ NumberField,
290
+ {
291
+ min: 5,
292
+ decimal: false,
293
+ value: defaultDuration,
294
+ onChange: (v) => setDefaultDuration(v ?? 5)
295
+ }
296
+ ) }),
297
+ !byTheNight && /* @__PURE__ */ jsx(Field, { label: "Gap after", hint: "Minutes", children: /* @__PURE__ */ jsx(
298
+ NumberField,
299
+ {
300
+ min: 0,
301
+ decimal: false,
302
+ value: bufferMinutes,
303
+ onChange: (v) => setBufferMinutes(v ?? 0)
304
+ }
305
+ ) }),
306
+ /* @__PURE__ */ jsx(Field, { label: "Booked ahead", hint: "Days", children: /* @__PURE__ */ jsx(
307
+ NumberField,
308
+ {
309
+ min: 1,
310
+ decimal: false,
311
+ value: advanceBookingDays,
312
+ onChange: (v) => setAdvanceBookingDays(v ?? 1)
313
+ }
314
+ ) }),
315
+ /* @__PURE__ */ jsx(Field, { label: byTheNight ? "Price a night" : "Price", children: /* @__PURE__ */ jsx(
316
+ Input,
317
+ {
318
+ type: "number",
319
+ min: 0,
320
+ step: "0.01",
321
+ value: price,
322
+ onChange: (e) => setPrice(e.target.value),
323
+ placeholder: "0.00"
324
+ }
325
+ ) }),
326
+ (kind === "space" || kind === "equipment") && /* @__PURE__ */ jsx(Field, { label: "At once", hint: "How many can share it", children: /* @__PURE__ */ jsx(
327
+ NumberField,
328
+ {
329
+ min: 1,
330
+ decimal: false,
331
+ value: maxBookingsPerSlot,
332
+ onChange: (v) => setMaxBookingsPerSlot(v ?? 1)
333
+ }
334
+ ) })
335
+ ] }) }),
336
+ !byTheNight && /* @__PURE__ */ jsx(EditorSection, { title: "The week it works", children: /* @__PURE__ */ jsx(
337
+ ScheduleEditor,
338
+ {
339
+ title: null,
340
+ schedule,
341
+ onChange: setSchedule
342
+ }
343
+ ) })
344
+ ] })
345
+ }
346
+ );
347
+ }
348
+ export {
349
+ ResourceRecordPage as default
350
+ };
351
+ //# sourceMappingURL=page.js.map