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

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 (414) hide show
  1. package/bitbucket-pipelines.yml +4 -13
  2. package/dist/Maintenance/Maintenance.scss.js +1 -1
  3. package/dist/index.js +2 -0
  4. package/dist/product-set/form/ProductsControl.d.ts +1 -2
  5. package/dist/product-set/form/ProductsControl.d.ts.map +1 -1
  6. package/dist/product-set/form/ProductsControl.js +24 -0
  7. package/dist/v2/components/ActionMenu/ActionMenu.scss.js +1 -1
  8. package/dist/v2/components/Badge/Badge.scss.js +1 -1
  9. package/dist/v2/components/Button/Button.scss.js +1 -1
  10. package/dist/v2/components/Button/GhostButton.scss.js +1 -1
  11. package/dist/v2/components/Checkbox/Checkbox.scss.js +1 -1
  12. package/dist/v2/components/DataTable/DataTable.d.ts.map +1 -1
  13. package/dist/v2/components/DataTable/DataTable.js +2 -86
  14. package/dist/v2/components/IconButton/IconButton.scss.js +1 -1
  15. package/dist/v2/components/Modal/DeleteModal.d.ts.map +1 -1
  16. package/dist/v2/components/Modal/DeleteModal.js +11 -13
  17. package/dist/v2/components/Modal/DeleteModal.scss.js +1 -1
  18. package/dist/v2/components/NPSScore/NPSScore.scss.js +1 -1
  19. package/dist/v2/components/NewTabs/NewTabs.scss.js +1 -1
  20. package/dist/v2/components/PeriodCard/PeriodCard.d.ts +66 -0
  21. package/dist/v2/components/PeriodCard/PeriodCard.d.ts.map +1 -0
  22. package/dist/v2/components/PeriodCard/PeriodCard.js +351 -0
  23. package/dist/v2/components/PeriodCard/PeriodCard.scss.js +6 -0
  24. package/dist/v2/components/PeriodCard/index.d.ts +3 -0
  25. package/dist/v2/components/PeriodCard/index.d.ts.map +1 -0
  26. package/dist/v2/components/ReorderRow/ReorderRow.d.ts +24 -0
  27. package/dist/v2/components/ReorderRow/ReorderRow.d.ts.map +1 -0
  28. package/dist/v2/components/ReorderRow/ReorderRow.js +109 -0
  29. package/dist/v2/components/ReorderRow/ReorderRow.scss.js +6 -0
  30. package/dist/v2/components/ReorderRow/index.d.ts +3 -0
  31. package/dist/v2/components/ReorderRow/index.d.ts.map +1 -0
  32. package/dist/v2/components/Select/Select.scss.js +1 -1
  33. package/dist/v2/components/StatusBadge/StatusBadge.scss.js +1 -1
  34. package/dist/v2/components/StepIndicator/StepIndicator.scss.js +1 -1
  35. package/dist/v2/components/Tabs/Tabs.scss.js +1 -1
  36. package/dist/v2/components/Toggle/Toggle.d.ts.map +1 -1
  37. package/dist/v2/components/Toggle/Toggle.js +5 -8
  38. package/dist/v2/components/Tooltip/Tooltip.scss.js +1 -1
  39. package/dist/v2/components/UserAvatar/UserAvatar.scss.js +1 -1
  40. package/dist/v2/components/UserPanel/UserPanel.scss.js +1 -1
  41. package/dist/v2/components/WYSIWYGEditor/WYSIWYGEditor.scss.js +1 -1
  42. package/dist/v2/components/ZoneCard/ZoneCard.scss.js +1 -1
  43. package/dist/v2/components/index.d.ts +4 -0
  44. package/dist/v2/components/index.d.ts.map +1 -1
  45. package/dist/v2/dashboard-analytics/chart/Chart.scss.js +1 -1
  46. package/dist/v2/dashboard-analytics/metric-card/MetricCard.scss.js +1 -1
  47. package/dist/v2/dashboard-analytics/venue-card/VenueCard.scss.js +1 -1
  48. package/dist/v2/dashboard-analytics/venue-closed-card/VenueClosedCard.scss.js +1 -1
  49. package/dist/v2/icons/index.js +16 -1
  50. package/dist/v2/index.d.ts +8 -0
  51. package/dist/v2/index.d.ts.map +1 -1
  52. package/dist/v2/navigation/DashboardLayout/AdminSidebar.scss.js +1 -1
  53. package/dist/v2/navigation/DashboardLayout/DashboardLayout.scss.js +1 -1
  54. package/dist/v2/navigation/DashboardLayout/ProviderSidebar.scss.js +1 -1
  55. package/dist/v2/navigation/DashboardLayout/TopNavigation.scss.js +1 -1
  56. package/dist/v2/pages/Settings/SettingsTabs.scss.js +1 -1
  57. package/dist/v2/pages/Settings/components/SidebarCustomisation.js +5 -0
  58. package/dist/v2/pages/Settings/components/SidebarCustomisation.scss.js +1 -1
  59. package/dist/v2/pages/Settings/components/SidebarNavItem.js +5 -0
  60. package/dist/v2/pages/auth/AuthLayout/AuthLayout.scss.js +1 -1
  61. package/dist/v2/shadcn/components/ui/accordion.d.ts +8 -0
  62. package/dist/v2/shadcn/components/ui/accordion.d.ts.map +1 -0
  63. package/dist/v2/shadcn/components/ui/alert-dialog.d.ts +21 -0
  64. package/dist/v2/shadcn/components/ui/alert-dialog.d.ts.map +1 -0
  65. package/dist/v2/shadcn/components/ui/alert.d.ts +9 -0
  66. package/dist/v2/shadcn/components/ui/alert.d.ts.map +1 -0
  67. package/dist/v2/shadcn/components/ui/aspect-ratio.d.ts +4 -0
  68. package/dist/v2/shadcn/components/ui/aspect-ratio.d.ts.map +1 -0
  69. package/dist/v2/shadcn/components/ui/avatar.d.ts +7 -0
  70. package/dist/v2/shadcn/components/ui/avatar.d.ts.map +1 -0
  71. package/dist/v2/shadcn/components/ui/badge.d.ts +10 -0
  72. package/dist/v2/shadcn/components/ui/badge.d.ts.map +1 -0
  73. package/dist/v2/shadcn/components/ui/breadcrumb.d.ts +20 -0
  74. package/dist/v2/shadcn/components/ui/breadcrumb.d.ts.map +1 -0
  75. package/dist/v2/shadcn/components/ui/button.d.ts +14 -0
  76. package/dist/v2/shadcn/components/ui/button.d.ts.map +1 -0
  77. package/dist/v2/shadcn/components/ui/calendar.d.ts +9 -0
  78. package/dist/v2/shadcn/components/ui/calendar.d.ts.map +1 -0
  79. package/dist/v2/shadcn/components/ui/card.d.ts +9 -0
  80. package/dist/v2/shadcn/components/ui/card.d.ts.map +1 -0
  81. package/dist/v2/shadcn/components/ui/carousel.d.ts +19 -0
  82. package/dist/v2/shadcn/components/ui/carousel.d.ts.map +1 -0
  83. package/dist/v2/shadcn/components/ui/checkbox.d.ts +6 -0
  84. package/dist/v2/shadcn/components/ui/checkbox.d.ts.map +1 -0
  85. package/dist/v2/shadcn/components/ui/checkbox.js +115 -0
  86. package/dist/v2/shadcn/components/ui/checkbox.scss.js +6 -0
  87. package/dist/v2/shadcn/components/ui/collapsible.d.ts +6 -0
  88. package/dist/v2/shadcn/components/ui/collapsible.d.ts.map +1 -0
  89. package/dist/v2/shadcn/components/ui/command.d.ts +83 -0
  90. package/dist/v2/shadcn/components/ui/command.d.ts.map +1 -0
  91. package/dist/v2/shadcn/components/ui/context-menu.d.ts +28 -0
  92. package/dist/v2/shadcn/components/ui/context-menu.d.ts.map +1 -0
  93. package/dist/v2/shadcn/components/ui/dialog.d.ts +20 -0
  94. package/dist/v2/shadcn/components/ui/dialog.d.ts.map +1 -0
  95. package/dist/v2/shadcn/components/ui/dialog.js +169 -0
  96. package/dist/v2/shadcn/components/ui/drawer.d.ts +23 -0
  97. package/dist/v2/shadcn/components/ui/drawer.d.ts.map +1 -0
  98. package/dist/v2/shadcn/components/ui/dropdown-menu.d.ts +28 -0
  99. package/dist/v2/shadcn/components/ui/dropdown-menu.d.ts.map +1 -0
  100. package/dist/v2/shadcn/components/ui/form.d.ts +24 -0
  101. package/dist/v2/shadcn/components/ui/form.d.ts.map +1 -0
  102. package/dist/v2/shadcn/components/ui/hover-card.d.ts +7 -0
  103. package/dist/v2/shadcn/components/ui/hover-card.d.ts.map +1 -0
  104. package/dist/v2/shadcn/components/ui/input-otp.d.ts +35 -0
  105. package/dist/v2/shadcn/components/ui/input-otp.d.ts.map +1 -0
  106. package/dist/v2/shadcn/components/ui/input.d.ts +6 -0
  107. package/dist/v2/shadcn/components/ui/input.d.ts.map +1 -0
  108. package/dist/v2/shadcn/components/ui/label.d.ts +6 -0
  109. package/dist/v2/shadcn/components/ui/label.d.ts.map +1 -0
  110. package/dist/v2/shadcn/components/ui/menubar.d.ts +34 -0
  111. package/dist/v2/shadcn/components/ui/menubar.d.ts.map +1 -0
  112. package/dist/v2/shadcn/components/ui/navigation-menu.d.ts +13 -0
  113. package/dist/v2/shadcn/components/ui/navigation-menu.d.ts.map +1 -0
  114. package/dist/v2/shadcn/components/ui/pagination.d.ts +29 -0
  115. package/dist/v2/shadcn/components/ui/pagination.d.ts.map +1 -0
  116. package/dist/v2/shadcn/components/ui/popover.d.ts +7 -0
  117. package/dist/v2/shadcn/components/ui/popover.d.ts.map +1 -0
  118. package/dist/v2/shadcn/components/ui/progress.d.ts +5 -0
  119. package/dist/v2/shadcn/components/ui/progress.d.ts.map +1 -0
  120. package/dist/v2/shadcn/components/ui/radio-card.d.ts +12 -0
  121. package/dist/v2/shadcn/components/ui/radio-card.d.ts.map +1 -0
  122. package/dist/v2/shadcn/components/ui/radio-group.d.ts +6 -0
  123. package/dist/v2/shadcn/components/ui/radio-group.d.ts.map +1 -0
  124. package/dist/v2/shadcn/components/ui/scroll-area.d.ts +6 -0
  125. package/dist/v2/shadcn/components/ui/scroll-area.d.ts.map +1 -0
  126. package/dist/v2/shadcn/components/ui/select.d.ts +14 -0
  127. package/dist/v2/shadcn/components/ui/select.d.ts.map +1 -0
  128. package/dist/v2/shadcn/components/ui/separator.d.ts +5 -0
  129. package/dist/v2/shadcn/components/ui/separator.d.ts.map +1 -0
  130. package/dist/v2/shadcn/components/ui/sheet.d.ts +26 -0
  131. package/dist/v2/shadcn/components/ui/sheet.d.ts.map +1 -0
  132. package/dist/v2/shadcn/components/ui/sidebar.d.ts +67 -0
  133. package/dist/v2/shadcn/components/ui/sidebar.d.ts.map +1 -0
  134. package/dist/v2/shadcn/components/ui/skeleton.d.ts +3 -0
  135. package/dist/v2/shadcn/components/ui/skeleton.d.ts.map +1 -0
  136. package/dist/v2/shadcn/components/ui/slider.d.ts +5 -0
  137. package/dist/v2/shadcn/components/ui/slider.d.ts.map +1 -0
  138. package/dist/v2/shadcn/components/ui/switch.d.ts +6 -0
  139. package/dist/v2/shadcn/components/ui/switch.d.ts.map +1 -0
  140. package/dist/v2/shadcn/components/ui/switch.js +115 -0
  141. package/dist/v2/shadcn/components/ui/switch.scss.js +6 -0
  142. package/dist/v2/shadcn/components/ui/table-pagination.d.ts +11 -0
  143. package/dist/v2/shadcn/components/ui/table-pagination.d.ts.map +1 -0
  144. package/dist/v2/shadcn/components/ui/table.d.ts +11 -0
  145. package/dist/v2/shadcn/components/ui/table.d.ts.map +1 -0
  146. package/dist/v2/shadcn/components/ui/tabs.d.ts +8 -0
  147. package/dist/v2/shadcn/components/ui/tabs.d.ts.map +1 -0
  148. package/dist/v2/shadcn/components/ui/textarea.d.ts +6 -0
  149. package/dist/v2/shadcn/components/ui/textarea.d.ts.map +1 -0
  150. package/dist/v2/shadcn/components/ui/toast.d.ts +16 -0
  151. package/dist/v2/shadcn/components/ui/toast.d.ts.map +1 -0
  152. package/dist/v2/shadcn/components/ui/toaster.d.ts +2 -0
  153. package/dist/v2/shadcn/components/ui/toaster.d.ts.map +1 -0
  154. package/dist/v2/shadcn/components/ui/toggle-group.d.ts +13 -0
  155. package/dist/v2/shadcn/components/ui/toggle-group.d.ts.map +1 -0
  156. package/dist/v2/shadcn/components/ui/toggle.d.ts +13 -0
  157. package/dist/v2/shadcn/components/ui/toggle.d.ts.map +1 -0
  158. package/dist/v2/shadcn/components/ui/tooltip.d.ts +8 -0
  159. package/dist/v2/shadcn/components/ui/tooltip.d.ts.map +1 -0
  160. package/dist/v2/shadcn/components/ui/use-toast.d.ts +3 -0
  161. package/dist/v2/shadcn/components/ui/use-toast.d.ts.map +1 -0
  162. package/dist/v2/shadcn/hooks/use-mobile.d.ts +2 -0
  163. package/dist/v2/shadcn/hooks/use-mobile.d.ts.map +1 -0
  164. package/dist/v2/shadcn/hooks/use-toast.d.ts +45 -0
  165. package/dist/v2/shadcn/hooks/use-toast.d.ts.map +1 -0
  166. package/dist/v2/shadcn/index.d.ts +20 -0
  167. package/dist/v2/shadcn/index.d.ts.map +1 -0
  168. package/dist/v2/shadcn/lib/utils.d.ts +3 -0
  169. package/dist/v2/shadcn/lib/utils.d.ts.map +1 -0
  170. package/dist/v2/shadcn/lib/utils.js +11 -0
  171. package/dist/v2/shadcn/styles/globals.css +112 -0
  172. package/dist/v2/styles/form/NewInput.scss.js +1 -1
  173. package/package.json +6 -6
  174. package/rollup.config.js +2 -16
  175. package/src/iframe/payment/payment-status-page/PaymentStatusPage.tsx +1 -1
  176. package/src/product-set/form/ProductsControl.tsx +1 -2
  177. package/src/v2/components/DataTable/DataTable.tsx +1 -23
  178. package/src/v2/components/Modal/DeleteModal.tsx +20 -12
  179. package/src/v2/components/PeriodCard/PeriodCard.scss +157 -0
  180. package/src/v2/components/PeriodCard/PeriodCard.stories.tsx +245 -0
  181. package/src/v2/components/PeriodCard/PeriodCard.tsx +350 -0
  182. package/src/v2/components/PeriodCard/index.ts +8 -0
  183. package/src/v2/components/ReorderRow/ReorderRow.scss +68 -0
  184. package/src/v2/components/ReorderRow/ReorderRow.stories.tsx +124 -0
  185. package/src/v2/components/ReorderRow/ReorderRow.tsx +88 -0
  186. package/src/v2/components/ReorderRow/index.ts +2 -0
  187. package/src/v2/components/Toggle/Toggle.tsx +5 -6
  188. package/src/v2/components/index.ts +6 -0
  189. package/src/v2/index.ts +82 -0
  190. package/src/v2/shadcn/_reference/AccountManagerCard.tsx +45 -0
  191. package/src/v2/shadcn/_reference/AffiliatesTable.tsx +178 -0
  192. package/src/v2/shadcn/_reference/AuditArchive.tsx +165 -0
  193. package/src/v2/shadcn/_reference/AuditContent.tsx +270 -0
  194. package/src/v2/shadcn/_reference/AutomationsGeneralSettings.tsx +251 -0
  195. package/src/v2/shadcn/_reference/AvatarUpload.tsx +150 -0
  196. package/src/v2/shadcn/_reference/BookingsSummaryCard.tsx +268 -0
  197. package/src/v2/shadcn/_reference/CodeCleanUpAudit.tsx +274 -0
  198. package/src/v2/shadcn/_reference/CompaniesTable.tsx +387 -0
  199. package/src/v2/shadcn/_reference/ComponentAudit.tsx +239 -0
  200. package/src/v2/shadcn/_reference/ConfigureSettingsCard.tsx +95 -0
  201. package/src/v2/shadcn/_reference/CustomerCard.tsx +155 -0
  202. package/src/v2/shadcn/_reference/DashboardCards.tsx +50 -0
  203. package/src/v2/shadcn/_reference/DashboardFooter.tsx +18 -0
  204. package/src/v2/shadcn/_reference/DiarySettings.tsx +187 -0
  205. package/src/v2/shadcn/_reference/DiaryView.tsx +998 -0
  206. package/src/v2/shadcn/_reference/EmptyState.tsx +76 -0
  207. package/src/v2/shadcn/_reference/EntityInfoCard.tsx +48 -0
  208. package/src/v2/shadcn/_reference/ExistingUserAssignments.tsx +131 -0
  209. package/src/v2/shadcn/_reference/FeatureToggle.tsx +72 -0
  210. package/src/v2/shadcn/_reference/FlowCard.tsx +170 -0
  211. package/src/v2/shadcn/_reference/FlowsContent.tsx +688 -0
  212. package/src/v2/shadcn/_reference/FlowsGeneralSettings.tsx +27 -0
  213. package/src/v2/shadcn/_reference/GeneralSettings.tsx +33 -0
  214. package/src/v2/shadcn/_reference/InventoryGeneralSettings.tsx +82 -0
  215. package/src/v2/shadcn/_reference/LanguageSelector.tsx +97 -0
  216. package/src/v2/shadcn/_reference/LoadingScreen.tsx +25 -0
  217. package/src/v2/shadcn/_reference/LoadingSpinner.tsx +41 -0
  218. package/src/v2/shadcn/_reference/ManagedClientsList.tsx +121 -0
  219. package/src/v2/shadcn/_reference/NPSScore.tsx +379 -0
  220. package/src/v2/shadcn/_reference/NPSSummaryCard.tsx +181 -0
  221. package/src/v2/shadcn/_reference/NotificationBanner.tsx +129 -0
  222. package/src/v2/shadcn/_reference/NotificationPanel.tsx +208 -0
  223. package/src/v2/shadcn/_reference/OnlineUsersCard.tsx +73 -0
  224. package/src/v2/shadcn/_reference/ProtectedRoute.tsx +39 -0
  225. package/src/v2/shadcn/_reference/ProvidersTable.tsx +353 -0
  226. package/src/v2/shadcn/_reference/QuickAddPanel.tsx +1057 -0
  227. package/src/v2/shadcn/_reference/QuickFilters.tsx +112 -0
  228. package/src/v2/shadcn/_reference/ScheduleView.tsx +410 -0
  229. package/src/v2/shadcn/_reference/ScrollToTop.tsx +14 -0
  230. package/src/v2/shadcn/_reference/SecondaryNav.tsx +50 -0
  231. package/src/v2/shadcn/_reference/SecuritySettings.tsx +258 -0
  232. package/src/v2/shadcn/_reference/SessionDetailView.tsx +294 -0
  233. package/src/v2/shadcn/_reference/Sidebar.tsx +14 -0
  234. package/src/v2/shadcn/_reference/SidebarAwareLayout.tsx +30 -0
  235. package/src/v2/shadcn/_reference/SidebarLabelCustomization.tsx +285 -0
  236. package/src/v2/shadcn/_reference/SimulationBanner.tsx +57 -0
  237. package/src/v2/shadcn/_reference/SortControls.tsx +65 -0
  238. package/src/v2/shadcn/_reference/StatusBadge.tsx +49 -0
  239. package/src/v2/shadcn/_reference/StyleGuideContent.tsx +331 -0
  240. package/src/v2/shadcn/_reference/TableActionMenu.tsx +126 -0
  241. package/src/v2/shadcn/_reference/ThemeProvider.tsx +119 -0
  242. package/src/v2/shadcn/_reference/ThemeSettings.tsx +73 -0
  243. package/src/v2/shadcn/_reference/TopNavigation.tsx +332 -0
  244. package/src/v2/shadcn/_reference/UserActivityHistory.tsx +209 -0
  245. package/src/v2/shadcn/_reference/UserLanguageSettings.tsx +94 -0
  246. package/src/v2/shadcn/_reference/UserPanel.tsx +472 -0
  247. package/src/v2/shadcn/_reference/UsersTable.tsx +1023 -0
  248. package/src/v2/shadcn/_reference/WaiverForm.tsx +301 -0
  249. package/src/v2/shadcn/_reference/WaiversGeneralSettings.tsx +46 -0
  250. package/src/v2/shadcn/_reference/WaiversTable.tsx +290 -0
  251. package/src/v2/shadcn/_reference/WaiversTemplatesSettings.tsx +416 -0
  252. package/src/v2/shadcn/_reference/ai/AIChatPanel.tsx +313 -0
  253. package/src/v2/shadcn/_reference/ai/AIChatSearchBar.tsx +36 -0
  254. package/src/v2/shadcn/_reference/ai/ChatInteractiveBlock.tsx +298 -0
  255. package/src/v2/shadcn/_reference/ai/ChatMessageContent.tsx +40 -0
  256. package/src/v2/shadcn/_reference/ai/parseInteractiveBlocks.ts +142 -0
  257. package/src/v2/shadcn/_reference/auth/AuthLayout.tsx +55 -0
  258. package/src/v2/shadcn/_reference/auth/CreatePasswordForm.tsx +285 -0
  259. package/src/v2/shadcn/_reference/auth/CreatePasswordPanel.tsx +20 -0
  260. package/src/v2/shadcn/_reference/auth/LoginFooter.tsx +14 -0
  261. package/src/v2/shadcn/_reference/auth/LoginForm.tsx +205 -0
  262. package/src/v2/shadcn/_reference/auth/LoginPanel.tsx +41 -0
  263. package/src/v2/shadcn/_reference/auth/ResetPasswordForm.tsx +102 -0
  264. package/src/v2/shadcn/_reference/auth/ResetPasswordPanel.tsx +20 -0
  265. package/src/v2/shadcn/_reference/auth/VerifyEmailForm.tsx +95 -0
  266. package/src/v2/shadcn/_reference/auth/VerifyEmailPanel.tsx +20 -0
  267. package/src/v2/shadcn/_reference/email/EmailAttachment.tsx +119 -0
  268. package/src/v2/shadcn/_reference/email/EmailAutomation.tsx +92 -0
  269. package/src/v2/shadcn/_reference/email/EmailPlaceholders.tsx +64 -0
  270. package/src/v2/shadcn/_reference/email/UnlayerEmailEditor.tsx +41 -0
  271. package/src/v2/shadcn/_reference/email/emailTemplateData.ts +53 -0
  272. package/src/v2/shadcn/_reference/emptyStateIcons.tsx +103 -0
  273. package/src/v2/shadcn/_reference/games/MazeGame.tsx +394 -0
  274. package/src/v2/shadcn/_reference/games/RunnerGame.tsx +497 -0
  275. package/src/v2/shadcn/_reference/logos/BookedLogoFull.tsx +36 -0
  276. package/src/v2/shadcn/_reference/logos/BookedLogoMark.tsx +31 -0
  277. package/src/v2/shadcn/_reference/logos/BookedLogoNew.tsx +36 -0
  278. package/src/v2/shadcn/_reference/pricing/DynamicPricingRulesEditor.tsx +401 -0
  279. package/src/v2/shadcn/_reference/pricing/DynamicPricingTierCard.tsx +77 -0
  280. package/src/v2/shadcn/_reference/pricing/DynamicPricingTiersList.tsx +218 -0
  281. package/src/v2/shadcn/_reference/pricing/PricingCalendar.tsx +810 -0
  282. package/src/v2/shadcn/_reference/pricing/PricingPeriodCard.tsx +152 -0
  283. package/src/v2/shadcn/_reference/pricing/PricingPeriodForm.tsx +377 -0
  284. package/src/v2/shadcn/_reference/pricing/PricingPeriodsList.tsx +213 -0
  285. package/src/v2/shadcn/_reference/pricing/getRuleSummary.ts +39 -0
  286. package/src/v2/shadcn/_reference/products/AvailabilityRulesSection.tsx +184 -0
  287. package/src/v2/shadcn/_reference/products/AvailabilitySection.tsx +677 -0
  288. package/src/v2/shadcn/_reference/products/BookingTypeConfigOptions.tsx +40 -0
  289. package/src/v2/shadcn/_reference/products/CapacityPeriodsSection.tsx +238 -0
  290. package/src/v2/shadcn/_reference/products/DynamicPricingTiersSection.tsx +131 -0
  291. package/src/v2/shadcn/_reference/products/GiftCardOrdersTab.tsx +192 -0
  292. package/src/v2/shadcn/_reference/products/GiftCardSettings.tsx +342 -0
  293. package/src/v2/shadcn/_reference/products/PackageProductsSection.tsx +322 -0
  294. package/src/v2/shadcn/_reference/products/PricingSection.tsx +173 -0
  295. package/src/v2/shadcn/_reference/products/ProductTypeFields.tsx +353 -0
  296. package/src/v2/shadcn/_reference/products/ProductTypeIcon.tsx +95 -0
  297. package/src/v2/shadcn/_reference/products/VariablePricingSection.tsx +140 -0
  298. package/src/v2/shadcn/_reference/products/productTypeConfig.ts +182 -0
  299. package/src/v2/shadcn/_reference/shared/BackButton.tsx +50 -0
  300. package/src/v2/shadcn/_reference/shared/CancelConfirmationDialog.tsx +18 -0
  301. package/src/v2/shadcn/_reference/shared/ConfirmationDialog.tsx +136 -0
  302. package/src/v2/shadcn/_reference/shared/DeleteConfirmationDialog.tsx +18 -0
  303. package/src/v2/shadcn/_reference/shared/DeleteEntityPage.tsx +221 -0
  304. package/src/v2/shadcn/_reference/shared/SidebarIcons.tsx +108 -0
  305. package/src/v2/shadcn/_reference/shared/UnifiedSidebar.tsx +722 -0
  306. package/src/v2/shadcn/_reference/tables/BulkActionsBar.tsx +68 -0
  307. package/src/v2/shadcn/_reference/tables/DataTable.tsx +221 -0
  308. package/src/v2/shadcn/_reference/tables/TableControls.tsx +94 -0
  309. package/src/v2/shadcn/_reference/tables/index.ts +3 -0
  310. package/src/v2/shadcn/_reference/tables/types.ts +79 -0
  311. package/src/v2/shadcn/_reference/zones/LegacyZoneSettings.tsx +299 -0
  312. package/src/v2/shadcn/components/ui/accordion.stories.tsx +63 -0
  313. package/src/v2/shadcn/components/ui/accordion.tsx +52 -0
  314. package/src/v2/shadcn/components/ui/alert-dialog.stories.tsx +44 -0
  315. package/src/v2/shadcn/components/ui/alert-dialog.tsx +104 -0
  316. package/src/v2/shadcn/components/ui/alert.stories.tsx +44 -0
  317. package/src/v2/shadcn/components/ui/alert.tsx +43 -0
  318. package/src/v2/shadcn/components/ui/aspect-ratio.stories.tsx +46 -0
  319. package/src/v2/shadcn/components/ui/aspect-ratio.tsx +5 -0
  320. package/src/v2/shadcn/components/ui/avatar.stories.tsx +39 -0
  321. package/src/v2/shadcn/components/ui/avatar.tsx +38 -0
  322. package/src/v2/shadcn/components/ui/badge.stories.tsx +17 -0
  323. package/src/v2/shadcn/components/ui/badge.tsx +30 -0
  324. package/src/v2/shadcn/components/ui/breadcrumb.stories.tsx +91 -0
  325. package/src/v2/shadcn/components/ui/breadcrumb.tsx +90 -0
  326. package/src/v2/shadcn/components/ui/button.stories.tsx +20 -0
  327. package/src/v2/shadcn/components/ui/button.tsx +60 -0
  328. package/src/v2/shadcn/components/ui/calendar.stories.tsx +61 -0
  329. package/src/v2/shadcn/components/ui/calendar.tsx +54 -0
  330. package/src/v2/shadcn/components/ui/card.stories.tsx +37 -0
  331. package/src/v2/shadcn/components/ui/card.tsx +43 -0
  332. package/src/v2/shadcn/components/ui/carousel.stories.tsx +92 -0
  333. package/src/v2/shadcn/components/ui/carousel.tsx +224 -0
  334. package/src/v2/shadcn/components/ui/checkbox.scss +38 -0
  335. package/src/v2/shadcn/components/ui/checkbox.stories.tsx +23 -0
  336. package/src/v2/shadcn/components/ui/checkbox.tsx +24 -0
  337. package/src/v2/shadcn/components/ui/collapsible.stories.tsx +59 -0
  338. package/src/v2/shadcn/components/ui/collapsible.tsx +9 -0
  339. package/src/v2/shadcn/components/ui/command.stories.tsx +70 -0
  340. package/src/v2/shadcn/components/ui/command.tsx +132 -0
  341. package/src/v2/shadcn/components/ui/context-menu.stories.tsx +72 -0
  342. package/src/v2/shadcn/components/ui/context-menu.tsx +178 -0
  343. package/src/v2/shadcn/components/ui/dialog.stories.tsx +67 -0
  344. package/src/v2/shadcn/components/ui/dialog.tsx +95 -0
  345. package/src/v2/shadcn/components/ui/drawer.stories.tsx +50 -0
  346. package/src/v2/shadcn/components/ui/drawer.tsx +87 -0
  347. package/src/v2/shadcn/components/ui/dropdown-menu.stories.tsx +73 -0
  348. package/src/v2/shadcn/components/ui/dropdown-menu.tsx +179 -0
  349. package/src/v2/shadcn/components/ui/form.stories.tsx +105 -0
  350. package/src/v2/shadcn/components/ui/form.tsx +129 -0
  351. package/src/v2/shadcn/components/ui/hover-card.stories.tsx +35 -0
  352. package/src/v2/shadcn/components/ui/hover-card.tsx +27 -0
  353. package/src/v2/shadcn/components/ui/input-otp.stories.tsx +72 -0
  354. package/src/v2/shadcn/components/ui/input-otp.tsx +61 -0
  355. package/src/v2/shadcn/components/ui/input.stories.tsx +16 -0
  356. package/src/v2/shadcn/components/ui/input.tsx +25 -0
  357. package/src/v2/shadcn/components/ui/label.stories.tsx +13 -0
  358. package/src/v2/shadcn/components/ui/label.tsx +17 -0
  359. package/src/v2/shadcn/components/ui/menubar.stories.tsx +86 -0
  360. package/src/v2/shadcn/components/ui/menubar.tsx +207 -0
  361. package/src/v2/shadcn/components/ui/navigation-menu.stories.tsx +68 -0
  362. package/src/v2/shadcn/components/ui/navigation-menu.tsx +120 -0
  363. package/src/v2/shadcn/components/ui/pagination.stories.tsx +78 -0
  364. package/src/v2/shadcn/components/ui/pagination.tsx +81 -0
  365. package/src/v2/shadcn/components/ui/popover.stories.tsx +44 -0
  366. package/src/v2/shadcn/components/ui/popover.tsx +29 -0
  367. package/src/v2/shadcn/components/ui/progress.stories.tsx +17 -0
  368. package/src/v2/shadcn/components/ui/progress.tsx +23 -0
  369. package/src/v2/shadcn/components/ui/radio-card.stories.tsx +68 -0
  370. package/src/v2/shadcn/components/ui/radio-card.tsx +52 -0
  371. package/src/v2/shadcn/components/ui/radio-group.stories.tsx +77 -0
  372. package/src/v2/shadcn/components/ui/radio-group.tsx +35 -0
  373. package/src/v2/shadcn/components/ui/scroll-area.stories.tsx +56 -0
  374. package/src/v2/shadcn/components/ui/scroll-area.tsx +38 -0
  375. package/src/v2/shadcn/components/ui/select.stories.tsx +60 -0
  376. package/src/v2/shadcn/components/ui/select.tsx +148 -0
  377. package/src/v2/shadcn/components/ui/separator.stories.tsx +30 -0
  378. package/src/v2/shadcn/components/ui/separator.tsx +20 -0
  379. package/src/v2/shadcn/components/ui/sheet.stories.tsx +115 -0
  380. package/src/v2/shadcn/components/ui/sheet.tsx +107 -0
  381. package/src/v2/shadcn/components/ui/sidebar.stories.tsx +167 -0
  382. package/src/v2/shadcn/components/ui/sidebar.tsx +637 -0
  383. package/src/v2/shadcn/components/ui/skeleton.stories.tsx +36 -0
  384. package/src/v2/shadcn/components/ui/skeleton.tsx +7 -0
  385. package/src/v2/shadcn/components/ui/slider.stories.tsx +16 -0
  386. package/src/v2/shadcn/components/ui/slider.tsx +23 -0
  387. package/src/v2/shadcn/components/ui/switch.scss +63 -0
  388. package/src/v2/shadcn/components/ui/switch.stories.tsx +23 -0
  389. package/src/v2/shadcn/components/ui/switch.tsx +24 -0
  390. package/src/v2/shadcn/components/ui/table-pagination.stories.tsx +81 -0
  391. package/src/v2/shadcn/components/ui/table-pagination.tsx +61 -0
  392. package/src/v2/shadcn/components/ui/table.stories.tsx +40 -0
  393. package/src/v2/shadcn/components/ui/table.tsx +72 -0
  394. package/src/v2/shadcn/components/ui/tabs.stories.tsx +85 -0
  395. package/src/v2/shadcn/components/ui/tabs.tsx +53 -0
  396. package/src/v2/shadcn/components/ui/textarea.stories.tsx +15 -0
  397. package/src/v2/shadcn/components/ui/textarea.tsx +21 -0
  398. package/src/v2/shadcn/components/ui/toast.stories.tsx +77 -0
  399. package/src/v2/shadcn/components/ui/toast.tsx +111 -0
  400. package/src/v2/shadcn/components/ui/toaster.stories.tsx +46 -0
  401. package/src/v2/shadcn/components/ui/toaster.tsx +24 -0
  402. package/src/v2/shadcn/components/ui/toggle-group.stories.tsx +95 -0
  403. package/src/v2/shadcn/components/ui/toggle-group.tsx +49 -0
  404. package/src/v2/shadcn/components/ui/toggle.stories.tsx +18 -0
  405. package/src/v2/shadcn/components/ui/toggle.tsx +37 -0
  406. package/src/v2/shadcn/components/ui/tooltip.stories.tsx +57 -0
  407. package/src/v2/shadcn/components/ui/tooltip.tsx +28 -0
  408. package/src/v2/shadcn/components/ui/use-toast.ts +3 -0
  409. package/src/v2/shadcn/hooks/use-mobile.tsx +19 -0
  410. package/src/v2/shadcn/hooks/use-toast.ts +184 -0
  411. package/src/v2/shadcn/index.ts +76 -0
  412. package/src/v2/shadcn/lib/utils.ts +6 -0
  413. package/src/v2/shadcn/styles/globals.css +112 -0
  414. package/.vscode/settings.json +0 -3
