@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,9 @@
1
+ import type { ReactNode } from "react";
2
+ import type { UseBackendTRPC } from "#types";
3
+ interface AuthRouterProps {
4
+ header: ReactNode;
5
+ providers?: string[];
6
+ useTRPC?: UseBackendTRPC;
7
+ }
8
+ export declare function AuthRouter({ header, providers, useTRPC }: AuthRouterProps): import("react/jsx-runtime").JSX.Element;
9
+ export {};
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Route } from "react-router";
3
+ import { AuthLayout } from "#modules/auth/components/AuthLayout";
4
+ import { ClaimAccountRoute } from "#modules/auth/components/ClaimAccountRoute";
5
+ import { ErrorAuthRoute } from "#modules/auth/components/ErrorAuthRoute";
6
+ import { ForgotPasswordRoute } from "#modules/auth/components/ForgotPasswordRoute";
7
+ import { LoginRoute } from "#modules/auth/components/LoginRoute";
8
+ import { ResetPasswordRoute } from "#modules/auth/components/ResetPasswordRoute";
9
+ import { SignupRoute } from "#modules/auth/components/SignupRoute";
10
+ export function AuthRouter({ header, providers, useTRPC }) {
11
+ return (_jsxs(Route, { element: _jsx(AuthLayout, { header: header }), children: [_jsx(Route, { path: "/login", element: _jsx(LoginRoute, { providers: providers }) }), _jsx(Route, { path: "/signup", element: _jsx(SignupRoute, { providers: providers, useTRPC: useTRPC }) }), _jsx(Route, { path: "/forgot-password", element: _jsx(ForgotPasswordRoute, {}) }), _jsx(Route, { path: "/reset-password", element: _jsx(ResetPasswordRoute, {}) }), _jsx(Route, { path: "/claim-account", element: _jsx(ClaimAccountRoute, { useTRPC: useTRPC }) }), _jsx(Route, { path: "/error-auth", element: _jsx(ErrorAuthRoute, {}) })] }));
12
+ }
@@ -0,0 +1,4 @@
1
+ import type { UseBackendTRPC } from "#types";
2
+ export declare function ClaimAccountRoute({ useTRPC }: {
3
+ useTRPC?: UseBackendTRPC;
4
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,143 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Alert, Button, Card, CardBody, CardHeader, Input } from "@heroui/react";
3
+ import { useSession } from "@m5kdev/frontend/modules/auth/hooks/useSession";
4
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
5
+ import { useEffect, useMemo, useState } from "react";
6
+ import { useLocation, useNavigate } from "react-router";
7
+ import { toast } from "sonner";
8
+ import { GoogleIcon } from "#icons/GoogleIcon";
9
+ import { LinkedInIcon } from "#icons/LinkedInIcon";
10
+ import { MicrosoftIcon } from "#icons/MicrosoftIcon";
11
+ export function ClaimAccountRoute({ useTRPC }) {
12
+ const { data: session, registerSession } = useSession();
13
+ const navigate = useNavigate();
14
+ const location = useLocation();
15
+ const queryClient = useQueryClient();
16
+ const [email, setEmail] = useState("");
17
+ const [newPassword, setNewPassword] = useState("");
18
+ const [busy, setBusy] = useState("none");
19
+ const trpc = useTRPC?.();
20
+ const linkedProvider = useMemo(() => {
21
+ const params = new URLSearchParams(location.search);
22
+ return params.get("linked");
23
+ }, [location.search]);
24
+ const claimStatusQuery = useQuery({
25
+ queryKey: ["auth", "claim-status", session?.user?.id ?? null],
26
+ enabled: !!trpc && !!session?.user,
27
+ queryFn: async () => {
28
+ if (!trpc)
29
+ return null;
30
+ return queryClient.fetchQuery(trpc.auth.getMyAccountClaimStatus.queryOptions());
31
+ },
32
+ });
33
+ const setEmailMutation = useMutation(trpc
34
+ ? trpc.auth.setMyAccountClaimEmail.mutationOptions()
35
+ : {
36
+ mutationFn: async () => ({ status: false }),
37
+ });
38
+ const acceptClaimMutation = useMutation(trpc
39
+ ? trpc.auth.acceptMyAccountClaim.mutationOptions()
40
+ : {
41
+ mutationFn: async () => ({ status: false }),
42
+ });
43
+ useEffect(() => {
44
+ if (session?.user?.email) {
45
+ setEmail(session.user.email);
46
+ }
47
+ }, [session?.user?.email]);
48
+ useEffect(() => {
49
+ if (!linkedProvider || !trpc)
50
+ return;
51
+ acceptClaimMutation
52
+ .mutateAsync(undefined)
53
+ .then(() => {
54
+ toast.success("Account provider linked");
55
+ queryClient.invalidateQueries({ queryKey: trpc.auth.getMyAccountClaimStatus.queryKey() });
56
+ })
57
+ .catch((error) => {
58
+ toast.error(error.message);
59
+ })
60
+ .finally(() => {
61
+ navigate("/claim-account", { replace: true });
62
+ });
63
+ }, [acceptClaimMutation, linkedProvider, navigate, queryClient, trpc]);
64
+ if (!trpc) {
65
+ return (_jsx(Alert, { color: "warning", variant: "faded", title: "Claim flow is unavailable because backend TRPC is not configured." }));
66
+ }
67
+ if (!session?.user) {
68
+ return (_jsx(Alert, { color: "warning", variant: "faded", title: "You need to sign in with your magic link before claiming this account." }));
69
+ }
70
+ const claim = claimStatusQuery.data;
71
+ const hasClaimEmail = Boolean(claim?.claimedEmail);
72
+ const onSetEmail = async () => {
73
+ setBusy("email");
74
+ try {
75
+ await setEmailMutation.mutateAsync({ email });
76
+ registerSession(() => undefined);
77
+ await queryClient.invalidateQueries({
78
+ queryKey: trpc.auth.getMyAccountClaimStatus.queryKey(),
79
+ });
80
+ toast.success("Email updated");
81
+ }
82
+ catch (error) {
83
+ toast.error(error instanceof Error ? error.message : "Unable to set email");
84
+ }
85
+ finally {
86
+ setBusy("none");
87
+ }
88
+ };
89
+ const onSetPassword = async () => {
90
+ setBusy("password");
91
+ try {
92
+ const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/auth/set-password`, {
93
+ method: "POST",
94
+ credentials: "include",
95
+ headers: {
96
+ "Content-Type": "application/json",
97
+ },
98
+ body: JSON.stringify({
99
+ newPassword,
100
+ }),
101
+ });
102
+ const payload = await response.json().catch(() => ({}));
103
+ if (!response.ok) {
104
+ throw new Error(payload?.message ?? "Unable to set password");
105
+ }
106
+ await acceptClaimMutation.mutateAsync(undefined);
107
+ await queryClient.invalidateQueries({
108
+ queryKey: trpc.auth.getMyAccountClaimStatus.queryKey(),
109
+ });
110
+ toast.success("Password set. Account claimed.");
111
+ }
112
+ catch (error) {
113
+ toast.error(error instanceof Error ? error.message : "Unable to set password");
114
+ }
115
+ finally {
116
+ setBusy("none");
117
+ }
118
+ };
119
+ const onLinkProvider = async (provider) => {
120
+ setBusy("link");
121
+ try {
122
+ const response = await fetch(`${import.meta.env.VITE_SERVER_URL}/api/auth/link-social`, {
123
+ method: "POST",
124
+ credentials: "include",
125
+ headers: { "Content-Type": "application/json" },
126
+ body: JSON.stringify({
127
+ provider,
128
+ callbackURL: `${window.location.origin}/claim-account?linked=${provider}`,
129
+ }),
130
+ });
131
+ const payload = await response.json().catch(() => ({}));
132
+ if (!response.ok || !payload?.url) {
133
+ throw new Error(payload?.message ?? "Unable to start provider linking");
134
+ }
135
+ window.location.href = payload.url;
136
+ }
137
+ catch (error) {
138
+ toast.error(error instanceof Error ? error.message : "Unable to link provider");
139
+ setBusy("none");
140
+ }
141
+ };
142
+ return (_jsxs(Card, { children: [_jsxs(CardHeader, { className: "flex flex-col gap-1", children: [_jsx("p", { className: "text-xl font-semibold", children: "Claim your account" }), _jsx("p", { className: "text-sm text-default-600", children: "You are signed in and can now set your permanent login methods." })] }), _jsxs(CardBody, { className: "grid gap-6", children: [claimStatusQuery.isLoading ? (_jsx(Alert, { color: "default", variant: "faded", title: "Loading claim status..." })) : !claim ? (_jsx(Alert, { color: "warning", variant: "faded", title: "No pending account claim was found for your user." })) : null, _jsxs("div", { className: "grid gap-2", children: [_jsx(Input, { type: "email", label: "Email", value: email, onValueChange: setEmail, description: "Set your real email before linking providers and password." }), _jsx(Button, { onPress: onSetEmail, isDisabled: !email || busy !== "none" || !claim, children: busy === "email" ? "Saving..." : "Save Email" })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx("p", { className: "text-sm font-medium", children: "Link a provider" }), _jsxs("div", { className: "grid gap-3 sm:grid-cols-3", children: [_jsxs(Button, { variant: "bordered", onPress: () => onLinkProvider("google"), isDisabled: busy !== "none" || !hasClaimEmail || !claim, children: [_jsx(GoogleIcon, { className: "h-4 w-4" }), " Google"] }), _jsxs(Button, { variant: "bordered", onPress: () => onLinkProvider("linkedin"), isDisabled: busy !== "none" || !hasClaimEmail || !claim, children: [_jsx(LinkedInIcon, { className: "h-4 w-4" }), " LinkedIn"] }), _jsxs(Button, { variant: "bordered", onPress: () => onLinkProvider("microsoft"), isDisabled: busy !== "none" || !hasClaimEmail || !claim, children: [_jsx(MicrosoftIcon, { className: "h-4 w-4" }), " Microsoft"] })] })] }), _jsxs("div", { className: "grid gap-2", children: [_jsx(Input, { type: "password", label: "Set password", value: newPassword, onValueChange: setNewPassword }), _jsx(Button, { onPress: onSetPassword, isDisabled: !newPassword || busy !== "none" || !hasClaimEmail || !claim, children: busy === "password" ? "Saving..." : "Set Password and Claim" })] })] })] }));
143
+ }
@@ -0,0 +1 @@
1
+ export declare function ErrorAuthRoute(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,93 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Card, CardBody, CardHeader } from "@heroui/react";
3
+ import { AlertCircle } from "lucide-react";
4
+ import { useQueryState } from "nuqs";
5
+ import { useTranslation } from "react-i18next";
6
+ import { Link } from "react-router";
7
+ export function ErrorAuthRoute() {
8
+ const { t } = useTranslation();
9
+ const [error] = useQueryState("error");
10
+ const ErrorEnum = {
11
+ invalid_callback_request: {
12
+ title: "Invalid callback request",
13
+ description: "The callback request is invalid. Please try again.",
14
+ buttons: ["login", "signup"],
15
+ signupLabel: null,
16
+ },
17
+ state_not_found: {
18
+ title: "State not found",
19
+ description: "The state was not found. Please try again.",
20
+ buttons: ["login", "signup"],
21
+ signupLabel: null,
22
+ },
23
+ account_already_linked_to_different_user: {
24
+ title: "Account already linked to different user",
25
+ description: "The account is already linked to a different user. Please try again.",
26
+ buttons: ["signup"],
27
+ signupLabel: null,
28
+ },
29
+ "email_doesn't_match": {
30
+ title: "Email doesn't match",
31
+ description: "The email doesn't match. Please try again.",
32
+ buttons: ["login", "signup"],
33
+ signupLabel: null,
34
+ },
35
+ email_not_found: {
36
+ title: "Email not found",
37
+ description: "The email was not found. Please try again.",
38
+ buttons: ["login", "signup"],
39
+ signupLabel: null,
40
+ },
41
+ no_callback_url: {
42
+ title: "No callback URL",
43
+ description: "The callback URL is not set. Please try again.",
44
+ buttons: ["login", "signup"],
45
+ signupLabel: null,
46
+ },
47
+ no_code: {
48
+ title: "No code",
49
+ description: "The code is not set. Please try again.",
50
+ buttons: ["login", "signup"],
51
+ signupLabel: null,
52
+ },
53
+ oauth_provider_not_found: {
54
+ title: "OAuth provider not found",
55
+ description: "The OAuth provider was not found. Please try again.",
56
+ buttons: ["login", "signup"],
57
+ signupLabel: null,
58
+ },
59
+ unable_to_link_account: {
60
+ title: "Unable to link account",
61
+ description: "The account could not be linked. Please try again.",
62
+ buttons: ["login", "signup"],
63
+ signupLabel: null,
64
+ },
65
+ unable_to_get_user_info: {
66
+ title: "Unable to get user info",
67
+ description: "The user info could not be retrieved. Please try again.",
68
+ buttons: ["login", "signup"],
69
+ signupLabel: null,
70
+ },
71
+ state_mismatch: {
72
+ title: "State mismatch",
73
+ description: "The state mismatch. Please try again.",
74
+ buttons: ["login", "signup"],
75
+ signupLabel: null,
76
+ },
77
+ signup_disabled: {
78
+ title: "Signup disabled",
79
+ description: "The signup is disabled while we are in beta. Please join the waitlist to be notified when we launch.",
80
+ buttons: ["signup"],
81
+ signupLabel: "Join the waitlist",
82
+ },
83
+ default: {
84
+ title: "Authentication Failed",
85
+ description: "We encountered an issue with your authentication request",
86
+ buttons: ["login", "signup"],
87
+ signupLabel: null,
88
+ },
89
+ };
90
+ const errorData = ErrorEnum[error] || ErrorEnum.default;
91
+ const { title, description, buttons, signupLabel } = errorData;
92
+ return (_jsx("div", { className: "flex flex-col gap-6", children: _jsxs(Card, { children: [_jsxs(CardHeader, { className: "text-center flex flex-col gap-2 items-center", children: [_jsx(AlertCircle, { className: "w-10 h-10 text-red-500" }), _jsx("p", { className: "text-xl font-semibold", children: title }), _jsx("p", { className: "text-sm text-default-600", children: description })] }), _jsx(CardBody, { className: "flex flex-col gap-4", children: _jsxs("div", { className: "flex flex-col gap-2", children: [buttons.includes("login") && (_jsx(Button, { as: Link, to: "/login", variant: "bordered", children: t("web-ui:auth.error.backToLogin") })), buttons.includes("signup") && (_jsx(Button, { as: Link, to: "/signup", variant: "bordered", children: signupLabel || t("web-ui:auth.error.backToSignup") }))] }) })] }) }));
93
+ }
@@ -0,0 +1 @@
1
+ export declare function ForgotPasswordForm(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,27 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Input } from "@heroui/react";
3
+ import { authClient } from "@m5kdev/frontend/modules/auth/auth.lib";
4
+ import { useState } from "react";
5
+ import { useForm } from "react-hook-form";
6
+ import { useTranslation } from "react-i18next";
7
+ import { toast } from "sonner";
8
+ export function ForgotPasswordForm() {
9
+ const { t } = useTranslation();
10
+ const { register, handleSubmit, formState: { errors }, } = useForm();
11
+ const [isBusy, setIsBusy] = useState(false);
12
+ const onSubmit = (data) => {
13
+ setIsBusy(true);
14
+ authClient
15
+ .requestPasswordReset({
16
+ email: data.email,
17
+ redirectTo: "/reset-password",
18
+ })
19
+ .then(() => {
20
+ toast.success(t("web-ui:auth.forgotPassword.success"));
21
+ })
22
+ .catch(() => {
23
+ toast.error(t("web-ui:auth.forgotPassword.error"));
24
+ });
25
+ };
26
+ return (_jsxs("form", { onSubmit: handleSubmit(onSubmit), className: "grid gap-6", children: [_jsxs("div", { className: "grid gap-2", children: [_jsx(Input, { labelPlacement: "outside", label: t("web-ui:auth.login.email"), type: "email", placeholder: t("web-ui:auth.login.placeholder.email"), variant: "bordered", isRequired: true, ...register("email", { required: true }) }), errors.email && (_jsx("span", { className: "text-red-500 text-xs", children: t("web-ui:auth.signup.emailRequired") }))] }), _jsx(Button, { type: "submit", className: "w-full", color: "primary", isDisabled: isBusy, children: t("web-ui:auth.forgotPassword.button") })] }));
27
+ }
@@ -0,0 +1 @@
1
+ export declare function ForgotPasswordRoute(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Card, CardBody, CardHeader } from "@heroui/react";
3
+ import { useTranslation } from "react-i18next";
4
+ import { Link } from "react-router";
5
+ import { ForgotPasswordForm } from "#modules/auth/components/ForgotPasswordForm";
6
+ export function ForgotPasswordRoute() {
7
+ const { t } = useTranslation();
8
+ return (_jsxs("div", { className: "flex flex-col gap-6", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { className: "text-center flex flex-col gap-1", children: [_jsx("p", { className: "text-xl font-semibold", children: t("web-ui:auth.forgotPassword.title") }), _jsx("p", { className: "text-sm text-default-600", children: t("web-ui:auth.forgotPassword.description") })] }), _jsx(CardBody, { children: _jsx(ForgotPasswordForm, {}) })] }), _jsxs("div", { className: "text-center text-xs text-muted-foreground", children: [t("web-ui:auth.forgotPassword.rememberPassword"), " ", _jsx(Link, { to: "/login", className: "underline underline-offset-4 hover:text-primary", children: t("web-ui:auth.login.button") })] })] }));
9
+ }
@@ -0,0 +1,5 @@
1
+ import type { UseBackendTRPC } from "#types";
2
+ export interface InviteFriendsProps {
3
+ useTRPC: UseBackendTRPC;
4
+ }
5
+ export declare function InviteFriends({ useTRPC }: InviteFriendsProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,74 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Card, CardBody, CardHeader, Chip, Input } from "@heroui/react";
3
+ import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
4
+ import { CheckCircle2, Link2Icon, Mail, Send, Ticket, Users, Zap } from "lucide-react";
5
+ import { useMemo, useState } from "react";
6
+ import { toast } from "sonner";
7
+ import { z } from "zod";
8
+ import { CopyButton } from "#components/CopyButton";
9
+ export function InviteFriends({ useTRPC }) {
10
+ const trpc = useTRPC();
11
+ const queryClient = useQueryClient();
12
+ const { data: waitlist = [] } = useQuery(trpc.auth.listWaitlist.queryOptions());
13
+ const { data: count = 0 } = useQuery(trpc.auth.getUserWaitlistCount.queryOptions());
14
+ const invitesAvailable = Math.max(0, 3 - count);
15
+ const inviteMutation = useMutation(trpc.auth.inviteToWaitlist.mutationOptions({
16
+ onSuccess: (result) => {
17
+ queryClient.setQueryData(trpc.auth.getUserWaitlistCount.queryKey(), (old) => (old ?? 0) + 1);
18
+ queryClient.setQueryData(trpc.auth.listWaitlist.queryKey(), (old) => [
19
+ ...(old ?? []),
20
+ result,
21
+ ]);
22
+ toast.success("Invitation sent successfully!");
23
+ },
24
+ onError: (error) => {
25
+ toast.error(error.message);
26
+ },
27
+ }));
28
+ const createInvitationCodeMutation = useMutation(trpc.auth.createInvitationCode.mutationOptions({
29
+ onSuccess: (result) => {
30
+ queryClient.setQueryData(trpc.auth.getUserWaitlistCount.queryKey(), (old) => (old ?? 0) + 1);
31
+ queryClient.setQueryData(trpc.auth.listWaitlist.queryKey(), (old) => [
32
+ ...(old ?? []),
33
+ result,
34
+ ]);
35
+ toast.success("Code created successfully!");
36
+ },
37
+ onError: (error) => {
38
+ toast.error(error.message);
39
+ },
40
+ }));
41
+ const [email, setEmail] = useState("");
42
+ const [name, setName] = useState("");
43
+ const isLoading = inviteMutation.isPending || createInvitationCodeMutation.isPending;
44
+ const isEmailValid = useMemo(() => {
45
+ return z.email().safeParse(email).success;
46
+ }, [email]);
47
+ const handleInvite = async (e) => {
48
+ e.preventDefault();
49
+ if (!email)
50
+ return;
51
+ inviteMutation.mutate({ email, name: name.length > 0 ? name : undefined });
52
+ setEmail("");
53
+ setName("");
54
+ };
55
+ const handleCreateCode = async () => {
56
+ createInvitationCodeMutation.mutate({ name: name.length > 0 ? name : undefined });
57
+ setEmail("");
58
+ setName("");
59
+ };
60
+ const getStatusColor = (status) => {
61
+ switch (status.toLowerCase()) {
62
+ case "accepted":
63
+ case "completed":
64
+ return "success";
65
+ case "invited":
66
+ return "warning";
67
+ case "waitlist":
68
+ return "default";
69
+ default:
70
+ return "default";
71
+ }
72
+ };
73
+ return (_jsxs("div", { className: "max-w-3xl mx-auto p-6 space-y-8", children: [_jsxs("div", { className: "text-center space-y-4", children: [_jsx("div", { className: "inline-flex items-center justify-center p-4 bg-primary/10 rounded-full mb-2 ring-1 ring-primary/20", children: _jsx(Ticket, { className: "w-8 h-8 text-primary" }) }), _jsx("h1", { className: "text-3xl md:text-4xl font-bold tracking-tight", children: "Invite Friends & Skip the Waitlist" }), _jsxs("p", { className: "text-lg text-default-600 max-w-lg mx-auto leading-relaxed", children: ["Encourage your friends to join! Friends invited by you get", " ", _jsx("span", { className: "text-foreground font-medium", children: "immediate access" }), " and skip the waitlist completely."] }), _jsx("div", { className: "flex justify-center mt-4", children: _jsxs(Chip, { color: invitesAvailable > 0 ? "warning" : "default", variant: "flat", size: "lg", startContent: _jsx(Zap, { size: 16, className: invitesAvailable > 0 ? "text-warning-600" : "" }), className: "font-medium", children: [invitesAvailable, " ", invitesAvailable === 1 ? "Invite" : "Invites", " Remaining"] }) })] }), _jsxs("div", { className: "grid gap-6", children: [_jsxs(Card, { className: "shadow-sm border border-default-200", children: [_jsxs(CardHeader, { className: "flex flex-col items-start gap-1 px-6 pt-6 pb-2", children: [_jsx("h3", { className: "text-xl font-semibold", children: "Send an Invitation via Email" }), _jsx("p", { className: "text-small text-default-600", children: "They'll receive a unique code to join instantly." })] }), _jsx(CardBody, { className: "px-6 pb-6", children: _jsxs("form", { onSubmit: handleInvite, className: "flex flex-col gap-4", children: [_jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [_jsx(Input, { label: "Friend's Name (Optional)", placeholder: "e.g. Alex", value: name, onValueChange: setName, variant: "bordered", labelPlacement: "outside" }), _jsx(Input, { type: "email", label: "Email Address (Required for sending)", placeholder: "friend@example.com", value: email, onValueChange: setEmail, variant: "bordered", labelPlacement: "outside", startContent: _jsx(Mail, { className: "text-default-400 pointer-events-none flex-shrink-0", size: 16 }) })] }), _jsxs("div", { className: "flex justify-end pt-2 gap-2", children: [_jsx(Button, { color: "primary", variant: "bordered", type: "button", isLoading: isLoading, isDisabled: invitesAvailable <= 0, onPress: handleCreateCode, className: "font-medium", endContent: !isLoading && _jsx(Link2Icon, { size: 16 }), children: "Create Invitation Link" }), _jsx(Button, { color: "primary", type: "submit", isLoading: isLoading, isDisabled: invitesAvailable <= 0 || !isEmailValid, className: "font-medium", endContent: !isLoading && _jsx(Send, { size: 16 }), children: "Send Invitation" })] })] }) })] }), _jsxs("div", { className: "space-y-4", children: [_jsx("div", { className: "flex items-center justify-between", children: _jsx("h3", { className: "text-xl font-semibold", children: "Created Invitations" }) }), waitlist.length > 0 ? (_jsx("div", { className: "flex flex-col gap-3", children: waitlist.map((item) => (_jsxs("div", { className: "flex items-center justify-between p-4 border border-default-200 rounded-lg bg-content1", children: [_jsxs("div", { className: "flex flex-row gap-3", children: [_jsx("div", { children: _jsx("span", { className: "text-sm font-medium", children: item.email || item.name || "Open Invitation Link" }) }), _jsx(Chip, { size: "sm", color: getStatusColor(item.status), variant: "flat", className: "capitalize", children: item.status.toLowerCase() })] }), _jsx("div", { className: "flex items-center gap-3", children: item.code && (_jsx(CopyButton, { variant: "flat", color: "success", size: "sm", text: `${import.meta.env.VITE_APP_URL}/signup?code=${item.code}`, isIconOnly: true })) })] }, item.id))) })) : (_jsx("div", { className: "text-center py-8 text-default-600 border border-dashed border-default-200 rounded-lg", children: "No invitations created yet." }))] })] }), _jsxs("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-4 py-4", children: [_jsxs("div", { className: "flex flex-col items-center text-center p-6 rounded-2xl bg-content1 border border-default-100 shadow-sm", children: [_jsx("div", { className: "p-3 bg-warning/10 text-warning rounded-full mb-4", children: _jsx(Zap, { className: "w-6 h-6" }) }), _jsx("h3", { className: "font-semibold mb-2", children: "Instant Access" }), _jsx("p", { className: "text-sm text-default-600", children: "Friends you invite skip the waitlist completely and get in right away." })] }), _jsxs("div", { className: "flex flex-col items-center text-center p-6 rounded-2xl bg-content1 border border-default-100 shadow-sm", children: [_jsx("div", { className: "p-3 bg-primary/10 text-primary rounded-full mb-4", children: _jsx(Users, { className: "w-6 h-6" }) }), _jsx("h3", { className: "font-semibold mb-2", children: "Grow Your Network" }), _jsx("p", { className: "text-sm text-default-600", children: "Build your circle within the app from day one." })] }), _jsxs("div", { className: "flex flex-col items-center text-center p-6 rounded-2xl bg-content1 border border-default-100 shadow-sm", children: [_jsx("div", { className: "p-3 bg-success/10 text-success rounded-full mb-4", children: _jsx(CheckCircle2, { className: "w-6 h-6" }) }), _jsx("h3", { className: "font-semibold mb-2", children: "Verified Status" }), _jsx("p", { className: "text-sm text-default-600", children: "Invited members get a verified badge on their profile." })] })] })] }));
74
+ }
@@ -0,0 +1,5 @@
1
+ import { type BadgeProps } from "@heroui/react";
2
+ export declare function LastUsedBadge({ lastMethod, method, children, ...props }: BadgeProps & {
3
+ lastMethod?: string | null;
4
+ method?: string | null;
5
+ }): string | number | bigint | boolean | Iterable<import("react").ReactNode> | Promise<string | number | bigint | boolean | import("react").ReactPortal | import("react").ReactElement<unknown, string | import("react").JSXElementConstructor<any>> | Iterable<import("react").ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Badge } from "@heroui/react";
3
+ import { useTranslation } from "react-i18next";
4
+ export function LastUsedBadge({ lastMethod, method, children, ...props }) {
5
+ const { t } = useTranslation();
6
+ if (lastMethod !== method)
7
+ return children;
8
+ return (_jsx(Badge, { ...props, content: t("web-ui:auth.login.lastUsed"), color: "warning", className: "px-2 !right-[10%]", children: children }));
9
+ }
@@ -0,0 +1,3 @@
1
+ export declare function LoginForm({ providers }: {
2
+ providers?: string[];
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,44 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Button, Input } 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 { useForm } from "react-hook-form";
6
+ import { useTranslation } from "react-i18next";
7
+ import { Link, useNavigate } from "react-router";
8
+ import { toast } from "sonner";
9
+ import { AuthProviders } from "./AuthProviders";
10
+ import { LastUsedBadge } from "./LastUsedBadge";
11
+ export function LoginForm({ providers }) {
12
+ const lastMethod = authClient.getLastUsedLoginMethod();
13
+ const { register, handleSubmit } = useForm();
14
+ const { registerSession } = useSession();
15
+ const navigate = useNavigate();
16
+ const { t } = useTranslation();
17
+ const onSubmit = (data) => {
18
+ console.log(data);
19
+ authClient.signIn
20
+ .email({
21
+ email: data.email,
22
+ password: data.password,
23
+ })
24
+ .then((res) => {
25
+ console.log(res);
26
+ if (res.data?.user) {
27
+ registerSession(() => {
28
+ navigate("/");
29
+ });
30
+ }
31
+ else if (res.error) {
32
+ toast.error(t("web-ui:auth.errors.authentication"), {
33
+ description: res.error.message,
34
+ });
35
+ }
36
+ })
37
+ .catch((error) => {
38
+ toast.error(t("web-ui:auth.errors.server"), {
39
+ description: error.message,
40
+ });
41
+ });
42
+ };
43
+ return (_jsx("form", { onSubmit: handleSubmit(onSubmit), children: _jsxs("div", { className: "grid gap-6", children: [_jsx(AuthProviders, { providers: providers, lastMethod: lastMethod }), _jsxs("div", { className: "grid gap-6", children: [_jsxs("div", { className: "grid gap-2", children: [_jsx(LastUsedBadge, { lastMethod: lastMethod, method: "email", children: _jsx("label", { htmlFor: "email", className: "text-sm font-medium", children: t("web-ui:auth.login.email") }) }), _jsx(Input, { type: "email", placeholder: t("web-ui:auth.login.placeholder.email"), variant: "bordered", isRequired: true, ...register("email", { required: true }) })] }), _jsxs("div", { className: "grid gap-2", children: [_jsxs("div", { className: "flex items-center", children: [_jsx("label", { htmlFor: "password", className: "text-sm font-medium", children: t("web-ui:auth.login.password") }), _jsx(Link, { to: "/forgot-password", className: "ml-auto text-sm underline-offset-4 hover:underline", children: t("web-ui:auth.login.forgotPassword") })] }), _jsx(Input, { placeholder: t("web-ui:auth.login.password"), type: "password", variant: "bordered", isRequired: true, ...register("password", { required: true }) })] }), _jsx(Button, { type: "submit", className: "w-full", color: "primary", children: t("web-ui:auth.login.button") })] }), _jsxs("div", { className: "text-center text-sm", children: [t("web-ui:auth.login.noAccount"), " ", _jsx(Link, { to: "/signup", className: "underline underline-offset-4", children: t("web-ui:auth.login.signUp") })] })] }) }));
44
+ }
@@ -0,0 +1,3 @@
1
+ export declare function LoginRoute({ providers }: {
2
+ providers?: string[];
3
+ }): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,11 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Card, CardBody, CardHeader } from "@heroui/react";
3
+ import { useTranslation } from "react-i18next";
4
+ import { Link } from "react-router";
5
+ import { LoginForm } from "./LoginForm";
6
+ export function LoginRoute({ providers }) {
7
+ const { t } = useTranslation();
8
+ return (_jsxs("div", { className: "flex flex-col gap-6", children: [_jsxs(Card, { children: [_jsxs(CardHeader, { className: "text-center flex flex-col gap-1", children: [_jsx("p", { className: "text-xl font-semibold", children: t("web-ui:auth.login.welcome") }), _jsx("p", { className: "text-sm text-default-600", children: providers
9
+ ? t("web-ui:auth.login.descriptionWithProviders")
10
+ : t("web-ui:auth.login.description") })] }), _jsx(CardBody, { children: _jsx(LoginForm, { providers: providers }) })] }), _jsxs("div", { className: "text-balance text-center text-xs text-muted-foreground [&_a]:underline [&_a]:underline-offset-4 [&_a]:hover:text-primary ", children: [t("web-ui:common.byClickingContinue"), " ", _jsx(Link, { to: "/terms-of-service", children: t("web-ui:common.termsOfService") }), " ", t("web-ui:common.and"), " ", _jsx(Link, { to: "/privacy-policy", children: t("web-ui:common.privacyPolicy") }), "."] })] }));
11
+ }
@@ -0,0 +1 @@
1
+ export default function Logout(): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,15 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Spinner } from "@heroui/react";
3
+ import { authClient } from "@m5kdev/frontend/modules/auth/auth.lib";
4
+ import { useEffect } from "react";
5
+ import { useNavigate } from "react-router";
6
+ export default function Logout() {
7
+ const navigate = useNavigate();
8
+ // biome-ignore lint/correctness/useExhaustiveDependencies(authClient): authClient is a singleton
9
+ // biome-ignore lint/correctness/useExhaustiveDependencies(navigate): navigate is a global hook
10
+ useEffect(() => {
11
+ authClient.signOut();
12
+ navigate("/login");
13
+ }, []);
14
+ return (_jsx("div", { className: "flex-1 justify-center align-center", children: _jsx(Spinner, {}) }));
15
+ }
@@ -0,0 +1,9 @@
1
+ export type OrganizationAcceptInvitationRouteProps = {
2
+ authReturnKey?: string;
3
+ loginPath?: string;
4
+ defaultRedirectPath?: string;
5
+ managerRedirectPath?: string;
6
+ managerRoles?: string[];
7
+ onInvalidateScopedQueries?: () => void | Promise<void>;
8
+ };
9
+ export declare function OrganizationAcceptInvitationRoute({ authReturnKey, loginPath, defaultRedirectPath, managerRedirectPath, managerRoles, onInvalidateScopedQueries, }: OrganizationAcceptInvitationRouteProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,102 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Card, CardBody, CardHeader, Spinner } 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 { useEffect, useMemo, useState } from "react";
6
+ import { useTranslation } from "react-i18next";
7
+ import { useLocation, useNavigate, useSearchParams } from "react-router";
8
+ import { toast } from "sonner";
9
+ export function OrganizationAcceptInvitationRoute({ authReturnKey = "org-auth-return", loginPath = "/login", defaultRedirectPath = "/", managerRedirectPath = "/organization/members", managerRoles = ["admin", "owner"], onInvalidateScopedQueries, }) {
10
+ const { t } = useTranslation();
11
+ const [searchParams] = useSearchParams();
12
+ const { data: session, registerSession } = useSession();
13
+ const navigate = useNavigate();
14
+ const location = useLocation();
15
+ const invitationId = searchParams.get("id");
16
+ const [phase, setPhase] = useState("idle");
17
+ const [errorMessage, setErrorMessage] = useState(null);
18
+ const managerRoleSet = useMemo(() => new Set(managerRoles), [managerRoles]);
19
+ useEffect(() => {
20
+ if (!invitationId) {
21
+ setPhase("error");
22
+ setErrorMessage(t("web-ui:organization.invitation.errorMissing"));
23
+ return;
24
+ }
25
+ if (!session) {
26
+ sessionStorage.setItem(authReturnKey, `${location.pathname}${location.search}`);
27
+ navigate(loginPath, { replace: true });
28
+ }
29
+ }, [
30
+ authReturnKey,
31
+ invitationId,
32
+ location.pathname,
33
+ location.search,
34
+ loginPath,
35
+ navigate,
36
+ session,
37
+ t,
38
+ ]);
39
+ useEffect(() => {
40
+ if (!session || !invitationId || phase !== "idle") {
41
+ return;
42
+ }
43
+ let isMounted = true;
44
+ const run = async () => {
45
+ try {
46
+ setPhase("accepting");
47
+ const { data, error } = await authClient.organization.acceptInvitation({ invitationId });
48
+ if (error) {
49
+ throw new Error(error.message ?? t("web-ui:organization.invitation.acceptFailed"));
50
+ }
51
+ const organizationId = data?.invitation
52
+ ?.organizationId ?? null;
53
+ const invitationRole = data?.invitation?.role ?? "member";
54
+ if (organizationId) {
55
+ const result = await authClient.organization.setActive({ organizationId });
56
+ if (result.error) {
57
+ throw new Error(result.error.message ?? t("web-ui:organization.invitation.activateFailed"));
58
+ }
59
+ }
60
+ registerSession(() => {
61
+ void onInvalidateScopedQueries?.();
62
+ });
63
+ if (isMounted) {
64
+ setPhase("success");
65
+ toast.success(t("web-ui:organization.invitation.accepted"));
66
+ navigate(managerRoleSet.has(invitationRole) ? managerRedirectPath : defaultRedirectPath, {
67
+ replace: true,
68
+ });
69
+ }
70
+ }
71
+ catch (error) {
72
+ if (isMounted) {
73
+ setPhase("error");
74
+ setErrorMessage(error instanceof Error
75
+ ? error.message
76
+ : t("web-ui:organization.invitation.acceptFailed"));
77
+ }
78
+ }
79
+ };
80
+ void run();
81
+ return () => {
82
+ isMounted = false;
83
+ };
84
+ }, [
85
+ defaultRedirectPath,
86
+ invitationId,
87
+ managerRedirectPath,
88
+ managerRoleSet,
89
+ navigate,
90
+ onInvalidateScopedQueries,
91
+ phase,
92
+ registerSession,
93
+ session,
94
+ t,
95
+ ]);
96
+ if (phase === "error") {
97
+ return (_jsx("div", { className: "min-h-screen flex items-center justify-center p-6", children: _jsxs(Card, { className: "w-full max-w-lg", children: [_jsx(CardHeader, { className: "text-lg font-semibold", children: t("web-ui:organization.invitation.error") }), _jsx(CardBody, { children: errorMessage ?? t("web-ui:organization.invitation.unableAccept") })] }) }));
98
+ }
99
+ return (_jsx("div", { className: "min-h-screen flex items-center justify-center p-6", children: _jsxs(Card, { className: "w-full max-w-lg", children: [_jsx(CardHeader, { className: "text-lg font-semibold", children: t("web-ui:organization.invitation.accepting") }), _jsxs(CardBody, { className: "flex items-center gap-3", children: [_jsx(Spinner, { size: "sm" }), _jsx("span", { children: phase === "success"
100
+ ? t("web-ui:organization.invitation.redirecting")
101
+ : t("web-ui:organization.invitation.pleaseWait") })] })] }) }));
102
+ }