@m5kdev/web-ui 0.1.3 → 0.1.5

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 (375) hide show
  1. package/dist/src/animations/card.motion.d.ts +2 -0
  2. package/dist/src/animations/card.motion.js +7 -0
  3. package/dist/src/components/AvatarUpload.d.ts +7 -0
  4. package/dist/src/components/AvatarUpload.js +67 -0
  5. package/dist/src/components/Button.d.ts +5 -0
  6. package/dist/src/components/Button.js +5 -0
  7. package/dist/src/components/Calendar.d.ts +35 -0
  8. package/dist/src/components/Calendar.js +10 -0
  9. package/dist/src/components/CardsSelect.d.ts +23 -0
  10. package/dist/src/components/CardsSelect.js +46 -0
  11. package/dist/src/components/CollapsibleSidebarMenuItem.d.ts +9 -0
  12. package/dist/src/components/CollapsibleSidebarMenuItem.js +11 -0
  13. package/dist/src/components/ColorPicker.d.ts +4 -0
  14. package/dist/src/components/ColorPicker.js +21 -0
  15. package/dist/src/components/CopyButton.d.ts +6 -0
  16. package/dist/src/components/CopyButton.js +24 -0
  17. package/dist/src/components/CropDialog.d.ts +10 -0
  18. package/dist/src/components/CropDialog.js +67 -0
  19. package/dist/src/components/DialogProvider.d.ts +15 -0
  20. package/dist/src/components/DialogProvider.js +50 -0
  21. package/dist/src/components/ErrorFallback.d.ts +4 -0
  22. package/dist/src/components/ErrorFallback.js +5 -0
  23. package/dist/src/components/FileDropzone.d.ts +6 -0
  24. package/dist/src/components/FileDropzone.js +63 -0
  25. package/dist/src/components/MultiSelectDropdown.d.ts +26 -0
  26. package/dist/src/components/MultiSelectDropdown.js +53 -0
  27. package/dist/src/components/Orb.d.ts +6 -0
  28. package/{src/components/Orb.tsx → dist/src/components/Orb.js} +107 -136
  29. package/dist/src/components/PageAlert.d.ts +18 -0
  30. package/dist/src/components/PageAlert.js +48 -0
  31. package/dist/src/components/SelectChips.d.ts +10 -0
  32. package/dist/src/components/SelectChips.js +11 -0
  33. package/dist/src/components/SidebarItem.d.ts +7 -0
  34. package/dist/src/components/SidebarItem.js +6 -0
  35. package/dist/src/components/Steps.d.ts +19 -0
  36. package/dist/src/components/Steps.js +34 -0
  37. package/dist/src/components/TablerIconPicker.d.ts +2 -0
  38. package/dist/src/components/TablerIconPicker.js +4238 -0
  39. package/dist/src/components/app-header.d.ts +6 -0
  40. package/dist/src/components/app-header.js +8 -0
  41. package/dist/src/components/blur-card.d.ts +13 -0
  42. package/dist/src/components/blur-card.js +34 -0
  43. package/dist/src/components/features-section-demo-1.d.ts +6 -0
  44. package/dist/src/components/features-section-demo-1.js +53 -0
  45. package/dist/src/components/features-section-demo-2.d.ts +1 -0
  46. package/dist/src/components/features-section-demo-2.js +51 -0
  47. package/dist/src/components/features-section-demo-3.d.ts +8 -0
  48. package/dist/src/components/features-section-demo-3.js +116 -0
  49. package/dist/src/components/mode-toggle.d.ts +1 -0
  50. package/dist/src/components/mode-toggle.js +9 -0
  51. package/dist/src/components/nav-main.d.ts +13 -0
  52. package/dist/src/components/nav-main.js +9 -0
  53. package/dist/src/components/pricing-cards.d.ts +1 -0
  54. package/dist/src/components/pricing-cards.js +27 -0
  55. package/dist/src/components/shared/ButtonCopy.d.ts +6 -0
  56. package/dist/src/components/shared/ButtonCopy.js +24 -0
  57. package/dist/src/components/team-switcher.d.ts +8 -0
  58. package/dist/src/components/team-switcher.js +10 -0
  59. package/dist/src/components/theme-provider.d.ts +13 -0
  60. package/dist/src/components/theme-provider.js +41 -0
  61. package/dist/src/components/typewriter.d.ts +18 -0
  62. package/dist/src/components/typewriter.js +38 -0
  63. package/dist/src/components/ui/alert-dialog.d.ts +14 -0
  64. package/dist/src/components/ui/alert-dialog.js +38 -0
  65. package/dist/src/components/ui/alert.d.ts +9 -0
  66. package/dist/src/components/ui/alert.js +24 -0
  67. package/dist/src/components/ui/avatar.d.ts +6 -0
  68. package/dist/src/components/ui/avatar.js +12 -0
  69. package/dist/src/components/ui/badge.d.ts +9 -0
  70. package/dist/src/components/ui/badge.js +20 -0
  71. package/dist/src/components/ui/bento-grid.d.ts +11 -0
  72. package/dist/src/components/ui/bento-grid.js +8 -0
  73. package/dist/src/components/ui/bento-grid2.d.ts +15 -0
  74. package/dist/src/components/ui/bento-grid2.js +13 -0
  75. package/dist/src/components/ui/breadcrumb.d.ts +19 -0
  76. package/dist/src/components/ui/breadcrumb.js +23 -0
  77. package/dist/src/components/ui/button.d.ts +11 -0
  78. package/dist/src/components/ui/button.js +33 -0
  79. package/dist/src/components/ui/card.d.ts +8 -0
  80. package/dist/src/components/ui/card.js +16 -0
  81. package/dist/src/components/ui/checkbox.d.ts +4 -0
  82. package/dist/src/components/ui/checkbox.js +8 -0
  83. package/dist/src/components/ui/collapsible.d.ts +5 -0
  84. package/{src/components/ui/collapsible.tsx → dist/src/components/ui/collapsible.js} +5 -9
  85. package/dist/src/components/ui/dialog.d.ts +13 -0
  86. package/dist/src/components/ui/dialog.js +35 -0
  87. package/dist/src/components/ui/dropdown-menu.d.ts +27 -0
  88. package/dist/src/components/ui/dropdown-menu.js +32 -0
  89. package/dist/src/components/ui/floating-navbar.d.ts +9 -0
  90. package/dist/src/components/ui/floating-navbar.js +38 -0
  91. package/dist/src/components/ui/form.d.ts +23 -0
  92. package/dist/src/components/ui/form.js +60 -0
  93. package/dist/src/components/ui/image.d.ts +6 -0
  94. package/dist/src/components/ui/image.js +15 -0
  95. package/dist/src/components/ui/input.d.ts +3 -0
  96. package/dist/src/components/ui/input.js +8 -0
  97. package/dist/src/components/ui/label.d.ts +5 -0
  98. package/dist/src/components/ui/label.js +9 -0
  99. package/dist/src/components/ui/pagination.d.ts +13 -0
  100. package/dist/src/components/ui/pagination.js +29 -0
  101. package/dist/src/components/ui/progress.d.ts +4 -0
  102. package/dist/src/components/ui/progress.js +7 -0
  103. package/dist/src/components/ui/resizable-navbar.d.ts +56 -0
  104. package/dist/src/components/ui/resizable-navbar.js +86 -0
  105. package/dist/src/components/ui/segment-control.d.ts +9 -0
  106. package/dist/src/components/ui/segment-control.js +42 -0
  107. package/dist/src/components/ui/select.d.ts +13 -0
  108. package/dist/src/components/ui/select.js +26 -0
  109. package/dist/src/components/ui/separator.d.ts +4 -0
  110. package/dist/src/components/ui/separator.js +7 -0
  111. package/dist/src/components/ui/sheet.d.ts +25 -0
  112. package/dist/src/components/ui/sheet.js +37 -0
  113. package/dist/src/components/ui/sidebar.d.ts +66 -0
  114. package/dist/src/components/ui/sidebar.js +222 -0
  115. package/dist/src/components/ui/skeleton.d.ts +2 -0
  116. package/dist/src/components/ui/skeleton.js +6 -0
  117. package/dist/src/components/ui/slider.d.ts +4 -0
  118. package/dist/src/components/ui/slider.js +7 -0
  119. package/dist/src/components/ui/sonner.d.ts +4 -0
  120. package/dist/src/components/ui/sonner.js +15 -0
  121. package/dist/src/components/ui/spinner.d.ts +14 -0
  122. package/dist/src/components/ui/spinner.js +30 -0
  123. package/dist/src/components/ui/switch.d.ts +4 -0
  124. package/dist/src/components/ui/switch.js +7 -0
  125. package/dist/src/components/ui/table.d.ts +10 -0
  126. package/dist/src/components/ui/table.js +27 -0
  127. package/dist/src/components/ui/tabs.d.ts +7 -0
  128. package/dist/src/components/ui/tabs.js +16 -0
  129. package/dist/src/components/ui/textarea.d.ts +3 -0
  130. package/dist/src/components/ui/textarea.js +6 -0
  131. package/dist/src/components/ui/timeline.d.ts +11 -0
  132. package/dist/src/components/ui/timeline.js +27 -0
  133. package/dist/src/components/ui/toast.d.ts +15 -0
  134. package/dist/src/components/ui/toast.js +33 -0
  135. package/dist/src/components/ui/tooltip.d.ts +7 -0
  136. package/dist/src/components/ui/tooltip.js +16 -0
  137. package/dist/src/components/ui/typewriter-effect.d.ts +16 -0
  138. package/dist/src/components/ui/typewriter-effect.js +76 -0
  139. package/dist/src/hooks/use-mobile.d.ts +1 -0
  140. package/dist/src/hooks/use-mobile.js +15 -0
  141. package/dist/src/hooks/useDialog.d.ts +4 -0
  142. package/dist/src/hooks/useDialog.js +22 -0
  143. package/dist/src/icons/GoogleIcon.d.ts +5 -0
  144. package/dist/src/icons/GoogleIcon.js +4 -0
  145. package/dist/src/icons/LinkedInIcon.d.ts +5 -0
  146. package/dist/src/icons/LinkedInIcon.js +4 -0
  147. package/dist/src/icons/MicrosoftIcon.d.ts +5 -0
  148. package/dist/src/icons/MicrosoftIcon.js +4 -0
  149. package/dist/src/lib/chatwoot.d.ts +11 -0
  150. package/dist/src/lib/chatwoot.js +28 -0
  151. package/dist/src/lib/utils.d.ts +2 -0
  152. package/dist/src/lib/utils.js +5 -0
  153. package/dist/src/modules/app/components/AppLoader.d.ts +2 -0
  154. package/dist/src/modules/app/components/AppLoader.js +5 -0
  155. package/dist/src/modules/app/components/AppShell.d.ts +7 -0
  156. package/dist/src/modules/app/components/AppShell.js +7 -0
  157. package/dist/src/modules/app/components/AppSidebar.d.ts +7 -0
  158. package/dist/src/modules/app/components/AppSidebar.js +5 -0
  159. package/dist/src/modules/app/components/AppSidebarContent.d.ts +16 -0
  160. package/dist/src/modules/app/components/AppSidebarContent.js +7 -0
  161. package/dist/src/modules/app/components/AppSidebarHeader.d.ts +8 -0
  162. package/dist/src/modules/app/components/AppSidebarHeader.js +10 -0
  163. package/dist/src/modules/app/components/AppSidebarInvites.d.ts +3 -0
  164. package/dist/src/modules/app/components/AppSidebarInvites.js +12 -0
  165. package/dist/src/modules/app/components/AppSidebarUser.d.ts +11 -0
  166. package/dist/src/modules/app/components/AppSidebarUser.js +16 -0
  167. package/dist/src/modules/auth/components/AdminUserManagement.d.ts +6 -0
  168. package/dist/src/modules/auth/components/AdminUserManagement.js +422 -0
  169. package/dist/src/modules/auth/components/AdminWaitlist.d.ts +6 -0
  170. package/dist/src/modules/auth/components/AdminWaitlist.js +118 -0
  171. package/dist/src/modules/auth/components/AuthLayout.d.ts +4 -0
  172. package/dist/src/modules/auth/components/AuthLayout.js +5 -0
  173. package/dist/src/modules/auth/components/AuthProviders.d.ts +6 -0
  174. package/dist/src/modules/auth/components/AuthProviders.js +45 -0
  175. package/dist/src/modules/auth/components/AuthRouter.d.ts +9 -0
  176. package/dist/src/modules/auth/components/AuthRouter.js +12 -0
  177. package/dist/src/modules/auth/components/ClaimAccountRoute.d.ts +4 -0
  178. package/dist/src/modules/auth/components/ClaimAccountRoute.js +143 -0
  179. package/dist/src/modules/auth/components/ErrorAuthRoute.d.ts +1 -0
  180. package/dist/src/modules/auth/components/ErrorAuthRoute.js +93 -0
  181. package/dist/src/modules/auth/components/ForgotPasswordForm.d.ts +1 -0
  182. package/dist/src/modules/auth/components/ForgotPasswordForm.js +27 -0
  183. package/dist/src/modules/auth/components/ForgotPasswordRoute.d.ts +1 -0
  184. package/dist/src/modules/auth/components/ForgotPasswordRoute.js +9 -0
  185. package/dist/src/modules/auth/components/InviteFriends.d.ts +5 -0
  186. package/dist/src/modules/auth/components/InviteFriends.js +74 -0
  187. package/dist/src/modules/auth/components/LastUsedBadge.d.ts +5 -0
  188. package/dist/src/modules/auth/components/LastUsedBadge.js +9 -0
  189. package/dist/src/modules/auth/components/LoginForm.d.ts +3 -0
  190. package/dist/src/modules/auth/components/LoginForm.js +44 -0
  191. package/dist/src/modules/auth/components/LoginRoute.d.ts +3 -0
  192. package/dist/src/modules/auth/components/LoginRoute.js +11 -0
  193. package/dist/src/modules/auth/components/LogoutRoute.d.ts +1 -0
  194. package/dist/src/modules/auth/components/LogoutRoute.js +15 -0
  195. package/dist/src/modules/auth/components/OrganizationAcceptInvitationRoute.d.ts +9 -0
  196. package/dist/src/modules/auth/components/OrganizationAcceptInvitationRoute.js +102 -0
  197. package/dist/src/modules/auth/components/OrganizationMembersRoute.d.ts +51 -0
  198. package/dist/src/modules/auth/components/OrganizationMembersRoute.js +359 -0
  199. package/dist/src/modules/auth/components/OrganizationSettingsRoute.d.ts +20 -0
  200. package/dist/src/modules/auth/components/OrganizationSettingsRoute.js +153 -0
  201. package/dist/src/modules/auth/components/OrganizationSwitcher.d.ts +7 -0
  202. package/dist/src/modules/auth/components/OrganizationSwitcher.js +74 -0
  203. package/dist/src/modules/auth/components/ProfileRoute.d.ts +1 -0
  204. package/dist/src/modules/auth/components/ProfileRoute.js +42 -0
  205. package/dist/src/modules/auth/components/RangeNuqsDatePicker.d.ts +31 -0
  206. package/dist/src/modules/auth/components/RangeNuqsDatePicker.js +236 -0
  207. package/dist/src/modules/auth/components/ResetPasswordForm.d.ts +1 -0
  208. package/dist/src/modules/auth/components/ResetPasswordForm.js +39 -0
  209. package/dist/src/modules/auth/components/ResetPasswordRoute.d.ts +1 -0
  210. package/dist/src/modules/auth/components/ResetPasswordRoute.js +9 -0
  211. package/dist/src/modules/auth/components/SignupFormRoute.d.ts +5 -0
  212. package/dist/src/modules/auth/components/SignupFormRoute.js +106 -0
  213. package/dist/src/modules/auth/components/SignupRoute.d.ts +7 -0
  214. package/dist/src/modules/auth/components/SignupRoute.js +16 -0
  215. package/dist/src/modules/auth/components/UserPreferences.d.ts +30 -0
  216. package/dist/src/modules/auth/components/UserPreferences.js +60 -0
  217. package/dist/src/modules/auth/components/WaitlistCard.d.ts +6 -0
  218. package/dist/src/modules/auth/components/WaitlistCard.js +32 -0
  219. package/dist/src/modules/auth/components/WaitlistCodeValidation.d.ts +7 -0
  220. package/dist/src/modules/auth/components/WaitlistCodeValidation.js +43 -0
  221. package/dist/src/modules/billing/components/BillingBetaPage.d.ts +8 -0
  222. package/dist/src/modules/billing/components/BillingBetaPage.js +11 -0
  223. package/dist/src/modules/billing/components/BillingInvoicePage.d.ts +7 -0
  224. package/dist/src/modules/billing/components/BillingInvoicePage.js +32 -0
  225. package/dist/src/modules/billing/components/BillingPlanSelect.d.ts +6 -0
  226. package/dist/src/modules/billing/components/BillingPlanSelect.js +8 -0
  227. package/dist/src/modules/billing/components/BillingRouter.d.ts +9 -0
  228. package/dist/src/modules/billing/components/BillingRouter.js +8 -0
  229. package/dist/src/modules/billing/components/BillingSinglePlanSelect.d.ts +8 -0
  230. package/dist/src/modules/billing/components/BillingSinglePlanSelect.js +46 -0
  231. package/dist/src/modules/table/components/ColumnOrderAndVisibility.d.ts +10 -0
  232. package/dist/src/modules/table/components/ColumnOrderAndVisibility.js +42 -0
  233. package/dist/src/modules/table/components/NuqsTable.d.ts +23 -0
  234. package/dist/src/modules/table/components/NuqsTable.js +198 -0
  235. package/dist/src/modules/table/components/TableFiltering.d.ts +23 -0
  236. package/dist/src/modules/table/components/TableFiltering.js +236 -0
  237. package/dist/src/modules/table/components/TablePagination.d.ts +9 -0
  238. package/dist/src/modules/table/components/TablePagination.js +21 -0
  239. package/{src/modules/table/components/table.types.ts → dist/src/modules/table/components/table.types.d.ts} +12 -11
  240. package/dist/src/modules/table/components/table.types.js +1 -0
  241. package/dist/src/modules/table/filterTransformers.d.ts +53 -0
  242. package/dist/src/modules/table/filterTransformers.js +276 -0
  243. package/{src/types.ts → dist/src/types.d.ts} +3 -4
  244. package/dist/src/types.js +1 -0
  245. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  246. package/package.json +8 -5
  247. package/.cursor/rules/web-ui.mdc +0 -126
  248. package/.turbo/turbo-build.log +0 -5
  249. package/.turbo/turbo-check-types.log +0 -5
  250. package/.turbo/turbo-lint$colon$fix.log +0 -381
  251. package/.turbo/turbo-lint.log +0 -361
  252. package/CHANGELOG.md +0 -19
  253. package/components.json +0 -21
  254. package/src/animations/card.motion.ts +0 -9
  255. package/src/components/AvatarUpload.tsx +0 -133
  256. package/src/components/Button.tsx +0 -14
  257. package/src/components/Calendar.css +0 -684
  258. package/src/components/Calendar.tsx +0 -32
  259. package/src/components/CardsSelect.tsx +0 -155
  260. package/src/components/CollapsibleSidebarMenuItem.tsx +0 -57
  261. package/src/components/ColorPicker.tsx +0 -56
  262. package/src/components/CopyButton.tsx +0 -45
  263. package/src/components/CropDialog.tsx +0 -154
  264. package/src/components/DialogProvider.tsx +0 -105
  265. package/src/components/ErrorFallback.tsx +0 -17
  266. package/src/components/FileDropzone.tsx +0 -120
  267. package/src/components/MultiSelectDropdown.tsx +0 -233
  268. package/src/components/PageAlert.tsx +0 -121
  269. package/src/components/SelectChips.tsx +0 -40
  270. package/src/components/SidebarItem.tsx +0 -26
  271. package/src/components/Steps.tsx +0 -340
  272. package/src/components/TablerIconPicker.tsx +0 -4260
  273. package/src/components/app-header.tsx +0 -40
  274. package/src/components/blur-card.tsx +0 -132
  275. package/src/components/features-section-demo-1.tsx +0 -127
  276. package/src/components/features-section-demo-2.tsx +0 -102
  277. package/src/components/features-section-demo-3.tsx +0 -272
  278. package/src/components/mode-toggle.tsx +0 -31
  279. package/src/components/nav-main.tsx +0 -69
  280. package/src/components/pricing-cards.tsx +0 -133
  281. package/src/components/shared/ButtonCopy.tsx +0 -50
  282. package/src/components/team-switcher.tsx +0 -83
  283. package/src/components/theme-provider.tsx +0 -74
  284. package/src/components/typewriter.tsx +0 -90
  285. package/src/components/ui/alert-dialog.tsx +0 -133
  286. package/src/components/ui/alert.tsx +0 -60
  287. package/src/components/ui/avatar.tsx +0 -47
  288. package/src/components/ui/badge.tsx +0 -33
  289. package/src/components/ui/bento-grid.tsx +0 -54
  290. package/src/components/ui/bento-grid2.tsx +0 -66
  291. package/src/components/ui/breadcrumb.tsx +0 -101
  292. package/src/components/ui/button.tsx +0 -50
  293. package/src/components/ui/card.tsx +0 -55
  294. package/src/components/ui/checkbox.tsx +0 -26
  295. package/src/components/ui/dialog.tsx +0 -119
  296. package/src/components/ui/dropdown-menu.tsx +0 -186
  297. package/src/components/ui/floating-navbar.tsx +0 -78
  298. package/src/components/ui/form.tsx +0 -167
  299. package/src/components/ui/image.tsx +0 -55
  300. package/src/components/ui/input.tsx +0 -22
  301. package/src/components/ui/label.tsx +0 -19
  302. package/src/components/ui/pagination.tsx +0 -105
  303. package/src/components/ui/progress.tsx +0 -23
  304. package/src/components/ui/resizable-navbar.tsx +0 -260
  305. package/src/components/ui/segment-control.tsx +0 -143
  306. package/src/components/ui/select.tsx +0 -153
  307. package/src/components/ui/separator.tsx +0 -24
  308. package/src/components/ui/sheet.tsx +0 -121
  309. package/src/components/ui/sidebar.tsx +0 -736
  310. package/src/components/ui/skeleton.tsx +0 -7
  311. package/src/components/ui/slider.tsx +0 -23
  312. package/src/components/ui/sonner.tsx +0 -27
  313. package/src/components/ui/spinner.tsx +0 -45
  314. package/src/components/ui/switch.tsx +0 -27
  315. package/src/components/ui/table.tsx +0 -90
  316. package/src/components/ui/tabs.tsx +0 -52
  317. package/src/components/ui/textarea.tsx +0 -18
  318. package/src/components/ui/timeline.tsx +0 -95
  319. package/src/components/ui/toast.tsx +0 -126
  320. package/src/components/ui/tooltip.tsx +0 -55
  321. package/src/components/ui/typewriter-effect.tsx +0 -181
  322. package/src/hooks/use-mobile.ts +0 -19
  323. package/src/hooks/useDialog.ts +0 -25
  324. package/src/icons/GoogleIcon.tsx +0 -32
  325. package/src/icons/LinkedInIcon.tsx +0 -30
  326. package/src/icons/MicrosoftIcon.tsx +0 -21
  327. package/src/lib/chatwoot.ts +0 -51
  328. package/src/lib/utils.ts +0 -6
  329. package/src/modules/app/components/AppLoader.tsx +0 -9
  330. package/src/modules/app/components/AppShell.tsx +0 -21
  331. package/src/modules/app/components/AppSidebar.tsx +0 -26
  332. package/src/modules/app/components/AppSidebarContent.tsx +0 -73
  333. package/src/modules/app/components/AppSidebarHeader.tsx +0 -57
  334. package/src/modules/app/components/AppSidebarInvites.tsx +0 -32
  335. package/src/modules/app/components/AppSidebarUser.tsx +0 -128
  336. package/src/modules/auth/components/AdminUserManagement.tsx +0 -1136
  337. package/src/modules/auth/components/AdminWaitlist.tsx +0 -358
  338. package/src/modules/auth/components/AuthLayout.tsx +0 -13
  339. package/src/modules/auth/components/AuthProviders.tsx +0 -105
  340. package/src/modules/auth/components/AuthRouter.tsx +0 -29
  341. package/src/modules/auth/components/ClaimAccountRoute.tsx +0 -242
  342. package/src/modules/auth/components/ErrorAuthRoute.tsx +0 -121
  343. package/src/modules/auth/components/ForgotPasswordForm.tsx +0 -58
  344. package/src/modules/auth/components/ForgotPasswordRoute.tsx +0 -27
  345. package/src/modules/auth/components/InviteFriends.tsx +0 -273
  346. package/src/modules/auth/components/LastUsedBadge.tsx +0 -22
  347. package/src/modules/auth/components/LoginForm.tsx +0 -104
  348. package/src/modules/auth/components/LoginRoute.tsx +0 -31
  349. package/src/modules/auth/components/LogoutRoute.tsx +0 -21
  350. package/src/modules/auth/components/OrganizationAcceptInvitationRoute.tsx +0 -161
  351. package/src/modules/auth/components/OrganizationMembersRoute.tsx +0 -730
  352. package/src/modules/auth/components/OrganizationSettingsRoute.tsx +0 -280
  353. package/src/modules/auth/components/OrganizationSwitcher.tsx +0 -148
  354. package/src/modules/auth/components/ProfileRoute.tsx +0 -104
  355. package/src/modules/auth/components/RangeNuqsDatePicker.tsx +0 -365
  356. package/src/modules/auth/components/ResetPasswordForm.tsx +0 -103
  357. package/src/modules/auth/components/ResetPasswordRoute.tsx +0 -27
  358. package/src/modules/auth/components/SignupFormRoute.tsx +0 -189
  359. package/src/modules/auth/components/SignupRoute.tsx +0 -53
  360. package/src/modules/auth/components/UserPreferences.tsx +0 -144
  361. package/src/modules/auth/components/WaitlistCard.tsx +0 -78
  362. package/src/modules/auth/components/WaitlistCodeValidation.tsx +0 -79
  363. package/src/modules/billing/components/BillingBetaPage.tsx +0 -124
  364. package/src/modules/billing/components/BillingInvoicePage.tsx +0 -180
  365. package/src/modules/billing/components/BillingPlanSelect.tsx +0 -14
  366. package/src/modules/billing/components/BillingRouter.tsx +0 -20
  367. package/src/modules/billing/components/BillingSinglePlanSelect.tsx +0 -172
  368. package/src/modules/table/components/ColumnOrderAndVisibility.tsx +0 -127
  369. package/src/modules/table/components/NuqsTable.tsx +0 -396
  370. package/src/modules/table/components/TableFiltering.tsx +0 -520
  371. package/src/modules/table/components/TablePagination.tsx +0 -59
  372. package/src/modules/table/filterTransformers.ts +0 -323
  373. package/src/vite-env.d.ts +0 -1
  374. package/translations/en/web-ui.json +0 -192
  375. package/tsconfig.json +0 -30
