@licklist/design 0.78.5-dev.105 → 0.78.5-dev.107

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 (371) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/bitbucket-pipelines.yml +13 -4
  3. package/dist/index.js +1 -1
  4. package/dist/product-set/form/ProductsControl.d.ts +2 -1
  5. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  6. package/dist/product-set/form/ProductsControl.js +0 -24
  7. package/dist/v2/components/DataTable/DataTable.d.ts.map +1 -1
  8. package/dist/v2/components/DataTable/DataTable.js +86 -2
  9. package/dist/v2/components/InputCheckbox/InputCheckbox.scss.js +1 -1
  10. package/dist/v2/components/Modal/DeleteModal.d.ts.map +1 -1
  11. package/dist/v2/components/Modal/DeleteModal.js +13 -11
  12. package/dist/v2/components/Toggle/Toggle.d.ts.map +1 -1
  13. package/dist/v2/components/Toggle/Toggle.js +8 -5
  14. package/dist/v2/components/ZoneCard/ZoneCard.scss.js +1 -1
  15. package/dist/v2/components/index.d.ts +1 -1
  16. package/dist/v2/components/index.d.ts.map +1 -1
  17. package/dist/v2/icons/index.d.ts +4 -0
  18. package/dist/v2/icons/index.d.ts.map +1 -1
  19. package/dist/v2/icons/index.js +47 -16
  20. package/dist/v2/index.d.ts +0 -4
  21. package/dist/v2/index.d.ts.map +1 -1
  22. package/dist/v2/pages/Settings/components/SidebarCustomisation.js +0 -3
  23. package/dist/v2/pages/Settings/components/SidebarNavItem.js +0 -3
  24. package/package.json +6 -6
  25. package/rollup.config.js +16 -2
  26. package/src/iframe/payment/payment-status-page/PaymentStatusPage.tsx +1 -1
  27. package/src/product-set/form/ProductsControl.tsx +2 -1
  28. package/src/v2/components/DataTable/DataTable.tsx +23 -1
  29. package/src/v2/components/InputCheckbox/InputCheckbox.scss +6 -6
  30. package/src/v2/components/Modal/DeleteModal.tsx +12 -20
  31. package/src/v2/components/Toggle/Toggle.tsx +6 -5
  32. package/src/v2/components/ZoneCard/ZoneCard.scss +78 -0
  33. package/src/v2/components/index.ts +1 -0
  34. package/src/v2/icons/index.tsx +10 -0
  35. package/src/v2/index.ts +0 -73
  36. package/src/v2/navigation/Navigation/Navigation.stories.tsx +137 -0
  37. package/dist/v2/shadcn/components/ui/accordion.d.ts +0 -8
  38. package/dist/v2/shadcn/components/ui/accordion.d.ts.map +0 -1
  39. package/dist/v2/shadcn/components/ui/alert-dialog.d.ts +0 -21
  40. package/dist/v2/shadcn/components/ui/alert-dialog.d.ts.map +0 -1
  41. package/dist/v2/shadcn/components/ui/alert.d.ts +0 -9
  42. package/dist/v2/shadcn/components/ui/alert.d.ts.map +0 -1
  43. package/dist/v2/shadcn/components/ui/aspect-ratio.d.ts +0 -4
  44. package/dist/v2/shadcn/components/ui/aspect-ratio.d.ts.map +0 -1
  45. package/dist/v2/shadcn/components/ui/avatar.d.ts +0 -7
  46. package/dist/v2/shadcn/components/ui/avatar.d.ts.map +0 -1
  47. package/dist/v2/shadcn/components/ui/badge.d.ts +0 -10
  48. package/dist/v2/shadcn/components/ui/badge.d.ts.map +0 -1
  49. package/dist/v2/shadcn/components/ui/breadcrumb.d.ts +0 -20
  50. package/dist/v2/shadcn/components/ui/breadcrumb.d.ts.map +0 -1
  51. package/dist/v2/shadcn/components/ui/button.d.ts +0 -14
  52. package/dist/v2/shadcn/components/ui/button.d.ts.map +0 -1
  53. package/dist/v2/shadcn/components/ui/calendar.d.ts +0 -9
  54. package/dist/v2/shadcn/components/ui/calendar.d.ts.map +0 -1
  55. package/dist/v2/shadcn/components/ui/card.d.ts +0 -9
  56. package/dist/v2/shadcn/components/ui/card.d.ts.map +0 -1
  57. package/dist/v2/shadcn/components/ui/carousel.d.ts +0 -19
  58. package/dist/v2/shadcn/components/ui/carousel.d.ts.map +0 -1
  59. package/dist/v2/shadcn/components/ui/checkbox.d.ts +0 -6
  60. package/dist/v2/shadcn/components/ui/checkbox.d.ts.map +0 -1
  61. package/dist/v2/shadcn/components/ui/checkbox.js +0 -115
  62. package/dist/v2/shadcn/components/ui/checkbox.scss.js +0 -6
  63. package/dist/v2/shadcn/components/ui/collapsible.d.ts +0 -6
  64. package/dist/v2/shadcn/components/ui/collapsible.d.ts.map +0 -1
  65. package/dist/v2/shadcn/components/ui/command.d.ts +0 -83
  66. package/dist/v2/shadcn/components/ui/command.d.ts.map +0 -1
  67. package/dist/v2/shadcn/components/ui/context-menu.d.ts +0 -28
  68. package/dist/v2/shadcn/components/ui/context-menu.d.ts.map +0 -1
  69. package/dist/v2/shadcn/components/ui/dialog.d.ts +0 -20
  70. package/dist/v2/shadcn/components/ui/dialog.d.ts.map +0 -1
  71. package/dist/v2/shadcn/components/ui/dialog.js +0 -169
  72. package/dist/v2/shadcn/components/ui/drawer.d.ts +0 -23
  73. package/dist/v2/shadcn/components/ui/drawer.d.ts.map +0 -1
  74. package/dist/v2/shadcn/components/ui/dropdown-menu.d.ts +0 -28
  75. package/dist/v2/shadcn/components/ui/dropdown-menu.d.ts.map +0 -1
  76. package/dist/v2/shadcn/components/ui/form.d.ts +0 -24
  77. package/dist/v2/shadcn/components/ui/form.d.ts.map +0 -1
  78. package/dist/v2/shadcn/components/ui/hover-card.d.ts +0 -7
  79. package/dist/v2/shadcn/components/ui/hover-card.d.ts.map +0 -1
  80. package/dist/v2/shadcn/components/ui/input-otp.d.ts +0 -35
  81. package/dist/v2/shadcn/components/ui/input-otp.d.ts.map +0 -1
  82. package/dist/v2/shadcn/components/ui/input.d.ts +0 -6
  83. package/dist/v2/shadcn/components/ui/input.d.ts.map +0 -1
  84. package/dist/v2/shadcn/components/ui/label.d.ts +0 -6
  85. package/dist/v2/shadcn/components/ui/label.d.ts.map +0 -1
  86. package/dist/v2/shadcn/components/ui/menubar.d.ts +0 -34
  87. package/dist/v2/shadcn/components/ui/menubar.d.ts.map +0 -1
  88. package/dist/v2/shadcn/components/ui/navigation-menu.d.ts +0 -13
  89. package/dist/v2/shadcn/components/ui/navigation-menu.d.ts.map +0 -1
  90. package/dist/v2/shadcn/components/ui/pagination.d.ts +0 -29
  91. package/dist/v2/shadcn/components/ui/pagination.d.ts.map +0 -1
  92. package/dist/v2/shadcn/components/ui/popover.d.ts +0 -7
  93. package/dist/v2/shadcn/components/ui/popover.d.ts.map +0 -1
  94. package/dist/v2/shadcn/components/ui/progress.d.ts +0 -5
  95. package/dist/v2/shadcn/components/ui/progress.d.ts.map +0 -1
  96. package/dist/v2/shadcn/components/ui/radio-card.d.ts +0 -12
  97. package/dist/v2/shadcn/components/ui/radio-card.d.ts.map +0 -1
  98. package/dist/v2/shadcn/components/ui/radio-group.d.ts +0 -6
  99. package/dist/v2/shadcn/components/ui/radio-group.d.ts.map +0 -1
  100. package/dist/v2/shadcn/components/ui/scroll-area.d.ts +0 -6
  101. package/dist/v2/shadcn/components/ui/scroll-area.d.ts.map +0 -1
  102. package/dist/v2/shadcn/components/ui/select.d.ts +0 -14
  103. package/dist/v2/shadcn/components/ui/select.d.ts.map +0 -1
  104. package/dist/v2/shadcn/components/ui/separator.d.ts +0 -5
  105. package/dist/v2/shadcn/components/ui/separator.d.ts.map +0 -1
  106. package/dist/v2/shadcn/components/ui/sheet.d.ts +0 -26
  107. package/dist/v2/shadcn/components/ui/sheet.d.ts.map +0 -1
  108. package/dist/v2/shadcn/components/ui/sidebar.d.ts +0 -67
  109. package/dist/v2/shadcn/components/ui/sidebar.d.ts.map +0 -1
  110. package/dist/v2/shadcn/components/ui/skeleton.d.ts +0 -3
  111. package/dist/v2/shadcn/components/ui/skeleton.d.ts.map +0 -1
  112. package/dist/v2/shadcn/components/ui/slider.d.ts +0 -5
  113. package/dist/v2/shadcn/components/ui/slider.d.ts.map +0 -1
  114. package/dist/v2/shadcn/components/ui/switch.d.ts +0 -6
  115. package/dist/v2/shadcn/components/ui/switch.d.ts.map +0 -1
  116. package/dist/v2/shadcn/components/ui/switch.js +0 -115
  117. package/dist/v2/shadcn/components/ui/switch.scss.js +0 -6
  118. package/dist/v2/shadcn/components/ui/table-pagination.d.ts +0 -11
  119. package/dist/v2/shadcn/components/ui/table-pagination.d.ts.map +0 -1
  120. package/dist/v2/shadcn/components/ui/table.d.ts +0 -11
  121. package/dist/v2/shadcn/components/ui/table.d.ts.map +0 -1
  122. package/dist/v2/shadcn/components/ui/tabs.d.ts +0 -8
  123. package/dist/v2/shadcn/components/ui/tabs.d.ts.map +0 -1
  124. package/dist/v2/shadcn/components/ui/textarea.d.ts +0 -6
  125. package/dist/v2/shadcn/components/ui/textarea.d.ts.map +0 -1
  126. package/dist/v2/shadcn/components/ui/toast.d.ts +0 -16
  127. package/dist/v2/shadcn/components/ui/toast.d.ts.map +0 -1
  128. package/dist/v2/shadcn/components/ui/toaster.d.ts +0 -2
  129. package/dist/v2/shadcn/components/ui/toaster.d.ts.map +0 -1
  130. package/dist/v2/shadcn/components/ui/toggle-group.d.ts +0 -13
  131. package/dist/v2/shadcn/components/ui/toggle-group.d.ts.map +0 -1
  132. package/dist/v2/shadcn/components/ui/toggle.d.ts +0 -13
  133. package/dist/v2/shadcn/components/ui/toggle.d.ts.map +0 -1
  134. package/dist/v2/shadcn/components/ui/tooltip.d.ts +0 -8
  135. package/dist/v2/shadcn/components/ui/tooltip.d.ts.map +0 -1
  136. package/dist/v2/shadcn/components/ui/use-toast.d.ts +0 -3
  137. package/dist/v2/shadcn/components/ui/use-toast.d.ts.map +0 -1
  138. package/dist/v2/shadcn/hooks/use-mobile.d.ts +0 -2
  139. package/dist/v2/shadcn/hooks/use-mobile.d.ts.map +0 -1
  140. package/dist/v2/shadcn/hooks/use-toast.d.ts +0 -45
  141. package/dist/v2/shadcn/hooks/use-toast.d.ts.map +0 -1
  142. package/dist/v2/shadcn/index.d.ts +0 -20
  143. package/dist/v2/shadcn/index.d.ts.map +0 -1
  144. package/dist/v2/shadcn/lib/utils.d.ts +0 -3
  145. package/dist/v2/shadcn/lib/utils.d.ts.map +0 -1
  146. package/dist/v2/shadcn/lib/utils.js +0 -11
  147. package/dist/v2/shadcn/styles/globals.css +0 -112
  148. package/src/v2/shadcn/_reference/AccountManagerCard.tsx +0 -45
  149. package/src/v2/shadcn/_reference/AffiliatesTable.tsx +0 -178
  150. package/src/v2/shadcn/_reference/AuditArchive.tsx +0 -165
  151. package/src/v2/shadcn/_reference/AuditContent.tsx +0 -270
  152. package/src/v2/shadcn/_reference/AutomationsGeneralSettings.tsx +0 -251
  153. package/src/v2/shadcn/_reference/AvatarUpload.tsx +0 -150
  154. package/src/v2/shadcn/_reference/BookingsSummaryCard.tsx +0 -268
  155. package/src/v2/shadcn/_reference/CodeCleanUpAudit.tsx +0 -274
  156. package/src/v2/shadcn/_reference/CompaniesTable.tsx +0 -387
  157. package/src/v2/shadcn/_reference/ComponentAudit.tsx +0 -239
  158. package/src/v2/shadcn/_reference/ConfigureSettingsCard.tsx +0 -95
  159. package/src/v2/shadcn/_reference/CustomerCard.tsx +0 -155
  160. package/src/v2/shadcn/_reference/DashboardCards.tsx +0 -50
  161. package/src/v2/shadcn/_reference/DashboardFooter.tsx +0 -18
  162. package/src/v2/shadcn/_reference/DiarySettings.tsx +0 -187
  163. package/src/v2/shadcn/_reference/DiaryView.tsx +0 -998
  164. package/src/v2/shadcn/_reference/EmptyState.tsx +0 -76
  165. package/src/v2/shadcn/_reference/EntityInfoCard.tsx +0 -48
  166. package/src/v2/shadcn/_reference/ExistingUserAssignments.tsx +0 -131
  167. package/src/v2/shadcn/_reference/FeatureToggle.tsx +0 -72
  168. package/src/v2/shadcn/_reference/FlowCard.tsx +0 -170
  169. package/src/v2/shadcn/_reference/FlowsContent.tsx +0 -688
  170. package/src/v2/shadcn/_reference/FlowsGeneralSettings.tsx +0 -27
  171. package/src/v2/shadcn/_reference/GeneralSettings.tsx +0 -33
  172. package/src/v2/shadcn/_reference/InventoryGeneralSettings.tsx +0 -82
  173. package/src/v2/shadcn/_reference/LanguageSelector.tsx +0 -97
  174. package/src/v2/shadcn/_reference/LoadingScreen.tsx +0 -25
  175. package/src/v2/shadcn/_reference/LoadingSpinner.tsx +0 -41
  176. package/src/v2/shadcn/_reference/ManagedClientsList.tsx +0 -121
  177. package/src/v2/shadcn/_reference/NPSScore.tsx +0 -379
  178. package/src/v2/shadcn/_reference/NPSSummaryCard.tsx +0 -181
  179. package/src/v2/shadcn/_reference/NotificationBanner.tsx +0 -129
  180. package/src/v2/shadcn/_reference/NotificationPanel.tsx +0 -208
  181. package/src/v2/shadcn/_reference/OnlineUsersCard.tsx +0 -73
  182. package/src/v2/shadcn/_reference/ProtectedRoute.tsx +0 -39
  183. package/src/v2/shadcn/_reference/ProvidersTable.tsx +0 -353
  184. package/src/v2/shadcn/_reference/QuickAddPanel.tsx +0 -1057
  185. package/src/v2/shadcn/_reference/QuickFilters.tsx +0 -112
  186. package/src/v2/shadcn/_reference/ScheduleView.tsx +0 -410
  187. package/src/v2/shadcn/_reference/ScrollToTop.tsx +0 -14
  188. package/src/v2/shadcn/_reference/SecondaryNav.tsx +0 -50
  189. package/src/v2/shadcn/_reference/SecuritySettings.tsx +0 -258
  190. package/src/v2/shadcn/_reference/SessionDetailView.tsx +0 -294
  191. package/src/v2/shadcn/_reference/Sidebar.tsx +0 -14
  192. package/src/v2/shadcn/_reference/SidebarAwareLayout.tsx +0 -30
  193. package/src/v2/shadcn/_reference/SidebarLabelCustomization.tsx +0 -285
  194. package/src/v2/shadcn/_reference/SimulationBanner.tsx +0 -57
  195. package/src/v2/shadcn/_reference/SortControls.tsx +0 -65
  196. package/src/v2/shadcn/_reference/StatusBadge.tsx +0 -49
  197. package/src/v2/shadcn/_reference/StyleGuideContent.tsx +0 -331
  198. package/src/v2/shadcn/_reference/TableActionMenu.tsx +0 -126
  199. package/src/v2/shadcn/_reference/ThemeProvider.tsx +0 -119
  200. package/src/v2/shadcn/_reference/ThemeSettings.tsx +0 -73
  201. package/src/v2/shadcn/_reference/TopNavigation.tsx +0 -332
  202. package/src/v2/shadcn/_reference/UserActivityHistory.tsx +0 -209
  203. package/src/v2/shadcn/_reference/UserLanguageSettings.tsx +0 -94
  204. package/src/v2/shadcn/_reference/UserPanel.tsx +0 -472
  205. package/src/v2/shadcn/_reference/UsersTable.tsx +0 -1023
  206. package/src/v2/shadcn/_reference/WaiverForm.tsx +0 -301
  207. package/src/v2/shadcn/_reference/WaiversGeneralSettings.tsx +0 -46
  208. package/src/v2/shadcn/_reference/WaiversTable.tsx +0 -290
  209. package/src/v2/shadcn/_reference/WaiversTemplatesSettings.tsx +0 -416
  210. package/src/v2/shadcn/_reference/ai/AIChatPanel.tsx +0 -313
  211. package/src/v2/shadcn/_reference/ai/AIChatSearchBar.tsx +0 -36
  212. package/src/v2/shadcn/_reference/ai/ChatInteractiveBlock.tsx +0 -298
  213. package/src/v2/shadcn/_reference/ai/ChatMessageContent.tsx +0 -40
  214. package/src/v2/shadcn/_reference/ai/parseInteractiveBlocks.ts +0 -142
  215. package/src/v2/shadcn/_reference/auth/AuthLayout.tsx +0 -55
  216. package/src/v2/shadcn/_reference/auth/CreatePasswordForm.tsx +0 -285
  217. package/src/v2/shadcn/_reference/auth/CreatePasswordPanel.tsx +0 -20
  218. package/src/v2/shadcn/_reference/auth/LoginFooter.tsx +0 -14
  219. package/src/v2/shadcn/_reference/auth/LoginForm.tsx +0 -205
  220. package/src/v2/shadcn/_reference/auth/LoginPanel.tsx +0 -41
  221. package/src/v2/shadcn/_reference/auth/ResetPasswordForm.tsx +0 -102
  222. package/src/v2/shadcn/_reference/auth/ResetPasswordPanel.tsx +0 -20
  223. package/src/v2/shadcn/_reference/auth/VerifyEmailForm.tsx +0 -95
  224. package/src/v2/shadcn/_reference/auth/VerifyEmailPanel.tsx +0 -20
  225. package/src/v2/shadcn/_reference/email/EmailAttachment.tsx +0 -119
  226. package/src/v2/shadcn/_reference/email/EmailAutomation.tsx +0 -92
  227. package/src/v2/shadcn/_reference/email/EmailPlaceholders.tsx +0 -64
  228. package/src/v2/shadcn/_reference/email/UnlayerEmailEditor.tsx +0 -41
  229. package/src/v2/shadcn/_reference/email/emailTemplateData.ts +0 -53
  230. package/src/v2/shadcn/_reference/emptyStateIcons.tsx +0 -103
  231. package/src/v2/shadcn/_reference/games/MazeGame.tsx +0 -394
  232. package/src/v2/shadcn/_reference/games/RunnerGame.tsx +0 -497
  233. package/src/v2/shadcn/_reference/logos/BookedLogoFull.tsx +0 -36
  234. package/src/v2/shadcn/_reference/logos/BookedLogoMark.tsx +0 -31
  235. package/src/v2/shadcn/_reference/logos/BookedLogoNew.tsx +0 -36
  236. package/src/v2/shadcn/_reference/pricing/DynamicPricingRulesEditor.tsx +0 -401
  237. package/src/v2/shadcn/_reference/pricing/DynamicPricingTierCard.tsx +0 -77
  238. package/src/v2/shadcn/_reference/pricing/DynamicPricingTiersList.tsx +0 -218
  239. package/src/v2/shadcn/_reference/pricing/PricingCalendar.tsx +0 -810
  240. package/src/v2/shadcn/_reference/pricing/PricingPeriodCard.tsx +0 -152
  241. package/src/v2/shadcn/_reference/pricing/PricingPeriodForm.tsx +0 -377
  242. package/src/v2/shadcn/_reference/pricing/PricingPeriodsList.tsx +0 -213
  243. package/src/v2/shadcn/_reference/pricing/getRuleSummary.ts +0 -39
  244. package/src/v2/shadcn/_reference/products/AvailabilityRulesSection.tsx +0 -184
  245. package/src/v2/shadcn/_reference/products/AvailabilitySection.tsx +0 -677
  246. package/src/v2/shadcn/_reference/products/BookingTypeConfigOptions.tsx +0 -40
  247. package/src/v2/shadcn/_reference/products/CapacityPeriodsSection.tsx +0 -238
  248. package/src/v2/shadcn/_reference/products/DynamicPricingTiersSection.tsx +0 -131
  249. package/src/v2/shadcn/_reference/products/GiftCardOrdersTab.tsx +0 -192
  250. package/src/v2/shadcn/_reference/products/GiftCardSettings.tsx +0 -342
  251. package/src/v2/shadcn/_reference/products/PackageProductsSection.tsx +0 -322
  252. package/src/v2/shadcn/_reference/products/PricingSection.tsx +0 -173
  253. package/src/v2/shadcn/_reference/products/ProductTypeFields.tsx +0 -353
  254. package/src/v2/shadcn/_reference/products/ProductTypeIcon.tsx +0 -95
  255. package/src/v2/shadcn/_reference/products/VariablePricingSection.tsx +0 -140
  256. package/src/v2/shadcn/_reference/products/productTypeConfig.ts +0 -182
  257. package/src/v2/shadcn/_reference/shared/BackButton.tsx +0 -50
  258. package/src/v2/shadcn/_reference/shared/CancelConfirmationDialog.tsx +0 -18
  259. package/src/v2/shadcn/_reference/shared/ConfirmationDialog.tsx +0 -136
  260. package/src/v2/shadcn/_reference/shared/DeleteConfirmationDialog.tsx +0 -18
  261. package/src/v2/shadcn/_reference/shared/DeleteEntityPage.tsx +0 -221
  262. package/src/v2/shadcn/_reference/shared/SidebarIcons.tsx +0 -108
  263. package/src/v2/shadcn/_reference/shared/UnifiedSidebar.tsx +0 -722
  264. package/src/v2/shadcn/_reference/tables/BulkActionsBar.tsx +0 -68
  265. package/src/v2/shadcn/_reference/tables/DataTable.tsx +0 -221
  266. package/src/v2/shadcn/_reference/tables/TableControls.tsx +0 -94
  267. package/src/v2/shadcn/_reference/tables/index.ts +0 -3
  268. package/src/v2/shadcn/_reference/tables/types.ts +0 -79
  269. package/src/v2/shadcn/_reference/zones/LegacyZoneSettings.tsx +0 -299
  270. package/src/v2/shadcn/components/ui/accordion.stories.tsx +0 -63
  271. package/src/v2/shadcn/components/ui/accordion.tsx +0 -52
  272. package/src/v2/shadcn/components/ui/alert-dialog.stories.tsx +0 -44
  273. package/src/v2/shadcn/components/ui/alert-dialog.tsx +0 -104
  274. package/src/v2/shadcn/components/ui/alert.stories.tsx +0 -44
  275. package/src/v2/shadcn/components/ui/alert.tsx +0 -43
  276. package/src/v2/shadcn/components/ui/aspect-ratio.stories.tsx +0 -46
  277. package/src/v2/shadcn/components/ui/aspect-ratio.tsx +0 -5
  278. package/src/v2/shadcn/components/ui/avatar.stories.tsx +0 -39
  279. package/src/v2/shadcn/components/ui/avatar.tsx +0 -38
  280. package/src/v2/shadcn/components/ui/badge.stories.tsx +0 -17
  281. package/src/v2/shadcn/components/ui/badge.tsx +0 -30
  282. package/src/v2/shadcn/components/ui/breadcrumb.stories.tsx +0 -91
  283. package/src/v2/shadcn/components/ui/breadcrumb.tsx +0 -90
  284. package/src/v2/shadcn/components/ui/button.stories.tsx +0 -20
  285. package/src/v2/shadcn/components/ui/button.tsx +0 -60
  286. package/src/v2/shadcn/components/ui/calendar.stories.tsx +0 -61
  287. package/src/v2/shadcn/components/ui/calendar.tsx +0 -54
  288. package/src/v2/shadcn/components/ui/card.stories.tsx +0 -37
  289. package/src/v2/shadcn/components/ui/card.tsx +0 -43
  290. package/src/v2/shadcn/components/ui/carousel.stories.tsx +0 -92
  291. package/src/v2/shadcn/components/ui/carousel.tsx +0 -224
  292. package/src/v2/shadcn/components/ui/checkbox.scss +0 -38
  293. package/src/v2/shadcn/components/ui/checkbox.stories.tsx +0 -23
  294. package/src/v2/shadcn/components/ui/checkbox.tsx +0 -24
  295. package/src/v2/shadcn/components/ui/collapsible.stories.tsx +0 -59
  296. package/src/v2/shadcn/components/ui/collapsible.tsx +0 -9
  297. package/src/v2/shadcn/components/ui/command.stories.tsx +0 -70
  298. package/src/v2/shadcn/components/ui/command.tsx +0 -132
  299. package/src/v2/shadcn/components/ui/context-menu.stories.tsx +0 -72
  300. package/src/v2/shadcn/components/ui/context-menu.tsx +0 -178
  301. package/src/v2/shadcn/components/ui/dialog.stories.tsx +0 -67
  302. package/src/v2/shadcn/components/ui/dialog.tsx +0 -95
  303. package/src/v2/shadcn/components/ui/drawer.stories.tsx +0 -50
  304. package/src/v2/shadcn/components/ui/drawer.tsx +0 -87
  305. package/src/v2/shadcn/components/ui/dropdown-menu.stories.tsx +0 -73
  306. package/src/v2/shadcn/components/ui/dropdown-menu.tsx +0 -179
  307. package/src/v2/shadcn/components/ui/form.stories.tsx +0 -105
  308. package/src/v2/shadcn/components/ui/form.tsx +0 -129
  309. package/src/v2/shadcn/components/ui/hover-card.stories.tsx +0 -35
  310. package/src/v2/shadcn/components/ui/hover-card.tsx +0 -27
  311. package/src/v2/shadcn/components/ui/input-otp.stories.tsx +0 -72
  312. package/src/v2/shadcn/components/ui/input-otp.tsx +0 -61
  313. package/src/v2/shadcn/components/ui/input.stories.tsx +0 -16
  314. package/src/v2/shadcn/components/ui/input.tsx +0 -25
  315. package/src/v2/shadcn/components/ui/label.stories.tsx +0 -13
  316. package/src/v2/shadcn/components/ui/label.tsx +0 -17
  317. package/src/v2/shadcn/components/ui/menubar.stories.tsx +0 -86
  318. package/src/v2/shadcn/components/ui/menubar.tsx +0 -207
  319. package/src/v2/shadcn/components/ui/navigation-menu.stories.tsx +0 -68
  320. package/src/v2/shadcn/components/ui/navigation-menu.tsx +0 -120
  321. package/src/v2/shadcn/components/ui/pagination.stories.tsx +0 -78
  322. package/src/v2/shadcn/components/ui/pagination.tsx +0 -81
  323. package/src/v2/shadcn/components/ui/popover.stories.tsx +0 -44
  324. package/src/v2/shadcn/components/ui/popover.tsx +0 -29
  325. package/src/v2/shadcn/components/ui/progress.stories.tsx +0 -17
  326. package/src/v2/shadcn/components/ui/progress.tsx +0 -23
  327. package/src/v2/shadcn/components/ui/radio-card.stories.tsx +0 -68
  328. package/src/v2/shadcn/components/ui/radio-card.tsx +0 -52
  329. package/src/v2/shadcn/components/ui/radio-group.stories.tsx +0 -77
  330. package/src/v2/shadcn/components/ui/radio-group.tsx +0 -35
  331. package/src/v2/shadcn/components/ui/scroll-area.stories.tsx +0 -56
  332. package/src/v2/shadcn/components/ui/scroll-area.tsx +0 -38
  333. package/src/v2/shadcn/components/ui/select.stories.tsx +0 -60
  334. package/src/v2/shadcn/components/ui/select.tsx +0 -148
  335. package/src/v2/shadcn/components/ui/separator.stories.tsx +0 -30
  336. package/src/v2/shadcn/components/ui/separator.tsx +0 -20
  337. package/src/v2/shadcn/components/ui/sheet.stories.tsx +0 -115
  338. package/src/v2/shadcn/components/ui/sheet.tsx +0 -107
  339. package/src/v2/shadcn/components/ui/sidebar.stories.tsx +0 -167
  340. package/src/v2/shadcn/components/ui/sidebar.tsx +0 -637
  341. package/src/v2/shadcn/components/ui/skeleton.stories.tsx +0 -36
  342. package/src/v2/shadcn/components/ui/skeleton.tsx +0 -7
  343. package/src/v2/shadcn/components/ui/slider.stories.tsx +0 -16
  344. package/src/v2/shadcn/components/ui/slider.tsx +0 -23
  345. package/src/v2/shadcn/components/ui/switch.scss +0 -63
  346. package/src/v2/shadcn/components/ui/switch.stories.tsx +0 -23
  347. package/src/v2/shadcn/components/ui/switch.tsx +0 -24
  348. package/src/v2/shadcn/components/ui/table-pagination.stories.tsx +0 -81
  349. package/src/v2/shadcn/components/ui/table-pagination.tsx +0 -61
  350. package/src/v2/shadcn/components/ui/table.stories.tsx +0 -40
  351. package/src/v2/shadcn/components/ui/table.tsx +0 -72
  352. package/src/v2/shadcn/components/ui/tabs.stories.tsx +0 -85
  353. package/src/v2/shadcn/components/ui/tabs.tsx +0 -53
  354. package/src/v2/shadcn/components/ui/textarea.stories.tsx +0 -15
  355. package/src/v2/shadcn/components/ui/textarea.tsx +0 -21
  356. package/src/v2/shadcn/components/ui/toast.stories.tsx +0 -77
  357. package/src/v2/shadcn/components/ui/toast.tsx +0 -111
  358. package/src/v2/shadcn/components/ui/toaster.stories.tsx +0 -46
  359. package/src/v2/shadcn/components/ui/toaster.tsx +0 -24
  360. package/src/v2/shadcn/components/ui/toggle-group.stories.tsx +0 -95
  361. package/src/v2/shadcn/components/ui/toggle-group.tsx +0 -49
  362. package/src/v2/shadcn/components/ui/toggle.stories.tsx +0 -18
  363. package/src/v2/shadcn/components/ui/toggle.tsx +0 -37
  364. package/src/v2/shadcn/components/ui/tooltip.stories.tsx +0 -57
  365. package/src/v2/shadcn/components/ui/tooltip.tsx +0 -28
  366. package/src/v2/shadcn/components/ui/use-toast.ts +0 -3
  367. package/src/v2/shadcn/hooks/use-mobile.tsx +0 -19
  368. package/src/v2/shadcn/hooks/use-toast.ts +0 -184
  369. package/src/v2/shadcn/index.ts +0 -76
  370. package/src/v2/shadcn/lib/utils.ts +0 -6
  371. package/src/v2/shadcn/styles/globals.css +0 -112