@@ -0,0 +1,472 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import LoadingSpinner from './LoadingSpinner';
3
+ import { useNavigate, useLocation } from 'react-router-dom';
4
+ import { IconCross } from '../../icons';
5
+ import userIcon from '@/assets/Icon_User.svg';
6
+ import settingsIcon from '@/assets/Icon_Settings.svg';
7
+ import simulationIcon from '@/assets/Icon_Simulation.svg';
8
+ import crossIcon from '@/assets/Icon_Cross.svg';
9
+ import logoutIcon from '@/assets/Icon_Logout.svg';
10
+ import { supabase } from '@/integrations/supabase/client';
11
+ import { formatUserId } from '@/lib/userUtils';
12
+ import { useAuth } from '@/contexts/AuthContext';
13
+ import { useUser } from '@/contexts/UserContext';
14
+ import { useSimulation } from '@/contexts/SimulationContext';
15
+ import { useUserRole, AppRole } from '../hooks/useUserRole';
16
+ import { Switch } from './ui/switch';
17
+ import { RadioGroup, RadioGroupItem } from './ui/radio-group';
18
+ import { Input } from './ui/input';
19
+ import { Label } from './ui/label';
20
+
21
+ interface UserPanelProps {
22
+ isOpen: boolean;
23
+ onClose: () => void;
24
+ userName: string;
25
+ }
26
+
27
+ export const UserPanel: React.FC<UserPanelProps> = ({
28
+ isOpen,
29
+ onClose
30
+ }) => {
31
+ const navigate = useNavigate();
32
+ const location = useLocation();
33
+ const { signOut } = useAuth();
34
+ const { profile } = useUser();
35
+ const { primaryRole, roleWeight } = useUserRole();
36
+ const simulation = useSimulation();
37
+ const [userRole, setUserRole] = useState<string>('');
38
+ const [selectedSimulation, setSelectedSimulation] = useState<string>('none');
39
+ const [userIdSearch, setUserIdSearch] = useState<string>('');
40
+ const [actualRoleWeight, setActualRoleWeight] = useState<number>(0);
41
+ const [searchResults, setSearchResults] = useState<Array<{
42
+ id: string;
43
+ fullName: string | null;
44
+ email: string | null;
45
+ userNumber: number | null;
46
+ role: string;
47
+ roleWeight: number;
48
+ }>>([]);
49
+ const [isSearching, setIsSearching] = useState(false);
50
+ const [simulatedUserNumber, setSimulatedUserNumber] = useState<number | null>(null);
51
+ const [simulatedUserName, setSimulatedUserName] = useState<string | null>(null);
52
+
53
+ const displayName = profile?.fullName || 'User';
54
+ const firstName = profile?.firstName || 'User';
55
+ const initials = profile?.initials || 'U';
56
+ const email = profile?.email || '';
57
+ const userNumber = profile?.userNumber || null;
58
+ const avatarUrl = profile?.avatarUrl || null;
59
+
60
+ // Fetch user role data on mount
61
+ useEffect(() => {
62
+ const fetchUserRole = async () => {
63
+ try {
64
+ const { data: { user } } = await supabase.auth.getUser();
65
+
66
+ if (user) {
67
+ // Fetch user's primary role
68
+ const { data: roleData } = await supabase
69
+ .rpc('get_user_primary_role', { _user_id: user.id });
70
+
71
+ if (roleData) {
72
+ // Format role name for display
73
+ const formattedRole = (roleData as string)
74
+ .split('_')
75
+ .map((word: string) => word.charAt(0).toUpperCase() + word.slice(1))
76
+ .join(' ');
77
+ setUserRole(formattedRole);
78
+ }
79
+
80
+ // Fetch user's ACTUAL max role weight (not simulated)
81
+ const { data: weightData } = await supabase
82
+ .rpc('get_user_max_role_weight', { _user_id: user.id });
83
+
84
+ if (weightData !== null) {
85
+ setActualRoleWeight(weightData);
86
+ }
87
+ }
88
+ } catch (error) {
89
+ console.error('Error fetching user role:', error);
90
+ }
91
+ };
92
+
93
+ fetchUserRole();
94
+ }, []);
95
+
96
+ // Sync simulation state with actual simulation status
97
+ useEffect(() => {
98
+ if (simulation.isSimulating) {
99
+ if (simulation.simulatedUserId) {
100
+ setSelectedSimulation('simulate-user');
101
+ // Fetch simulated user's details for local display
102
+ const fetchSimulatedUserDetails = async () => {
103
+ const { data } = await supabase
104
+ .from('profiles')
105
+ .select('user_number, full_name')
106
+ .eq('id', simulation.simulatedUserId)
107
+ .maybeSingle();
108
+
109
+ if (data) {
110
+ setSimulatedUserNumber(data.user_number);
111
+ setSimulatedUserName(data.full_name);
112
+ }
113
+ };
114
+ fetchSimulatedUserDetails();
115
+ } else if (simulation.simulatedRole) {
116
+ setSelectedSimulation(simulation.simulatedRole);
117
+ }
118
+ } else {
119
+ setSelectedSimulation('none');
120
+ setSimulatedUserNumber(null);
121
+ setSimulatedUserName(null);
122
+ }
123
+ }, [simulation.isSimulating, simulation.simulatedRole, simulation.simulatedUserId]);
124
+
125
+ // Role weights mapping
126
+ const roleWeights: Record<AppRole, number> = {
127
+ super_admin: 999,
128
+ system_admin: 500,
129
+ admin: 200,
130
+ manager: 100,
131
+ operations: 50,
132
+ staff: 25,
133
+ viewer: 10,
134
+ desk: 10,
135
+ customer: 0,
136
+ };
137
+
138
+ // Get available roles for simulation (lower weight than user's ACTUAL role, not simulated)
139
+ const getAvailableRoles = (): AppRole[] => {
140
+ if (!actualRoleWeight) return [];
141
+ return (Object.keys(roleWeights) as AppRole[]).filter(
142
+ role => role !== 'customer' && roleWeights[role] < actualRoleWeight
143
+ );
144
+ };
145
+
146
+ const handleSimulationChange = (value: string) => {
147
+ setSelectedSimulation(value);
148
+
149
+ if (value === 'none') {
150
+ simulation.stopSimulation();
151
+ setUserIdSearch('');
152
+ setSearchResults([]);
153
+ setSimulatedUserNumber(null);
154
+ setSimulatedUserName(null);
155
+ } else if (value === 'simulate-user') {
156
+ setUserIdSearch('');
157
+ setSearchResults([]);
158
+ } else {
159
+ const weight = roleWeights[value as AppRole];
160
+ simulation.startSimulation(value as AppRole, weight);
161
+ setUserIdSearch('');
162
+ setSearchResults([]);
163
+ setSimulatedUserNumber(null);
164
+ setSimulatedUserName(null);
165
+ }
166
+ };
167
+
168
+ const handleUserIdSearch = async (searchTerm: string) => {
169
+ if (!searchTerm.trim()) {
170
+ setSearchResults([]);
171
+ return;
172
+ }
173
+
174
+ setIsSearching(true);
175
+ try {
176
+ // Search by user_number, user ID, name, or email
177
+ const { data: profiles, error } = await supabase
178
+ .from('profiles')
179
+ .select('id, full_name, email, user_number')
180
+ .or(
181
+ /^\d+$/.test(searchTerm)
182
+ ? `user_number.eq.${parseInt(searchTerm)},id.ilike.%${searchTerm}%,full_name.ilike.%${searchTerm}%,email.ilike.%${searchTerm}%`
183
+ : `id.ilike.%${searchTerm}%,full_name.ilike.%${searchTerm}%,email.ilike.%${searchTerm}%`
184
+ )
185
+ .limit(10);
186
+
187
+ if (error) {
188
+ console.error('Error searching users:', error);
189
+ setSearchResults([]);
190
+ return;
191
+ }
192
+
193
+ console.log('Search results:', profiles);
194
+
195
+ if (profiles && profiles.length > 0) {
196
+ // Fetch roles for each user
197
+ const usersWithRoles = await Promise.all(
198
+ profiles.map(async (profile) => {
199
+ const { data: roleData } = await supabase
200
+ .rpc('get_user_primary_role', { _user_id: profile.id });
201
+
202
+ const { data: weightData } = await supabase
203
+ .rpc('get_user_max_role_weight', { _user_id: profile.id });
204
+
205
+ return {
206
+ id: profile.id,
207
+ fullName: profile.full_name,
208
+ email: profile.email,
209
+ userNumber: profile.user_number,
210
+ role: roleData || 'customer',
211
+ roleWeight: weightData || 0,
212
+ };
213
+ })
214
+ );
215
+
216
+ console.log('Users with roles:', usersWithRoles);
217
+ setSearchResults(usersWithRoles);
218
+ } else {
219
+ console.log('No profiles found');
220
+ setSearchResults([]);
221
+ }
222
+ } catch (error) {
223
+ console.error('Error searching users:', error);
224
+ setSearchResults([]);
225
+ } finally {
226
+ setIsSearching(false);
227
+ }
228
+ };
229
+
230
+ const handleSelectUser = (user: typeof searchResults[0]) => {
231
+ setUserIdSearch('');
232
+ setSearchResults([]);
233
+ simulation.startSimulation(user.role as AppRole, user.roleWeight, user.id);
234
+ };
235
+
236
+ if (!isOpen) return null;
237
+
238
+ return (
239
+ <>
240
+ {/* Overlay */}
241
+ <div
242
+ className="fixed inset-0 z-40 animate-fade-in"
243
+ style={{ backgroundColor: 'var(--overlay-curtain)' }}
244
+ onClick={onClose}
245
+ />
246
+
247
+ {/* Panel */}
248
+ <div
249
+ className="fixed right-0 top-0 h-screen w-full sm:w-[320px] bg-surface-primary shadow-xl z-50 animate-slide-in-right"
250
+ onClick={(e) => e.stopPropagation()}
251
+ >
252
+ {/* Header */}
253
+ <div className="flex items-center justify-between p-4 border-b border-border-primary">
254
+ <div className="flex items-center gap-2">
255
+ <div className="w-8 h-8 relative flex items-center justify-center flex-shrink-0 overflow-hidden rounded-full">
256
+ {avatarUrl ? (
257
+ <img src={avatarUrl} alt="Profile" className="w-full h-full object-cover" />
258
+ ) : (
259
+ <>
260
+ <svg width="32" height="32" viewBox="0 0 32 32" fill="none" className="absolute">
261
+ <circle cx="16" cy="16" r="15" className="fill-fill-secondary stroke-fill-secondary" fillOpacity="0.2" strokeWidth="2" />
262
+ </svg>
263
+ <div className="text-[10px] font-extrabold leading-[8px] text-label-secondary relative mt-0.5">
264
+ {initials}
265
+ </div>
266
+ </>
267
+ )}
268
+ </div>
269
+ <div className="flex flex-col gap-0.5">
270
+ <h2 className="text-sm font-semibold text-label-primary">Hey {firstName}</h2>
271
+ {email && (
272
+ <span className="text-label-secondary text-xs leading-3">{email}</span>
273
+ )}
274
+ </div>
275
+ </div>
276
+ <button
277
+ onClick={onClose}
278
+ className="p-2 rounded-lg hover:bg-surface-primary-hover transition-colors flex-shrink-0 flex items-center justify-center"
279
+ aria-label="Close user menu"
280
+ >
281
+ <IconCross className="w-5 h-5 text-label-secondary" />
282
+ </button>
283
+ </div>
284
+
285
+ {/* Menu Items */}
286
+ <div className="flex flex-col flex-1 p-2 gap-1 pb-0">
287
+ <button
288
+ onClick={() => {
289
+ navigate('/profile');
290
+ onClose();
291
+ }}
292
+ className="flex items-center gap-2 w-full p-2 rounded-lg hover:bg-surface-primary-hover active:bg-surface-primary-pressed transition-colors text-label-primary outline-none text-left"
293
+ >
294
+ <img src={userIcon} alt="" className="w-5 h-5" />
295
+ <span className="text-[13px] font-medium leading-4">Profile</span>
296
+ </button>
297
+ <button
298
+ onClick={() => {
299
+ navigate('/user-settings', { state: { returnTo: location.pathname } });
300
+ onClose();
301
+ }}
302
+ className="flex items-center gap-2 w-full p-2 rounded-lg hover:bg-surface-primary-hover active:bg-surface-primary-pressed transition-colors text-label-primary outline-none text-left"
303
+ >
304
+ <img src={settingsIcon} alt="" className="w-5 h-5" />
305
+ <span className="text-[13px] font-medium leading-4">User Settings</span>
306
+ </button>
307
+ </div>
308
+
309
+ {/* Simulation Section - Only for System Admin (500) and Super Admin (999) */}
310
+ {simulation.canAccessSimulation && (
311
+ <div className="p-2 pt-1">
312
+ <div className="space-y-3 pt-3 pb-3">
313
+ <div className="flex items-center gap-2 px-2">
314
+ <img src={simulationIcon} alt="" className="w-5 h-5" />
315
+ <Label className="text-[13px] font-medium leading-4 text-label-primary">
316
+ Role / User Simulation
317
+ </Label>
318
+ </div>
319
+
320
+ <RadioGroup value={selectedSimulation} onValueChange={handleSimulationChange}>
321
+ <div className="space-y-2 pl-2">
322
+ {/* No Simulation Option */}
323
+ <div className="flex items-center space-x-2">
324
+ <RadioGroupItem value="none" id="sim-none" />
325
+ <Label
326
+ htmlFor="sim-none"
327
+ className="text-sm text-label-primary cursor-pointer font-normal"
328
+ >
329
+ No Simulation
330
+ </Label>
331
+ </div>
332
+
333
+ {/* Available Role Options */}
334
+ {getAvailableRoles().map((role) => (
335
+ <div key={role} className="flex items-center space-x-2">
336
+ <RadioGroupItem value={role} id={`role-${role}`} />
337
+ <Label
338
+ htmlFor={`role-${role}`}
339
+ className="text-sm text-label-primary cursor-pointer font-normal"
340
+ >
341
+ {role.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')}
342
+ </Label>
343
+ </div>
344
+ ))}
345
+
346
+ {/* Simulate User Option */}
347
+ <div className="flex items-center space-x-2">
348
+ <RadioGroupItem value="simulate-user" id="sim-user" />
349
+ <Label
350
+ htmlFor="sim-user"
351
+ className="text-sm text-label-primary cursor-pointer font-normal"
352
+ >
353
+ Simulate user
354
+ </Label>
355
+ </div>
356
+
357
+ {/* Show simulated user card when a user is being simulated */}
358
+ {simulation.isSimulating && simulation.simulatedUserId && simulatedUserName && (
359
+ <div className="mt-2 bg-surface-status-info text-label-status-info pl-4 pr-2 py-2 flex items-center justify-between gap-3 rounded-lg border border-border-status-info">
360
+ <div className="flex items-center gap-3 flex-1 min-w-0">
361
+ <div className="relative flex items-center justify-center w-5 h-5">
362
+ <div className="absolute inset-0 bg-surface-primary rounded-full animate-soft-pulse scale-150" />
363
+ <img src={simulationIcon} alt="" className="relative w-4 h-4 z-10" />
364
+ </div>
365
+ <div className="flex flex-col gap-0.5 flex-1 min-w-0">
366
+ <span className="text-xs font-semibold truncate">
367
+ {simulatedUserName}
368
+ </span>
369
+ <span className="text-[10px] font-mono opacity-70 truncate">
370
+ {simulation.simulatedRole?.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')} • User #{simulatedUserNumber?.toString().padStart(2, '0') || 'N/A'}
371
+ </span>
372
+ </div>
373
+ </div>
374
+ <button
375
+ onClick={() => simulation.stopSimulation()}
376
+ className="p-1 hover:bg-surface-primary/20 rounded transition-colors flex-shrink-0 self-center"
377
+ aria-label="Stop simulation"
378
+ >
379
+ <img src={crossIcon} alt="" className="w-3 h-3" />
380
+ </button>
381
+ </div>
382
+ )}
383
+ </div>
384
+ </RadioGroup>
385
+
386
+ {/* User Search - Show when "Simulate user" is selected AND no user is currently simulated */}
387
+ {selectedSimulation === 'simulate-user' && !(simulation.isSimulating && simulation.simulatedUserId) && (
388
+ <div className="space-y-2 pl-2">
389
+ <div className="relative">
390
+ <Input
391
+ type="text"
392
+
393
+ value={userIdSearch}
394
+ onChange={(e) => {
395
+ setUserIdSearch(e.target.value);
396
+ handleUserIdSearch(e.target.value);
397
+ }}
398
+ className="w-full"
399
+ autoComplete="off"
400
+ data-lpignore="true"
401
+ data-form-type="other"
402
+ />
403
+ {isSearching && (
404
+ <div className="absolute right-3 top-1/2 -translate-y-1/2">
405
+ <LoadingSpinner size="sm" className="w-4 h-4" />
406
+ </div>
407
+ )}
408
+ </div>
409
+
410
+ {searchResults.length > 0 && (
411
+ <div className="mt-2 bg-surface-secondary rounded-lg border border-border-primary max-h-[200px] overflow-y-auto">
412
+ {searchResults.map((user) => (
413
+ <button
414
+ key={user.id}
415
+ onClick={() => handleSelectUser(user)}
416
+ className="w-full p-3 text-left hover:bg-surface-primary-hover transition-colors border-b border-border-primary last:border-b-0"
417
+ >
418
+ <div className="flex items-center justify-between gap-3">
419
+ <div className="flex-1 min-w-0">
420
+ <div className="flex items-center gap-2 mb-1">
421
+ <span className="text-xs font-mono font-semibold text-label-tertiary">
422
+ User: {user.userNumber?.toString().padStart(2, '0') || 'N/A'}
423
+ </span>
424
+ <span className="text-xs px-1.5 py-0.5 rounded bg-surface-tertiary text-label-tertiary font-medium">
425
+ {user.role.split('_').map(word => word.charAt(0).toUpperCase() + word.slice(1)).join(' ')}
426
+ </span>
427
+ </div>
428
+ <div className="text-sm font-medium text-label-primary truncate">
429
+ {user.fullName || 'No name'}
430
+ </div>
431
+ <div className="text-xs text-label-secondary truncate">
432
+ {user.email || 'No email'}
433
+ </div>
434
+ </div>
435
+ </div>
436
+ </button>
437
+ ))}
438
+ </div>
439
+ )}
440
+ </div>
441
+ )}
442
+ </div>
443
+ </div>
444
+ )}
445
+
446
+ {/* Logout */}
447
+ <div className="p-2 pt-1">
448
+ <button
449
+ onClick={async () => {
450
+ await signOut();
451
+ navigate('/auth');
452
+ onClose();
453
+ }}
454
+ className="flex items-center gap-2 w-full p-2 rounded-lg hover:bg-surface-primary-hover active:bg-surface-primary-pressed transition-colors text-label-primary outline-none text-left"
455
+ >
456
+ <img src={logoutIcon} alt="" className="w-5 h-5" />
457
+ <span className="text-[13px] font-medium leading-4">Log out</span>
458
+ </button>
459
+ </div>
460
+
461
+ {/* Footer with User ID and Role */}
462
+ <div className="p-4 border-t border-primary mt-auto">
463
+ <div className="flex justify-center items-center gap-2 bg-surface-tertiary px-2 py-1 rounded-lg w-fit">
464
+ <span className="text-label-secondary text-[10px] leading-3 font-mono font-semibold whitespace-nowrap">
465
+ User: {userNumber ? String(userNumber).padStart(2, '0') : 'N/A'}{userRole ? ` - ${userRole}` : ''}
466
+ </span>
467
+ </div>
468
+ </div>
469
+ </div>
470
+ </>
471
+ );
472
+ };