@@ -0,0 +1,51 @@
1
+ declare const ORGANIZATION_ROLES: readonly ["member", "admin", "owner"];
2
+ export type OrganizationRole = (typeof ORGANIZATION_ROLES)[number];
3
+ export type OrganizationMembersRouteLabels = {
4
+ loadError: string;
5
+ membersTitle: string;
6
+ membersNoActive: string;
7
+ membersManageOnly: string;
8
+ membersDescription: (organizationName: string) => string;
9
+ defaultOrganizationName: string;
10
+ loadMembersError: string;
11
+ loadInvitationsError: string;
12
+ roleUpdateSuccess: string;
13
+ roleUpdateError: string;
14
+ removeMemberSuccess: string;
15
+ removeMemberError: string;
16
+ emailRequired: string;
17
+ inviteSuccess: string;
18
+ inviteError: string;
19
+ cancelInvitationSuccess: string;
20
+ cancelInvitationError: string;
21
+ inviteLinkCopied: string;
22
+ copyInviteLinkError: string;
23
+ unknownName: string;
24
+ invitedUser: string;
25
+ emailLabel: string;
26
+ emailPlaceholder: string;
27
+ roleLabel: string;
28
+ inviteButton: string;
29
+ tableTitle: string;
30
+ columnName: string;
31
+ columnEmail: string;
32
+ columnRole: string;
33
+ columnStatus: string;
34
+ columnActions: string;
35
+ tableEmpty: string;
36
+ roleFor: (name: string) => string;
37
+ statusActive: string;
38
+ statusInvited: string;
39
+ removeMember: string;
40
+ copyInviteLink: string;
41
+ cancelInvitation: string;
42
+ roleUnknown: string;
43
+ };
44
+ export type OrganizationMembersRouteProps = {
45
+ managerRoles?: string[];
46
+ assignableRoles?: OrganizationRole[];
47
+ invitationAcceptPath?: string;
48
+ onInvalidateScopedQueries?: () => void | Promise<void>;
49
+ };
50
+ export declare function OrganizationMembersRoute({ managerRoles, assignableRoles, invitationAcceptPath, onInvalidateScopedQueries, }: OrganizationMembersRouteProps): import("react/jsx-runtime").JSX.Element;
51
+ export {};
@@ -0,0 +1,359 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Card, CardBody, CardHeader, Chip, Input, Select, SelectItem, Spinner, Table, TableBody, TableCell, TableColumn, TableHeader, TableRow, } from "@heroui/react";
3
+ import { authClient } from "@m5kdev/frontend/modules/auth/auth.lib";
4
+ import { useSession } from "@m5kdev/frontend/modules/auth/hooks/useSession";
5
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
6
+ import { Copy, Trash2, UserPlus, Users } from "lucide-react";
7
+ import { useCallback, useEffect, useMemo, useRef, useState } from "react";
8
+ import { useTranslation } from "react-i18next";
9
+ import { toast } from "sonner";
10
+ const ORGANIZATION_ROLES = ["member", "admin", "owner"];
11
+ function isOrganizationRole(role) {
12
+ return ORGANIZATION_ROLES.includes(role);
13
+ }
14
+ function OrganizationStateCard({ title, message }) {
15
+ return (_jsx("div", { className: "p-6", children: _jsxs(Card, { children: [_jsx(CardHeader, { className: "text-lg font-semibold", children: title }), _jsx(CardBody, { children: message })] }) }));
16
+ }
17
+ function useOrganizationAccess({ managerRoles, onInvalidateScopedQueries, }) {
18
+ const { data: session, registerSession } = useSession();
19
+ const queryClient = useQueryClient();
20
+ const activeOrganizationId = session?.session.activeOrganizationId ?? "";
21
+ const activeOrganizationRole = session?.session?.activeOrganizationRole ??
22
+ "";
23
+ const managerRoleSet = useMemo(() => new Set(managerRoles ?? ["admin", "owner"]), [managerRoles]);
24
+ const canManageOrganization = managerRoleSet.has(activeOrganizationRole);
25
+ const refreshOrganizationQueries = useCallback(async () => {
26
+ await Promise.allSettled([
27
+ queryClient.invalidateQueries({ queryKey: ["auth-organization-list"] }),
28
+ queryClient.invalidateQueries({
29
+ queryKey: ["auth-organization-details", activeOrganizationId],
30
+ }),
31
+ queryClient.invalidateQueries({
32
+ queryKey: ["auth-organization-members", activeOrganizationId],
33
+ }),
34
+ queryClient.invalidateQueries({
35
+ queryKey: ["auth-organization-invitations", activeOrganizationId],
36
+ }),
37
+ ]);
38
+ registerSession(() => {
39
+ void onInvalidateScopedQueries?.();
40
+ });
41
+ }, [activeOrganizationId, onInvalidateScopedQueries, queryClient, registerSession]);
42
+ return {
43
+ activeOrganizationId,
44
+ activeOrganizationRole,
45
+ canManageOrganization,
46
+ refreshOrganizationQueries,
47
+ };
48
+ }
49
+ function useOrganizationConfig({ assignableRoles, }) {
50
+ const { t } = useTranslation();
51
+ const translatedLabels = useMemo(() => ({
52
+ loadError: t("web-ui:organization.members.loadError"),
53
+ membersTitle: t("web-ui:organization.members.title"),
54
+ membersNoActive: t("web-ui:organization.members.noActive"),
55
+ membersManageOnly: t("web-ui:organization.members.manageOnly"),
56
+ membersDescription: (organizationName) => t("web-ui:organization.members.description", { name: organizationName }),
57
+ defaultOrganizationName: t("web-ui:organization.members.defaultName"),
58
+ loadMembersError: t("web-ui:organization.members.loadMembersError"),
59
+ loadInvitationsError: t("web-ui:organization.members.loadInvitationsError"),
60
+ roleUpdateSuccess: t("web-ui:organization.members.roleUpdateSuccess"),
61
+ roleUpdateError: t("web-ui:organization.members.roleUpdateError"),
62
+ removeMemberSuccess: t("web-ui:organization.members.removeMemberSuccess"),
63
+ removeMemberError: t("web-ui:organization.members.removeMemberError"),
64
+ emailRequired: t("web-ui:organization.members.emailRequired"),
65
+ inviteSuccess: t("web-ui:organization.members.inviteSuccess"),
66
+ inviteError: t("web-ui:organization.members.inviteError"),
67
+ cancelInvitationSuccess: t("web-ui:organization.members.cancelInvitationSuccess"),
68
+ cancelInvitationError: t("web-ui:organization.members.cancelInvitationError"),
69
+ inviteLinkCopied: t("web-ui:organization.members.inviteLinkCopied"),
70
+ copyInviteLinkError: t("web-ui:organization.members.copyInviteLinkError"),
71
+ unknownName: t("web-ui:organization.members.unknownName"),
72
+ invitedUser: t("web-ui:organization.members.invitedUser"),
73
+ emailLabel: t("web-ui:organization.members.emailLabel"),
74
+ emailPlaceholder: t("web-ui:organization.members.emailPlaceholder"),
75
+ roleLabel: t("web-ui:organization.members.roleLabel"),
76
+ inviteButton: t("web-ui:organization.members.inviteButton"),
77
+ tableTitle: t("web-ui:organization.members.tableTitle"),
78
+ columnName: t("web-ui:organization.members.columnName"),
79
+ columnEmail: t("web-ui:organization.members.columnEmail"),
80
+ columnRole: t("web-ui:organization.members.columnRole"),
81
+ columnStatus: t("web-ui:organization.members.columnStatus"),
82
+ columnActions: t("web-ui:organization.members.columnActions"),
83
+ tableEmpty: t("web-ui:organization.members.tableEmpty"),
84
+ roleFor: (name) => t("web-ui:organization.members.roleFor", { name }),
85
+ statusActive: t("web-ui:organization.members.statusActive"),
86
+ statusInvited: t("web-ui:organization.members.statusInvited"),
87
+ removeMember: t("web-ui:organization.members.removeMember"),
88
+ copyInviteLink: t("web-ui:organization.members.copyInviteLink"),
89
+ cancelInvitation: t("web-ui:organization.members.cancelInvitation"),
90
+ roleUnknown: t("web-ui:organization.members.roleUnknown"),
91
+ }), [t]);
92
+ const translatedRoleLabels = useMemo(() => ({
93
+ member: t("web-ui:organization.roles.member"),
94
+ admin: t("web-ui:organization.roles.admin"),
95
+ owner: t("web-ui:organization.roles.owner"),
96
+ }), [t]);
97
+ const resolvedAssignableRoles = useMemo(() => assignableRoles && assignableRoles.length > 0 ? assignableRoles : [...ORGANIZATION_ROLES], [assignableRoles]);
98
+ return {
99
+ resolvedLabels: translatedLabels,
100
+ resolvedRoleLabels: translatedRoleLabels,
101
+ resolvedAssignableRoles,
102
+ };
103
+ }
104
+ export function OrganizationMembersRoute({ managerRoles, assignableRoles, invitationAcceptPath, onInvalidateScopedQueries, }) {
105
+ const { resolvedLabels, resolvedRoleLabels, resolvedAssignableRoles } = useOrganizationConfig({
106
+ assignableRoles,
107
+ });
108
+ const { activeOrganizationId, activeOrganizationRole, canManageOrganization, refreshOrganizationQueries, } = useOrganizationAccess({ managerRoles, onInvalidateScopedQueries });
109
+ const [inviteEmail, setInviteEmail] = useState("");
110
+ const [inviteRole, setInviteRole] = useState(resolvedAssignableRoles[0] ?? "member");
111
+ const isMountedRef = useRef(true);
112
+ useEffect(() => {
113
+ return () => {
114
+ isMountedRef.current = false;
115
+ };
116
+ }, []);
117
+ const refreshOrganizationQueriesStable = useCallback(() => refreshOrganizationQueries(), [refreshOrganizationQueries]);
118
+ const updateRoleMutation = useMutation({
119
+ mutationFn: async ({ memberId, role, organizationId, }) => {
120
+ const { error } = await authClient.organization.updateMemberRole({
121
+ memberId,
122
+ role,
123
+ organizationId,
124
+ });
125
+ if (error)
126
+ throw new Error(error.message ?? resolvedLabels.roleUpdateError);
127
+ },
128
+ onSuccess: async () => {
129
+ await refreshOrganizationQueriesStable();
130
+ toast.success(resolvedLabels.roleUpdateSuccess);
131
+ },
132
+ onError: (error) => {
133
+ toast.error(error instanceof Error ? error.message : resolvedLabels.roleUpdateError);
134
+ },
135
+ });
136
+ const removeMemberMutation = useMutation({
137
+ mutationFn: async ({ memberId, organizationId, }) => {
138
+ const { error } = await authClient.organization.removeMember({
139
+ memberIdOrEmail: memberId,
140
+ organizationId,
141
+ });
142
+ if (error)
143
+ throw new Error(error.message ?? resolvedLabels.removeMemberError);
144
+ },
145
+ onSuccess: async () => {
146
+ await refreshOrganizationQueriesStable();
147
+ toast.success(resolvedLabels.removeMemberSuccess);
148
+ },
149
+ onError: (error) => {
150
+ toast.error(error instanceof Error ? error.message : resolvedLabels.removeMemberError);
151
+ },
152
+ });
153
+ const createInvitationMutation = useMutation({
154
+ mutationFn: async ({ email, role, organizationId, }) => {
155
+ const { error } = await authClient.organization.inviteMember({
156
+ organizationId,
157
+ email: email.trim(),
158
+ role,
159
+ });
160
+ if (error)
161
+ throw new Error(error.message ?? resolvedLabels.inviteError);
162
+ },
163
+ onSuccess: async () => {
164
+ await refreshOrganizationQueriesStable();
165
+ toast.success(resolvedLabels.inviteSuccess);
166
+ if (isMountedRef.current) {
167
+ setInviteEmail("");
168
+ setInviteRole(resolvedAssignableRoles[0] ?? "member");
169
+ }
170
+ },
171
+ onError: (error) => {
172
+ toast.error(error instanceof Error ? error.message : resolvedLabels.inviteError);
173
+ },
174
+ });
175
+ const cancelInvitationMutation = useMutation({
176
+ mutationFn: async ({ invitationId }) => {
177
+ const { error } = await authClient.organization.cancelInvitation({ invitationId });
178
+ if (error)
179
+ throw new Error(error.message ?? resolvedLabels.cancelInvitationError);
180
+ },
181
+ onSuccess: async () => {
182
+ await refreshOrganizationQueriesStable();
183
+ toast.success(resolvedLabels.cancelInvitationSuccess);
184
+ },
185
+ onError: (error) => {
186
+ toast.error(error instanceof Error ? error.message : resolvedLabels.cancelInvitationError);
187
+ },
188
+ });
189
+ const updatingMemberId = updateRoleMutation.isPending && updateRoleMutation.variables
190
+ ? updateRoleMutation.variables.memberId
191
+ : null;
192
+ const removingMemberId = removeMemberMutation.isPending && removeMemberMutation.variables
193
+ ? removeMemberMutation.variables.memberId
194
+ : null;
195
+ const cancelingInvitationId = cancelInvitationMutation.isPending && cancelInvitationMutation.variables
196
+ ? cancelInvitationMutation.variables.invitationId
197
+ : null;
198
+ useEffect(() => {
199
+ if (!resolvedAssignableRoles.includes(inviteRole)) {
200
+ setInviteRole(resolvedAssignableRoles[0] ?? "member");
201
+ }
202
+ }, [inviteRole, resolvedAssignableRoles]);
203
+ const organizationQuery = useQuery({
204
+ queryKey: ["auth-organization-details", activeOrganizationId],
205
+ enabled: Boolean(activeOrganizationId && canManageOrganization),
206
+ queryFn: async () => {
207
+ const { data, error } = await authClient.organization.getFullOrganization({
208
+ query: {
209
+ organizationId: activeOrganizationId,
210
+ membersLimit: 200,
211
+ },
212
+ });
213
+ if (error) {
214
+ throw new Error(error.message ?? resolvedLabels.loadError);
215
+ }
216
+ return data;
217
+ },
218
+ });
219
+ const membersQuery = useQuery({
220
+ queryKey: ["auth-organization-members", activeOrganizationId],
221
+ enabled: Boolean(activeOrganizationId && canManageOrganization),
222
+ queryFn: async () => {
223
+ const { data, error } = await authClient.organization.listMembers({
224
+ query: {
225
+ organizationId: activeOrganizationId,
226
+ limit: 200,
227
+ offset: 0,
228
+ },
229
+ });
230
+ if (error) {
231
+ throw new Error(error.message ?? resolvedLabels.loadMembersError);
232
+ }
233
+ return (data?.members ??
234
+ []);
235
+ },
236
+ });
237
+ const invitationsQuery = useQuery({
238
+ queryKey: ["auth-organization-invitations", activeOrganizationId],
239
+ enabled: Boolean(activeOrganizationId && canManageOrganization),
240
+ queryFn: async () => {
241
+ const { data, error } = await authClient.organization.listInvitations({
242
+ query: {
243
+ organizationId: activeOrganizationId,
244
+ },
245
+ });
246
+ if (error) {
247
+ throw new Error(error.message ?? resolvedLabels.loadInvitationsError);
248
+ }
249
+ return (data ?? []);
250
+ },
251
+ });
252
+ const members = membersQuery.data ?? [];
253
+ const invitations = invitationsQuery.data ?? [];
254
+ const rows = useMemo(() => {
255
+ const memberRows = members.map((member) => ({
256
+ kind: "member",
257
+ id: `member-${member.id}`,
258
+ displayName: member.user?.name || resolvedLabels.unknownName,
259
+ email: member.user?.email || "-",
260
+ role: member.role,
261
+ status: "active",
262
+ memberId: member.id,
263
+ }));
264
+ const invitationRows = invitations.map((invitation) => ({
265
+ kind: "invitation",
266
+ id: `invitation-${invitation.id}`,
267
+ displayName: resolvedLabels.invitedUser,
268
+ email: invitation.email,
269
+ role: invitation.role,
270
+ status: "invited",
271
+ invitationId: invitation.id,
272
+ }));
273
+ return [...memberRows, ...invitationRows].sort((left, right) => {
274
+ if (left.status === right.status) {
275
+ return left.email.localeCompare(right.email);
276
+ }
277
+ return left.status === "active" ? -1 : 1;
278
+ });
279
+ }, [invitations, members, resolvedLabels.invitedUser, resolvedLabels.unknownName]);
280
+ const onUpdateMemberRole = useCallback((memberId, role) => {
281
+ if (!canManageOrganization || !activeOrganizationId)
282
+ return;
283
+ updateRoleMutation.mutate({ memberId, role, organizationId: activeOrganizationId });
284
+ }, [canManageOrganization, activeOrganizationId, updateRoleMutation]);
285
+ const onRemoveMember = useCallback((memberId) => {
286
+ if (!canManageOrganization || !activeOrganizationId)
287
+ return;
288
+ removeMemberMutation.mutate({ memberId, organizationId: activeOrganizationId });
289
+ }, [canManageOrganization, activeOrganizationId, removeMemberMutation]);
290
+ const onCreateInvitation = useCallback(() => {
291
+ if (!canManageOrganization || !activeOrganizationId)
292
+ return;
293
+ if (!inviteEmail.trim()) {
294
+ toast.error(resolvedLabels.emailRequired);
295
+ return;
296
+ }
297
+ createInvitationMutation.mutate({
298
+ email: inviteEmail,
299
+ role: inviteRole,
300
+ organizationId: activeOrganizationId,
301
+ });
302
+ }, [
303
+ canManageOrganization,
304
+ activeOrganizationId,
305
+ inviteEmail,
306
+ inviteRole,
307
+ resolvedLabels.emailRequired,
308
+ createInvitationMutation,
309
+ ]);
310
+ const onCancelInvitation = useCallback((invitationId) => {
311
+ if (!canManageOrganization)
312
+ return;
313
+ cancelInvitationMutation.mutate({ invitationId });
314
+ }, [canManageOrganization, cancelInvitationMutation]);
315
+ const invitationLinkBase = useMemo(() => {
316
+ const invitationPath = invitationAcceptPath ?? "/organization/accept-invitation";
317
+ if (/^https?:\/\//i.test(invitationPath)) {
318
+ return `${invitationPath}?id=`;
319
+ }
320
+ return typeof window === "undefined"
321
+ ? `${invitationPath}?id=`
322
+ : `${window.location.origin}${invitationPath}?id=`;
323
+ }, [invitationAcceptPath]);
324
+ const onCopyInvitationLink = async (invitationId) => {
325
+ try {
326
+ await navigator.clipboard.writeText(`${invitationLinkBase}${invitationId}`);
327
+ toast.success(resolvedLabels.inviteLinkCopied);
328
+ }
329
+ catch {
330
+ toast.error(resolvedLabels.copyInviteLinkError);
331
+ }
332
+ };
333
+ const getRoleLabel = (role) => resolvedRoleLabels[role] ?? resolvedLabels.roleUnknown;
334
+ if (!activeOrganizationId) {
335
+ return (_jsx(OrganizationStateCard, { title: resolvedLabels.membersTitle, message: resolvedLabels.membersNoActive }));
336
+ }
337
+ if (!canManageOrganization) {
338
+ return (_jsx(OrganizationStateCard, { title: resolvedLabels.membersTitle, message: resolvedLabels.membersManageOnly }));
339
+ }
340
+ if (organizationQuery.isLoading || membersQuery.isLoading || invitationsQuery.isLoading) {
341
+ return (_jsx("div", { className: "p-6 flex justify-center", children: _jsx(Spinner, {}) }));
342
+ }
343
+ return (_jsx("div", { className: "p-6 space-y-6", children: _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Users, { className: "h-4 w-4" }), _jsxs("div", { className: "flex flex-col", children: [_jsx("h2", { className: "text-lg font-semibold", children: resolvedLabels.membersTitle }), _jsx("p", { className: "text-sm text-default-500", children: resolvedLabels.membersDescription(organizationQuery.data?.name ?? resolvedLabels.defaultOrganizationName) })] })] }), _jsx(Chip, { variant: "flat", color: "primary", children: getRoleLabel(activeOrganizationRole || "member") })] }), _jsxs(CardBody, { className: "space-y-4", children: [_jsxs("div", { className: "grid gap-3 md:grid-cols-[1fr_160px_auto]", children: [_jsx(Input, { type: "email", label: resolvedLabels.emailLabel, value: inviteEmail, onValueChange: setInviteEmail, placeholder: resolvedLabels.emailPlaceholder }), _jsx(Select, { label: resolvedLabels.roleLabel, selectedKeys: [inviteRole], disallowEmptySelection: true, onSelectionChange: (keys) => {
344
+ const role = Array.from(keys)[0];
345
+ if (role && isOrganizationRole(role) && resolvedAssignableRoles.includes(role)) {
346
+ setInviteRole(role);
347
+ }
348
+ }, children: resolvedAssignableRoles.map((role) => (_jsx(SelectItem, { children: getRoleLabel(role) }, role))) }), _jsx(Button, { color: "primary", startContent: _jsx(UserPlus, { className: "h-4 w-4" }), onPress: onCreateInvitation, isLoading: createInvitationMutation.isPending, children: resolvedLabels.inviteButton })] }), _jsxs(Table, { "aria-label": resolvedLabels.tableTitle, children: [_jsxs(TableHeader, { children: [_jsx(TableColumn, { children: resolvedLabels.columnName }), _jsx(TableColumn, { children: resolvedLabels.columnEmail }), _jsx(TableColumn, { children: resolvedLabels.columnRole }), _jsx(TableColumn, { children: resolvedLabels.columnStatus }), _jsx(TableColumn, { className: "text-right", children: resolvedLabels.columnActions })] }), _jsx(TableBody, { emptyContent: resolvedLabels.tableEmpty, children: rows.map((row) => (_jsxs(TableRow, { children: [_jsx(TableCell, { children: row.displayName }), _jsx(TableCell, { children: row.email }), _jsx(TableCell, { children: row.kind === "member" ? (_jsx(Select, { size: "sm", selectedKeys: [row.role], disallowEmptySelection: true, isDisabled: updatingMemberId === row.memberId, "aria-label": resolvedLabels.roleFor(row.displayName), onSelectionChange: (keys) => {
349
+ const role = Array.from(keys)[0];
350
+ if (role &&
351
+ role !== row.role &&
352
+ isOrganizationRole(role) &&
353
+ resolvedAssignableRoles.includes(role)) {
354
+ void onUpdateMemberRole(row.memberId, role);
355
+ }
356
+ }, children: resolvedAssignableRoles.map((role) => (_jsx(SelectItem, { children: getRoleLabel(role) }, role))) })) : (getRoleLabel(row.role)) }), _jsx(TableCell, { children: _jsx(Chip, { size: "sm", variant: "flat", color: row.status === "active" ? "success" : "warning", children: row.status === "active"
357
+ ? resolvedLabels.statusActive
358
+ : resolvedLabels.statusInvited }) }), _jsx(TableCell, { className: "text-right", children: row.kind === "member" ? (_jsx(Button, { size: "sm", color: "danger", variant: "light", isIconOnly: true, onPress: () => void onRemoveMember(row.memberId), isDisabled: removingMemberId === row.memberId, "aria-label": resolvedLabels.removeMember, children: _jsx(Trash2, { className: "h-4 w-4" }) })) : (_jsxs("div", { className: "flex justify-end gap-2", children: [_jsx(Button, { size: "sm", variant: "light", isIconOnly: true, onPress: () => void onCopyInvitationLink(row.invitationId), "aria-label": resolvedLabels.copyInviteLink, children: _jsx(Copy, { className: "h-4 w-4" }) }), _jsx(Button, { size: "sm", color: "danger", variant: "light", isIconOnly: true, onPress: () => void onCancelInvitation(row.invitationId), isDisabled: cancelingInvitationId === row.invitationId, "aria-label": resolvedLabels.cancelInvitation, children: _jsx(Trash2, { className: "h-4 w-4" }) })] })) })] }, row.id))) })] })] })] }) }));
359
+ }
@@ -0,0 +1,20 @@
1
+ export type OrganizationSettingsRouteLabels = {
2
+ settingsTitle: string;
3
+ settingsDescription: string;
4
+ settingsNoActive: string;
5
+ settingsManageOnly: string;
6
+ formName: string;
7
+ formSlug: string;
8
+ formMetadata: string;
9
+ formMetadataInvalidJson: string;
10
+ formMetadataInvalid: string;
11
+ saveButton: string;
12
+ updateSuccess: string;
13
+ updateError: string;
14
+ loadError: string;
15
+ };
16
+ export type OrganizationSettingsRouteProps = {
17
+ managerRoles?: string[];
18
+ onInvalidateScopedQueries?: () => void | Promise<void>;
19
+ };
20
+ export declare function OrganizationSettingsRoute({ managerRoles, onInvalidateScopedQueries, }: OrganizationSettingsRouteProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,153 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Card, CardBody, CardHeader, Chip, Input, Spinner, Textarea } from "@heroui/react";
3
+ import { authClient } from "@m5kdev/frontend/modules/auth/auth.lib";
4
+ import { useSession } from "@m5kdev/frontend/modules/auth/hooks/useSession";
5
+ import { useQuery, useQueryClient } from "@tanstack/react-query";
6
+ import { useCallback, useEffect, useMemo, useState } from "react";
7
+ import { useTranslation } from "react-i18next";
8
+ import { toast } from "sonner";
9
+ function OrganizationStateCard({ title, message }) {
10
+ return (_jsx("div", { className: "p-6", children: _jsxs(Card, { children: [_jsx(CardHeader, { className: "text-lg font-semibold", children: title }), _jsx(CardBody, { children: message })] }) }));
11
+ }
12
+ function useOrganizationAccess({ managerRoles, onInvalidateScopedQueries, }) {
13
+ const { data: session, registerSession } = useSession();
14
+ const queryClient = useQueryClient();
15
+ const activeOrganizationId = session?.session.activeOrganizationId ?? "";
16
+ const activeOrganizationRole = session?.session?.activeOrganizationRole ??
17
+ "";
18
+ const managerRoleSet = useMemo(() => new Set(managerRoles ?? ["admin", "owner"]), [managerRoles]);
19
+ const canManageOrganization = managerRoleSet.has(activeOrganizationRole);
20
+ const refreshOrganizationQueries = useCallback(async () => {
21
+ await Promise.allSettled([
22
+ queryClient.invalidateQueries({ queryKey: ["auth-organization-list"] }),
23
+ queryClient.invalidateQueries({
24
+ queryKey: ["auth-organization-details", activeOrganizationId],
25
+ }),
26
+ queryClient.invalidateQueries({
27
+ queryKey: ["auth-organization-members", activeOrganizationId],
28
+ }),
29
+ queryClient.invalidateQueries({
30
+ queryKey: ["auth-organization-invitations", activeOrganizationId],
31
+ }),
32
+ ]);
33
+ registerSession(() => {
34
+ void onInvalidateScopedQueries?.();
35
+ });
36
+ }, [activeOrganizationId, onInvalidateScopedQueries, queryClient, registerSession]);
37
+ return {
38
+ activeOrganizationId,
39
+ activeOrganizationRole,
40
+ canManageOrganization,
41
+ refreshOrganizationQueries,
42
+ };
43
+ }
44
+ function useOrganizationConfig() {
45
+ const { t } = useTranslation();
46
+ const translatedLabels = useMemo(() => ({
47
+ settingsTitle: t("web-ui:organization.settings.title"),
48
+ settingsDescription: t("web-ui:organization.settings.description"),
49
+ settingsNoActive: t("web-ui:organization.settings.noActive"),
50
+ settingsManageOnly: t("web-ui:organization.settings.manageOnly"),
51
+ formName: t("web-ui:organization.settings.form.name"),
52
+ formSlug: t("web-ui:organization.settings.form.slug"),
53
+ formMetadata: t("web-ui:organization.settings.form.metadata"),
54
+ formMetadataInvalidJson: t("web-ui:organization.settings.form.metadataInvalidJson"),
55
+ formMetadataInvalid: t("web-ui:organization.settings.form.metadataInvalid"),
56
+ saveButton: t("web-ui:organization.settings.button.save"),
57
+ updateSuccess: t("web-ui:organization.settings.updateSuccess"),
58
+ updateError: t("web-ui:organization.settings.updateError"),
59
+ loadError: t("web-ui:organization.settings.loadError"),
60
+ }), [t]);
61
+ const translatedRoleLabels = useMemo(() => ({
62
+ member: t("web-ui:organization.roles.member"),
63
+ admin: t("web-ui:organization.roles.admin"),
64
+ owner: t("web-ui:organization.roles.owner"),
65
+ }), [t]);
66
+ return { resolvedLabels: translatedLabels, resolvedRoleLabels: translatedRoleLabels };
67
+ }
68
+ export function OrganizationSettingsRoute({ managerRoles, onInvalidateScopedQueries, }) {
69
+ const { resolvedLabels, resolvedRoleLabels } = useOrganizationConfig();
70
+ const { activeOrganizationId, activeOrganizationRole, canManageOrganization, refreshOrganizationQueries, } = useOrganizationAccess({ managerRoles, onInvalidateScopedQueries });
71
+ const [organizationName, setOrganizationName] = useState("");
72
+ const [organizationSlug, setOrganizationSlug] = useState("");
73
+ const [organizationMetadata, setOrganizationMetadata] = useState("{}");
74
+ const [isSavingOrganization, setIsSavingOrganization] = useState(false);
75
+ const organizationQuery = useQuery({
76
+ queryKey: ["auth-organization-details", activeOrganizationId],
77
+ enabled: Boolean(activeOrganizationId && canManageOrganization),
78
+ queryFn: async () => {
79
+ const { data, error } = await authClient.organization.getFullOrganization({
80
+ query: {
81
+ organizationId: activeOrganizationId,
82
+ membersLimit: 200,
83
+ },
84
+ });
85
+ if (error) {
86
+ throw new Error(error.message ?? resolvedLabels.loadError);
87
+ }
88
+ return data;
89
+ },
90
+ });
91
+ useEffect(() => {
92
+ const organization = organizationQuery.data;
93
+ if (!organization) {
94
+ return;
95
+ }
96
+ setOrganizationName(organization.name ?? "");
97
+ setOrganizationSlug(organization.slug ?? "");
98
+ setOrganizationMetadata(JSON.stringify(organization.metadata ?? {}, null, 2));
99
+ }, [organizationQuery.data]);
100
+ const onUpdateOrganization = async () => {
101
+ if (!canManageOrganization || !activeOrganizationId) {
102
+ return;
103
+ }
104
+ try {
105
+ setIsSavingOrganization(true);
106
+ let parsedMetadata;
107
+ try {
108
+ parsedMetadata = organizationMetadata.trim()
109
+ ? JSON.parse(organizationMetadata)
110
+ : {};
111
+ }
112
+ catch (parseError) {
113
+ const message = parseError instanceof SyntaxError
114
+ ? resolvedLabels.formMetadataInvalidJson
115
+ : parseError instanceof Error
116
+ ? parseError.message
117
+ : resolvedLabels.formMetadataInvalid;
118
+ throw new Error(message);
119
+ }
120
+ const { error } = await authClient.organization.update({
121
+ organizationId: activeOrganizationId,
122
+ data: {
123
+ name: organizationName.trim(),
124
+ slug: organizationSlug.trim(),
125
+ metadata: parsedMetadata,
126
+ },
127
+ });
128
+ if (error) {
129
+ throw new Error(error.message ?? resolvedLabels.updateError);
130
+ }
131
+ await refreshOrganizationQueries();
132
+ toast.success(resolvedLabels.updateSuccess);
133
+ }
134
+ catch (error) {
135
+ toast.error(error instanceof Error ? error.message : resolvedLabels.updateError);
136
+ }
137
+ finally {
138
+ setIsSavingOrganization(false);
139
+ }
140
+ };
141
+ if (!activeOrganizationId) {
142
+ return (_jsx(OrganizationStateCard, { title: resolvedLabels.settingsTitle, message: resolvedLabels.settingsNoActive }));
143
+ }
144
+ if (!canManageOrganization) {
145
+ return (_jsx(OrganizationStateCard, { title: resolvedLabels.settingsTitle, message: resolvedLabels.settingsManageOnly }));
146
+ }
147
+ if (organizationQuery.isLoading) {
148
+ return (_jsx("div", { className: "p-6 flex justify-center", children: _jsx(Spinner, {}) }));
149
+ }
150
+ return (_jsx("div", { className: "p-6", children: _jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx("h2", { className: "text-xl font-semibold", children: resolvedLabels.settingsTitle }), _jsx("p", { className: "text-sm text-default-500", children: resolvedLabels.settingsDescription })] }), _jsx(Chip, { variant: "flat", color: "primary", children: resolvedRoleLabels[activeOrganizationRole] ??
151
+ activeOrganizationRole ??
152
+ resolvedRoleLabels.member })] }), _jsxs(CardBody, { className: "grid gap-3", children: [_jsx(Input, { label: resolvedLabels.formName, value: organizationName, onValueChange: setOrganizationName }), _jsx(Input, { label: resolvedLabels.formSlug, value: organizationSlug, onValueChange: setOrganizationSlug }), _jsx(Textarea, { label: resolvedLabels.formMetadata, value: organizationMetadata, onValueChange: setOrganizationMetadata, minRows: 4 }), _jsx("div", { className: "flex justify-end", children: _jsx(Button, { color: "primary", isLoading: isSavingOrganization, onPress: onUpdateOrganization, children: resolvedLabels.saveButton }) })] })] }) }));
153
+ }
@@ -0,0 +1,7 @@
1
+ export type OrganizationSwitcherProps = {
2
+ onInvalidateScopedQueries?: () => void | Promise<void>;
3
+ managerRoles?: string[];
4
+ managerPath?: string;
5
+ fallbackPath?: string;
6
+ };
7
+ export declare function OrganizationSwitcher({ onInvalidateScopedQueries, managerRoles, managerPath, fallbackPath, }: OrganizationSwitcherProps): import("react/jsx-runtime").JSX.Element;