@@ -1,677 +0,0 @@
1
- import React, { useEffect, useState } from 'react';
2
- import { Button } from '../ui/button';
3
- import { Input } from '../ui/input';
4
- import { Label } from '../ui/label';
5
- import { RadioGroup, RadioGroupItem } from '../ui/radio-group';
6
- import { Switch } from '../ui/switch';
7
- import { IconPlus, IconCross } from '../../../icons';
8
- import { supabase } from '@/integrations/supabase/client';
9
-
10
- interface OpeningHours {
11
- day_of_week: number;
12
- is_open: boolean;
13
- open_time: string;
14
- close_time: string;
15
- }
16
-
17
- // Database uses 0 = Sunday, 1 = Monday, etc. (JavaScript Date.getDay() convention)
18
- const DAYS_OF_WEEK = [
19
- { value: 1, label: 'Monday', short: 'Mon' },
20
- { value: 2, label: 'Tuesday', short: 'Tue' },
21
- { value: 3, label: 'Wednesday', short: 'Wed' },
22
- { value: 4, label: 'Thursday', short: 'Thu' },
23
- { value: 5, label: 'Friday', short: 'Fri' },
24
- { value: 6, label: 'Saturday', short: 'Sat' },
25
- { value: 0, label: 'Sunday', short: 'Sun' },
26
- ];
27
-
28
- const INCREMENT_OPTIONS = [
29
- { value: 5, label: '5 min' },
30
- { value: 10, label: '10 min' },
31
- { value: 15, label: '15 min' },
32
- { value: 20, label: '20 min' },
33
- { value: 30, label: '30 min' },
34
- { value: 45, label: '45 min' },
35
- { value: 60, label: '1 hour' },
36
- ];
37
-
38
- // Default opening time if no provider opening hours available
39
- const DEFAULT_OPENING_TIME = '09:00';
40
-
41
- export interface DayAvailability {
42
- enabled: boolean;
43
- times: string[]; // For fixed sessions
44
- }
45
-
46
- export interface AvailabilityData {
47
- availability_type: 'fixed_sessions' | 'incremental' | '';
48
- is_daily_availability: boolean;
49
- increment_minutes: number;
50
- // For daily mode (same times every day)
51
- daily_times: string[];
52
- // For per-day mode
53
- day_availability: Record<number, DayAvailability>;
54
- }
55
-
56
- interface AvailabilitySectionProps {
57
- values: Record<string, any>;
58
- onChange: (field: string, value: any) => void;
59
- providerId?: string;
60
- }
61
-
62
- // Helper function to convert time string to minutes from midnight
63
- const timeToMinutes = (time: string): number => {
64
- const [hours, minutes] = time.split(':').map(Number);
65
- return hours * 60 + minutes;
66
- };
67
-
68
- // Helper function to add minutes to a time string (HH:MM format)
69
- const addMinutesToTime = (time: string, minutesToAdd: number): string => {
70
- const [hours, minutes] = time.split(':').map(Number);
71
- const totalMinutes = hours * 60 + minutes + minutesToAdd;
72
- const newHours = Math.floor(totalMinutes / 60) % 24;
73
- const newMinutes = totalMinutes % 60;
74
- return `${String(newHours).padStart(2, '0')}:${String(newMinutes).padStart(2, '0')}`;
75
- };
76
-
77
- // Get duration in minutes from timing fields
78
- const getDurationMinutes = (values: Record<string, any>): number => {
79
- // Prefer persisted duration (minutes) when available
80
- if (typeof values.duration === 'number' && Number.isFinite(values.duration) && values.duration > 0) {
81
- return values.duration;
82
- }
83
-
84
- const timingType = values.timing_type;
85
-
86
- if (timingType === 'session_based') {
87
- const hours = values.session_duration_hours || 0;
88
- const minutes = values.session_duration_minutes || 0;
89
- return hours * 60 + minutes;
90
- } else if (timingType === 'timed_per_person') {
91
- const hours = values.time_per_person_hours || 0;
92
- const minutes = values.time_per_person_minutes || 0;
93
- return hours * 60 + minutes;
94
- }
95
-
96
- // Default to 1 hour if no duration set
97
- return 60;
98
- };
99
-
100
- // Format duration for display
101
- const formatDuration = (minutes: number): string => {
102
- if (minutes < 60) {
103
- return `${minutes} min`;
104
- }
105
- const hours = Math.floor(minutes / 60);
106
- const mins = minutes % 60;
107
- if (mins === 0) {
108
- return `${hours} hour${hours > 1 ? 's' : ''}`;
109
- }
110
- return `${hours}h ${mins}m`;
111
- };
112
-
113
- // Format time for display (remove seconds if present)
114
- const formatTimeForDisplay = (time: string): string => {
115
- if (!time) return DEFAULT_OPENING_TIME;
116
- // Handle HH:MM:SS format from database
117
- return time.substring(0, 5);
118
- };
119
-
120
- const AvailabilitySection: React.FC<AvailabilitySectionProps> = ({
121
- values,
122
- onChange,
123
- providerId,
124
- }) => {
125
- const [openingHours, setOpeningHours] = useState<OpeningHours[]>([]);
126
- const [loadingHours, setLoadingHours] = useState(false);
127
-
128
- // Fetch provider opening hours
129
- useEffect(() => {
130
- const fetchOpeningHours = async () => {
131
- if (!providerId) return;
132
-
133
- setLoadingHours(true);
134
- try {
135
- const { data, error } = await supabase
136
- .from('provider_opening_hours')
137
- .select('day_of_week, is_open, open_time, close_time')
138
- .eq('provider_id', providerId)
139
- .order('day_of_week');
140
-
141
- if (error) {
142
- console.error('Error fetching opening hours:', error);
143
- } else if (data) {
144
- setOpeningHours(data);
145
- }
146
- } catch (err) {
147
- console.error('Error fetching opening hours:', err);
148
- } finally {
149
- setLoadingHours(false);
150
- }
151
- };
152
-
153
- fetchOpeningHours();
154
- }, [providerId]);
155
-
156
- // Get opening hours for a specific day
157
- const getOpeningHoursForDay = (dayValue: number): OpeningHours | undefined => {
158
- return openingHours.find(h => h.day_of_week === dayValue);
159
- };
160
-
161
- // Check if venue is open on a specific day
162
- const isVenueOpenOnDay = (dayValue: number): boolean => {
163
- const hours = getOpeningHoursForDay(dayValue);
164
- // If no hours data, assume open (fallback)
165
- if (!hours) return true;
166
- return hours.is_open;
167
- };
168
-
169
- // Get default first session time for a day (venue opening time)
170
- const getDefaultOpeningTimeForDay = (dayValue: number): string => {
171
- const hours = getOpeningHoursForDay(dayValue);
172
- if (hours?.open_time) {
173
- return formatTimeForDisplay(hours.open_time);
174
- }
175
- return DEFAULT_OPENING_TIME;
176
- };
177
-
178
- // Get earliest opening time across all open days (for daily mode)
179
- const getEarliestOpeningTime = (): string => {
180
- const openDays = openingHours.filter(h => h.is_open);
181
- if (openDays.length === 0) return DEFAULT_OPENING_TIME;
182
-
183
- const times = openDays.map(h => formatTimeForDisplay(h.open_time));
184
- return times.sort()[0] || DEFAULT_OPENING_TIME;
185
- };
186
-
187
- // Get latest closing time across all open days (for daily mode validation)
188
- const getLatestClosingTime = (): string | null => {
189
- const openDays = openingHours.filter(h => h.is_open);
190
- if (openDays.length === 0) return null;
191
-
192
- const times = openDays.map(h => formatTimeForDisplay(h.close_time));
193
- // Sort descending to get latest
194
- return times.sort().reverse()[0] || null;
195
- };
196
-
197
- // Check if a session exceeds closing time for daily mode - returns affected days info
198
- const getSessionIssuesDaily = (startTime: string): {
199
- exceedsClosing: boolean;
200
- startsAfterClose: boolean;
201
- beforeOpening: boolean;
202
- affectedDays: { day: string; issue: 'before_open' | 'after_close' | 'starts_after_close'; time: string }[];
203
- } => {
204
- const startMinutes = timeToMinutes(startTime);
205
- const sessionEndTime = addMinutesToTime(startTime, durationMinutes);
206
- const sessionEndMinutes = timeToMinutes(sessionEndTime);
207
-
208
- const affectedDays: { day: string; issue: 'before_open' | 'after_close' | 'starts_after_close'; time: string }[] = [];
209
-
210
- // Check each open day
211
- const openDays = openingHours.filter(h => h.is_open);
212
-
213
- for (const hours of openDays) {
214
- const dayInfo = DAYS_OF_WEEK.find(d => d.value === hours.day_of_week);
215
- if (!dayInfo) continue;
216
-
217
- const openTime = formatTimeForDisplay(hours.open_time);
218
- const closeTime = formatTimeForDisplay(hours.close_time);
219
- const openMinutes = timeToMinutes(openTime);
220
- const closeMinutes = timeToMinutes(closeTime);
221
-
222
- // Check if session starts before opening
223
- if (startMinutes < openMinutes) {
224
- affectedDays.push({ day: dayInfo.short, issue: 'before_open', time: openTime });
225
- }
226
-
227
- // Check if session starts after closing (completely outside hours)
228
- if (startMinutes >= closeMinutes) {
229
- affectedDays.push({ day: dayInfo.short, issue: 'starts_after_close', time: closeTime });
230
- }
231
- // Check if session ends after closing (but starts within hours)
232
- else if (sessionEndMinutes > closeMinutes && !(sessionEndMinutes < startMinutes)) {
233
- affectedDays.push({ day: dayInfo.short, issue: 'after_close', time: closeTime });
234
- }
235
- }
236
-
237
- const beforeOpeningDays = affectedDays.filter(d => d.issue === 'before_open');
238
- const startsAfterCloseDays = affectedDays.filter(d => d.issue === 'starts_after_close');
239
- const exceedsClosingDays = affectedDays.filter(d => d.issue === 'after_close');
240
-
241
- return {
242
- exceedsClosing: exceedsClosingDays.length > 0,
243
- startsAfterClose: startsAfterCloseDays.length > 0,
244
- beforeOpening: beforeOpeningDays.length > 0,
245
- affectedDays
246
- };
247
- };
248
-
249
- // Check if a session exceeds closing time for a specific day
250
- const getSessionIssuesForDay = (startTime: string, dayValue: number): {
251
- exceedsClosing: boolean;
252
- startsAfterClose: boolean;
253
- beforeOpening: boolean;
254
- openTime: string;
255
- closeTime: string;
256
- } => {
257
- const hours = getOpeningHoursForDay(dayValue);
258
- if (!hours || !hours.is_open) {
259
- return { exceedsClosing: false, startsAfterClose: false, beforeOpening: false, openTime: '', closeTime: '' };
260
- }
261
-
262
- const openTime = formatTimeForDisplay(hours.open_time);
263
- const closeTime = formatTimeForDisplay(hours.close_time);
264
- const startMinutes = timeToMinutes(startTime);
265
- const openMinutes = timeToMinutes(openTime);
266
- const closeMinutes = timeToMinutes(closeTime);
267
-
268
- const sessionEndTime = addMinutesToTime(startTime, durationMinutes);
269
- const sessionEndMinutes = timeToMinutes(sessionEndTime);
270
-
271
- // Session starts before opening
272
- const beforeOpening = startMinutes < openMinutes;
273
-
274
- // Session starts after closing (completely outside hours)
275
- const startsAfterClose = startMinutes >= closeMinutes;
276
-
277
- // Session ends after closing (but starts within hours) - handle overnight
278
- const exceedsClosing = !startsAfterClose && sessionEndMinutes > closeMinutes && !(sessionEndMinutes < startMinutes);
279
-
280
- return { exceedsClosing, startsAfterClose, beforeOpening, openTime, closeTime };
281
- };
282
-
283
-
284
- const availabilityType = values.availability_type || '';
285
- const isDaily = values.is_daily_availability !== false; // Default to true
286
- const incrementMinutes = values.increment_minutes || 15;
287
- const dailyTimes: string[] = values.daily_times || [];
288
- const dayAvailability: Record<number, DayAvailability> = values.day_availability ||
289
- DAYS_OF_WEEK.reduce((acc, day) => ({
290
- ...acc,
291
- [day.value]: { enabled: isVenueOpenOnDay(day.value), times: [] }
292
- }), {});
293
-
294
- // Get duration from timing settings
295
- const durationMinutes = getDurationMinutes(values);
296
-
297
- const handleAvailabilityTypeChange = (type: string) => {
298
- onChange('availability_type', type);
299
- };
300
-
301
- const handleDailyToggle = (checked: boolean) => {
302
- onChange('is_daily_availability', checked);
303
-
304
- // When switching to per-day mode, initialize day availability based on opening hours
305
- if (!checked) {
306
- const initialDayAvailability = DAYS_OF_WEEK.reduce((acc, day) => ({
307
- ...acc,
308
- [day.value]: {
309
- enabled: isVenueOpenOnDay(day.value),
310
- times: []
311
- }
312
- }), {});
313
- onChange('day_availability', initialDayAvailability);
314
- }
315
- };
316
-
317
- const handleIncrementChange = (value: number) => {
318
- onChange('increment_minutes', value);
319
- };
320
-
321
- // Calculate next session time based on last time + duration
322
- const getNextSessionTime = (existingTimes: string[], dayValue?: number): string => {
323
- if (existingTimes.length === 0) {
324
- // First session defaults to opening time
325
- if (dayValue !== undefined) {
326
- return getDefaultOpeningTimeForDay(dayValue);
327
- }
328
- return getEarliestOpeningTime();
329
- }
330
-
331
- // Get the last time and add duration
332
- const lastTime = existingTimes[existingTimes.length - 1];
333
- return addMinutesToTime(lastTime, durationMinutes);
334
- };
335
-
336
- // Daily times management
337
- const addDailyTime = () => {
338
- const nextTime = getNextSessionTime(dailyTimes);
339
- const newTimes = [...dailyTimes, nextTime];
340
- onChange('daily_times', newTimes);
341
- };
342
-
343
- const updateDailyTime = (index: number, time: string) => {
344
- const newTimes = [...dailyTimes];
345
- newTimes[index] = time;
346
- onChange('daily_times', newTimes);
347
- };
348
-
349
- const removeDailyTime = (index: number) => {
350
- const newTimes = dailyTimes.filter((_, i) => i !== index);
351
- onChange('daily_times', newTimes);
352
- };
353
-
354
- // Per-day times management
355
- const toggleDayEnabled = (dayValue: number) => {
356
- // Prevent enabling if venue is closed
357
- if (!isVenueOpenOnDay(dayValue) && !dayAvailability[dayValue]?.enabled) {
358
- return;
359
- }
360
-
361
- const newDayAvailability = {
362
- ...dayAvailability,
363
- [dayValue]: {
364
- ...dayAvailability[dayValue],
365
- enabled: !dayAvailability[dayValue]?.enabled
366
- }
367
- };
368
- onChange('day_availability', newDayAvailability);
369
- };
370
-
371
- const addDayTime = (dayValue: number) => {
372
- const currentTimes = dayAvailability[dayValue]?.times || [];
373
- const nextTime = getNextSessionTime(currentTimes, dayValue);
374
- const newDayAvailability = {
375
- ...dayAvailability,
376
- [dayValue]: {
377
- ...dayAvailability[dayValue],
378
- times: [...currentTimes, nextTime]
379
- }
380
- };
381
- onChange('day_availability', newDayAvailability);
382
- };
383
-
384
- const updateDayTime = (dayValue: number, index: number, time: string) => {
385
- const currentTimes = dayAvailability[dayValue]?.times || [];
386
- const newTimes = [...currentTimes];
387
- newTimes[index] = time;
388
- const newDayAvailability = {
389
- ...dayAvailability,
390
- [dayValue]: {
391
- ...dayAvailability[dayValue],
392
- times: newTimes
393
- }
394
- };
395
- onChange('day_availability', newDayAvailability);
396
- };
397
-
398
- const removeDayTime = (dayValue: number, index: number) => {
399
- const currentTimes = dayAvailability[dayValue]?.times || [];
400
- const newDayAvailability = {
401
- ...dayAvailability,
402
- [dayValue]: {
403
- ...dayAvailability[dayValue],
404
- times: currentTimes.filter((_, i) => i !== index)
405
- }
406
- };
407
- onChange('day_availability', newDayAvailability);
408
- };
409
-
410
- return (
411
- <div className="flex flex-col gap-4 pt-4 border-t border-border-primary">
412
- <h2 className="text-label-primary text-xl font-semibold">Availability</h2>
413
-
414
- {/* Availability Type Selection */}
415
- <RadioGroup
416
- value={availabilityType}
417
- onValueChange={handleAvailabilityTypeChange}
418
- className="flex gap-4"
419
- >
420
- <label className={`flex items-center gap-2 px-4 py-2 rounded-lg border cursor-pointer transition-colors ${
421
- availabilityType === 'fixed_sessions'
422
- ? 'border-border-selected bg-surface-action-soft'
423
- : 'border-border-primary hover:border-border-hover'
424
- }`}>
425
- <RadioGroupItem value="fixed_sessions" id="avail-fixed" />
426
- <span className="text-label-primary">Fixed Sessions</span>
427
- </label>
428
- <label className={`flex items-center gap-2 px-4 py-2 rounded-lg border cursor-pointer transition-colors ${
429
- availabilityType === 'incremental'
430
- ? 'border-border-selected bg-surface-action-soft'
431
- : 'border-border-primary hover:border-border-hover'
432
- }`}>
433
- <RadioGroupItem value="incremental" id="avail-incremental" />
434
- <span className="text-label-primary">Incremental</span>
435
- </label>
436
- </RadioGroup>
437
-
438
- {/* Show options only when a type is selected */}
439
- {availabilityType && (
440
- <>
441
- {/* Daily Toggle */}
442
- <div className="flex items-center justify-between py-2">
443
- <div className="flex flex-col">
444
- <Label className="text-label-primary">Same times every day</Label>
445
- <span className="text-label-tertiary text-sm">
446
- {isDaily ? 'Times apply to all open days' : 'Configure times per day'}
447
- </span>
448
- </div>
449
- <Switch
450
- checked={isDaily}
451
- onCheckedChange={handleDailyToggle}
452
- />
453
- </div>
454
-
455
- {/* Incremental: Show increment selector */}
456
- {availabilityType === 'incremental' && (
457
- <div className="flex flex-col gap-2">
458
- <Label>Time Increment</Label>
459
- <div className="flex flex-wrap gap-2">
460
- {INCREMENT_OPTIONS.map((option) => (
461
- <button
462
- key={option.value}
463
- type="button"
464
- onClick={() => handleIncrementChange(option.value)}
465
- className={`px-3 py-1.5 rounded-md text-sm transition-colors ${
466
- incrementMinutes === option.value
467
- ? 'bg-surface-action-soft border border-border-selected text-label-primary'
468
- : 'bg-surface-secondary border border-border-primary text-label-secondary hover:border-border-hover'
469
- }`}
470
- >
471
- {option.label}
472
- </button>
473
- ))}
474
- </div>
475
- <p className="text-label-tertiary text-sm mt-1">
476
- Customers can book every {incrementMinutes} minutes during available hours
477
- </p>
478
- </div>
479
- )}
480
-
481
- {/* Fixed Sessions: Show time inputs */}
482
- {availabilityType === 'fixed_sessions' && isDaily && (
483
- <div className="flex flex-col gap-3">
484
- <div className="flex items-center justify-between">
485
- <Label>Session Times</Label>
486
- {durationMinutes > 0 && (
487
- <span className="text-label-tertiary text-sm">
488
- Session duration: {formatDuration(durationMinutes)}
489
- </span>
490
- )}
491
- </div>
492
- <div className="flex flex-col gap-2">
493
- {dailyTimes.map((time, index) => {
494
- const issues = getSessionIssuesDaily(time);
495
- const hasWarning = issues.exceedsClosing || issues.startsAfterClose || issues.beforeOpening;
496
-
497
- // Group affected days by issue type
498
- const beforeOpenDays = issues.affectedDays.filter(d => d.issue === 'before_open');
499
- const startsAfterCloseDays = issues.affectedDays.filter(d => d.issue === 'starts_after_close');
500
- const endsAfterCloseDays = issues.affectedDays.filter(d => d.issue === 'after_close');
501
-
502
- return (
503
- <div key={index} className="flex flex-col gap-1">
504
- <div className="flex items-center gap-2">
505
- <Input
506
- type="time"
507
- value={time}
508
- onChange={(e) => updateDailyTime(index, e.target.value)}
509
- className={`w-32 ${hasWarning ? 'border-border-status-error' : ''}`}
510
- />
511
- <span className={`text-sm ${hasWarning ? 'text-label-status-error' : 'text-label-tertiary'}`}>
512
- → ends {addMinutesToTime(time, durationMinutes)}
513
- </span>
514
- <button
515
- type="button"
516
- onClick={() => removeDailyTime(index)}
517
- className="p-1.5 text-label-tertiary hover:text-label-danger transition-colors ml-auto"
518
- >
519
- <IconCross className="w-4 h-4 fill-current" />
520
- </button>
521
- </div>
522
- {hasWarning && (
523
- <div className="bg-surface-status-error border border-border-status-error rounded-md px-2 py-1.5 mt-1">
524
- {startsAfterCloseDays.length > 0 && (
525
- <span className="text-label-status-error text-xs block">
526
- ⚠ Session starts after venue closes
527
- </span>
528
- )}
529
- {endsAfterCloseDays.length > 0 && (
530
- <span className="text-label-status-error text-xs block">
531
- ⚠ Session ends after venue closes
532
- </span>
533
- )}
534
- {beforeOpenDays.length > 0 && (
535
- <span className="text-label-status-error text-xs block">
536
- ⚠ Session starts before venue opens
537
- </span>
538
- )}
539
- </div>
540
- )}
541
- </div>
542
- );
543
- })}
544
- <Button
545
- type="button"
546
- variant="outline"
547
- onClick={addDailyTime}
548
- className="w-fit"
549
- withIcon
550
- >
551
- <IconPlus className="w-4 h-4 fill-fill-secondary" />
552
- Add Session
553
- </Button>
554
- </div>
555
- </div>
556
- )}
557
-
558
- {/* Per-day configuration */}
559
- {!isDaily && (
560
- <div className="flex flex-col gap-4">
561
- {durationMinutes > 0 && availabilityType === 'fixed_sessions' && (
562
- <p className="text-label-tertiary text-sm">
563
- Session duration: {formatDuration(durationMinutes)}
564
- </p>
565
- )}
566
- {DAYS_OF_WEEK.map((day) => {
567
- const dayData = dayAvailability[day.value] || { enabled: true, times: [] };
568
- const venueOpen = isVenueOpenOnDay(day.value);
569
- const hours = getOpeningHoursForDay(day.value);
570
-
571
- return (
572
- <div
573
- key={day.value}
574
- className={`flex flex-col gap-2 p-3 rounded-lg ${
575
- venueOpen ? 'bg-surface-secondary' : 'bg-surface-tertiary opacity-60'
576
- }`}
577
- >
578
- <div className="flex items-center justify-between">
579
- <div className="flex items-center gap-3">
580
- <Switch
581
- checked={dayData.enabled && venueOpen}
582
- onCheckedChange={() => toggleDayEnabled(day.value)}
583
- disabled={!venueOpen}
584
- />
585
- <div className="flex flex-col">
586
- <span className={`text-sm font-medium ${
587
- dayData.enabled && venueOpen ? 'text-label-primary' : 'text-label-tertiary'
588
- }`}>
589
- {day.label}
590
- </span>
591
- {!venueOpen && (
592
- <span className="text-xs text-label-tertiary">Venue closed</span>
593
- )}
594
- {venueOpen && hours && (
595
- <span className="text-xs text-label-tertiary">
596
- Open {formatTimeForDisplay(hours.open_time)} - {formatTimeForDisplay(hours.close_time)}
597
- </span>
598
- )}
599
- </div>
600
- </div>
601
- </div>
602
-
603
- {dayData.enabled && venueOpen && availabilityType === 'fixed_sessions' && (
604
- <div className="flex flex-col gap-2 pl-10">
605
- <div className="flex flex-wrap items-center gap-2">
606
- {dayData.times.map((time, index) => {
607
- const issues = getSessionIssuesForDay(time, day.value);
608
- const hasWarning = issues.exceedsClosing || issues.startsAfterClose || issues.beforeOpening;
609
-
610
- // Build appropriate warning message
611
- let warningText = '';
612
- if (issues.startsAfterClose) {
613
- warningText = '⚠ Starts after close';
614
- } else if (issues.exceedsClosing) {
615
- warningText = '⚠ Ends after close';
616
- } else if (issues.beforeOpening) {
617
- warningText = '⚠ Starts before open';
618
- }
619
-
620
- return (
621
- <div key={index} className="flex flex-col gap-0.5">
622
- <div className={`flex items-center gap-1 rounded px-2 py-1 ${
623
- hasWarning ? 'bg-surface-status-error/20 border border-border-status-error' : 'bg-surface-primary'
624
- }`}>
625
- <Input
626
- type="time"
627
- value={time}
628
- onChange={(e) => updateDayTime(day.value, index, e.target.value)}
629
- className="w-28 h-7 text-sm border-0 bg-transparent p-0"
630
- />
631
- <button
632
- type="button"
633
- onClick={() => removeDayTime(day.value, index)}
634
- className="p-0.5 text-label-tertiary hover:text-label-danger transition-colors"
635
- >
636
- <IconCross className="w-3 h-3 fill-current" />
637
- </button>
638
- </div>
639
- {hasWarning && (
640
- <div className="bg-surface-status-error border border-border-status-error rounded px-1.5 py-0.5 mt-0.5">
641
- <span className="text-label-status-error text-[10px]">
642
- {warningText}
643
- </span>
644
- </div>
645
- )}
646
- </div>
647
- );
648
- })}
649
- <button
650
- type="button"
651
- onClick={() => addDayTime(day.value)}
652
- className="flex items-center gap-1 px-2 py-1 text-sm text-label-action hover:underline"
653
- >
654
- <IconPlus className="w-3 h-3 fill-fill-action" />
655
- Add
656
- </button>
657
- </div>
658
- </div>
659
- )}
660
-
661
- {dayData.enabled && venueOpen && availabilityType === 'incremental' && (
662
- <p className="text-label-tertiary text-sm pl-10">
663
- Available every {incrementMinutes} minutes
664
- </p>
665
- )}
666
- </div>
667
- );
668
- })}
669
- </div>
670
- )}
671
- </>
672
- )}
673
- </div>
674
- );
675
- };
676
-
677
- export default AvailabilitySection;