@alepha/ui 0.18.1 → 0.18.3

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 (280) hide show
  1. package/dist/admin/{AdminApiKeys-C-6_Q-lH.js → AdminApiKeys-Dy_k-4Vd.js} +17 -38
  2. package/dist/admin/AdminApiKeys-Dy_k-4Vd.js.map +1 -0
  3. package/dist/admin/{AdminAudits-Bgbf04hO.js → AdminAudits-CKiFMSSU.js} +23 -19
  4. package/dist/admin/AdminAudits-CKiFMSSU.js.map +1 -0
  5. package/dist/admin/AdminDashboard-PhC_dZqo.js +67 -0
  6. package/dist/admin/AdminDashboard-PhC_dZqo.js.map +1 -0
  7. package/dist/admin/{AdminFiles-B9a7G3cY.js → AdminFiles-DFTjijGp.js} +3 -7
  8. package/dist/admin/AdminFiles-DFTjijGp.js.map +1 -0
  9. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js → AdminJobDashboard-BL8gGPDp.js} +2 -2
  10. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js.map → AdminJobDashboard-BL8gGPDp.js.map} +1 -1
  11. package/dist/admin/{AdminJobExecutions-B9cek5dl.js → AdminJobExecutions-D9E-CS-U.js} +24 -36
  12. package/dist/admin/AdminJobExecutions-D9E-CS-U.js.map +1 -0
  13. package/dist/admin/{AdminJobRegistry-DFgV3oqx.js → AdminJobRegistry-Ci9ue1zC.js} +10 -18
  14. package/dist/admin/AdminJobRegistry-Ci9ue1zC.js.map +1 -0
  15. package/dist/admin/AdminLayout-I6TlUMPc.js +61 -0
  16. package/dist/admin/AdminLayout-I6TlUMPc.js.map +1 -0
  17. package/dist/admin/AdminNotifications-ZPHCYrv7.js +542 -0
  18. package/dist/admin/AdminNotifications-ZPHCYrv7.js.map +1 -0
  19. package/dist/admin/{AdminParameters-DHw9ATgl.js → AdminParameters-CqgvhRsb.js} +120 -105
  20. package/dist/admin/AdminParameters-CqgvhRsb.js.map +1 -0
  21. package/dist/admin/{AdminSessions-BhGJPI3z.js → AdminSessions-Bz5NRuoW.js} +48 -53
  22. package/dist/admin/AdminSessions-Bz5NRuoW.js.map +1 -0
  23. package/dist/admin/{AdminUserLayout-BdC4Te8m.js → AdminUserLayout-lXT6I0Qq.js} +14 -8
  24. package/dist/admin/AdminUserLayout-lXT6I0Qq.js.map +1 -0
  25. package/dist/admin/{AdminUserProfile-DAt23fqY.js → AdminUserProfile-vFBLoJ3h.js} +3 -3
  26. package/dist/admin/{AdminUserProfile-DAt23fqY.js.map → AdminUserProfile-vFBLoJ3h.js.map} +1 -1
  27. package/dist/admin/{AdminUserSessions-1uzcx02z.js → AdminUserSessions-CT_YDim0.js} +33 -35
  28. package/dist/admin/AdminUserSessions-CT_YDim0.js.map +1 -0
  29. package/dist/admin/AdminUsers-D1UfGya9.js +206 -0
  30. package/dist/admin/AdminUsers-D1UfGya9.js.map +1 -0
  31. package/dist/admin/{AuthLayout-DFJvCvzw.js → AuthLayout-_frhdgOO.js} +2 -2
  32. package/dist/admin/{AuthLayout-DFJvCvzw.js.map → AuthLayout-_frhdgOO.js.map} +1 -1
  33. package/dist/admin/{IconGoogle-CSQLPYwX.js → IconGoogle-Ch1m3Uzl.js} +1 -1
  34. package/dist/admin/{IconGoogle-CSQLPYwX.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
  35. package/dist/admin/Login-xtNmQtGh.js +275 -0
  36. package/dist/admin/Login-xtNmQtGh.js.map +1 -0
  37. package/dist/{auth/Profile-BMX_Ar_s.js → admin/Profile-_AtPUwAP.js} +31 -27
  38. package/dist/admin/Profile-_AtPUwAP.js.map +1 -0
  39. package/dist/admin/{Register-Cs10l8vX.js → Register-JcCjHUUn.js} +199 -143
  40. package/dist/admin/Register-JcCjHUUn.js.map +1 -0
  41. package/dist/admin/{ResetPassword-BwDdfkGH.js → ResetPassword-CwGBPLJO.js} +7 -7
  42. package/dist/admin/ResetPassword-CwGBPLJO.js.map +1 -0
  43. package/dist/admin/{VerifyEmail-DfXHAiQl.js → VerifyEmail-hNxWejWf.js} +23 -8
  44. package/dist/admin/VerifyEmail-hNxWejWf.js.map +1 -0
  45. package/dist/admin/{core-2xoLiT0o.js → core-CYaRQ8O-.js} +2082 -688
  46. package/dist/admin/core-CYaRQ8O-.js.map +1 -0
  47. package/dist/admin/index.d.ts +112 -48
  48. package/dist/admin/index.d.ts.map +1 -1
  49. package/dist/admin/index.js +467 -69
  50. package/dist/admin/index.js.map +1 -1
  51. package/dist/auth/{AuthLayout-CAE1pX9s.js → AuthLayout-AvLlcLjS.js} +2 -2
  52. package/dist/auth/{AuthLayout-CAE1pX9s.js.map → AuthLayout-AvLlcLjS.js.map} +1 -1
  53. package/dist/auth/Login-BA1E8IZl.js +275 -0
  54. package/dist/auth/Login-BA1E8IZl.js.map +1 -0
  55. package/dist/{admin/Profile-B-c9pCPf.js → auth/Profile-YcWdeuFz.js} +31 -27
  56. package/dist/auth/Profile-YcWdeuFz.js.map +1 -0
  57. package/dist/auth/{Register-6hi_cpfF.js → Register-CPhEO5MG.js} +198 -142
  58. package/dist/auth/Register-CPhEO5MG.js.map +1 -0
  59. package/dist/{demo/ResetPassword-DWN0lzr5.js → auth/ResetPassword-DCtGcneA.js} +7 -7
  60. package/dist/auth/ResetPassword-DCtGcneA.js.map +1 -0
  61. package/dist/{demo/VerifyEmail-DZWL72K4.js → auth/VerifyEmail-DkH7NBfn.js} +23 -8
  62. package/dist/auth/VerifyEmail-DkH7NBfn.js.map +1 -0
  63. package/dist/auth/{core-niW0sFLv.js → core-D5jIAVF2.js} +1385 -329
  64. package/dist/auth/core-D5jIAVF2.js.map +1 -0
  65. package/dist/auth/index.d.ts +105 -49
  66. package/dist/auth/index.d.ts.map +1 -1
  67. package/dist/auth/index.js +29 -26
  68. package/dist/auth/index.js.map +1 -1
  69. package/dist/core/index.d.ts +210 -74
  70. package/dist/core/index.d.ts.map +1 -1
  71. package/dist/core/index.js +2247 -834
  72. package/dist/core/index.js.map +1 -1
  73. package/dist/demo/{AuthLayout-jLa0aKsI.js → AuthLayout-Brri4A-L.js} +2 -2
  74. package/dist/demo/{AuthLayout-jLa0aKsI.js.map → AuthLayout-Brri4A-L.js.map} +1 -1
  75. package/dist/demo/DemoButton-wiCxZZ_L.js +182 -0
  76. package/dist/demo/DemoButton-wiCxZZ_L.js.map +1 -0
  77. package/dist/demo/DemoControlSelect-D7ILObVg.js +305 -0
  78. package/dist/demo/DemoControlSelect-D7ILObVg.js.map +1 -0
  79. package/dist/demo/DemoDataTable-DZ5Y8pFX.js +362 -0
  80. package/dist/demo/DemoDataTable-DZ5Y8pFX.js.map +1 -0
  81. package/dist/demo/{DemoDialog-4ItHLf9t.js → DemoDialog-CUWdLHim.js} +2 -2
  82. package/dist/demo/{DemoDialog-4ItHLf9t.js.map → DemoDialog-CUWdLHim.js.map} +1 -1
  83. package/dist/demo/{DemoFlex-EtVq8QfX.js → DemoFlex-a8OhMMvq.js} +3 -3
  84. package/dist/demo/{DemoFlex-EtVq8QfX.js.map → DemoFlex-a8OhMMvq.js.map} +1 -1
  85. package/dist/demo/{DemoHeading-BS-vGfkI.js → DemoHeading-C13OVDfS.js} +3 -3
  86. package/dist/demo/{DemoHeading-BS-vGfkI.js.map → DemoHeading-C13OVDfS.js.map} +1 -1
  87. package/dist/demo/{DemoHome-Clbn8AmS.js → DemoHome-D_De3UiT.js} +2 -2
  88. package/dist/demo/{DemoHome-Clbn8AmS.js.map → DemoHome-D_De3UiT.js.map} +1 -1
  89. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js → DemoJsonViewer-B50s9aGM.js} +3 -3
  90. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js.map → DemoJsonViewer-B50s9aGM.js.map} +1 -1
  91. package/dist/demo/{DemoLayout-C56xb5EE.js → DemoLayout-CHU8WTwO.js} +14 -5
  92. package/dist/demo/DemoLayout-CHU8WTwO.js.map +1 -0
  93. package/dist/demo/{DemoLogin-BZwpicOS.js → DemoLogin-BBlrWpml.js} +49 -32
  94. package/dist/demo/DemoLogin-BBlrWpml.js.map +1 -0
  95. package/dist/demo/{DemoRegister-C7_qc4MJ.js → DemoRegister-BuNE3_-f.js} +49 -50
  96. package/dist/demo/DemoRegister-BuNE3_-f.js.map +1 -0
  97. package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js → DemoResetPassword-D_IjjjOJ.js} +12 -16
  98. package/dist/demo/DemoResetPassword-D_IjjjOJ.js.map +1 -0
  99. package/dist/demo/{DemoSidebar-CcBo4ltC.js → DemoSidebar-Giy2HRBD.js} +3 -3
  100. package/dist/demo/{DemoSidebar-CcBo4ltC.js.map → DemoSidebar-Giy2HRBD.js.map} +1 -1
  101. package/dist/demo/{DemoText-CzXuUn3g.js → DemoText-ubcw-vog.js} +3 -3
  102. package/dist/demo/{DemoText-CzXuUn3g.js.map → DemoText-ubcw-vog.js.map} +1 -1
  103. package/dist/demo/{DemoToast-BgHDhWrX.js → DemoToast-9die_dYT.js} +2 -2
  104. package/dist/demo/{DemoToast-BgHDhWrX.js.map → DemoToast-9die_dYT.js.map} +1 -1
  105. package/dist/demo/{DemoTypeForm-DDzWoMSV.js → DemoTypeForm-D_d6OVKL.js} +8 -4
  106. package/dist/demo/DemoTypeForm-D_d6OVKL.js.map +1 -0
  107. package/dist/demo/DemoVerifyEmail-B43KlF4F.js +34 -0
  108. package/dist/demo/DemoVerifyEmail-B43KlF4F.js.map +1 -0
  109. package/dist/demo/Login-C12N4oGs.js +275 -0
  110. package/dist/demo/Login-C12N4oGs.js.map +1 -0
  111. package/dist/demo/{Profile-CWqti7FB.js → Profile-DS5q4vOh.js} +31 -27
  112. package/dist/demo/Profile-DS5q4vOh.js.map +1 -0
  113. package/dist/demo/{Register-a70LPgs2.js → Register-B4hLBeEv.js} +198 -142
  114. package/dist/demo/Register-B4hLBeEv.js.map +1 -0
  115. package/dist/{auth/ResetPassword-CqfTk1FI.js → demo/ResetPassword-D8g9ha1N.js} +7 -7
  116. package/dist/demo/ResetPassword-D8g9ha1N.js.map +1 -0
  117. package/dist/demo/{Showcase-Dq3MISpd.js → Showcase-D6Fxt4X4.js} +64 -65
  118. package/dist/demo/Showcase-D6Fxt4X4.js.map +1 -0
  119. package/dist/{auth/VerifyEmail-nWiSTMjF.js → demo/VerifyEmail-BjDo0cZA.js} +23 -8
  120. package/dist/demo/VerifyEmail-BjDo0cZA.js.map +1 -0
  121. package/dist/demo/{auth-d6n3xbug.js → auth-ByVTreDl.js} +8 -8
  122. package/dist/demo/{auth-d6n3xbug.js.map → auth-ByVTreDl.js.map} +1 -1
  123. package/dist/demo/{core-RCUw1Q-a.js → core-DFgB3yU4.js} +2182 -756
  124. package/dist/demo/core-DFgB3yU4.js.map +1 -0
  125. package/dist/demo/index.d.ts +1 -0
  126. package/dist/demo/index.d.ts.map +1 -1
  127. package/dist/demo/index.js +24 -18
  128. package/dist/demo/index.js.map +1 -1
  129. package/package.json +7 -7
  130. package/src/admin/{AdminRouter.ts → AdminRouter.tsx} +150 -18
  131. package/src/admin/components/AdminDashboard.tsx +52 -0
  132. package/src/admin/components/AdminLayout.tsx +32 -40
  133. package/src/admin/components/audits/AdminAudits.tsx +22 -16
  134. package/src/admin/components/files/AdminFiles.tsx +1 -6
  135. package/src/admin/components/jobs/AdminJobExecutions.tsx +33 -39
  136. package/src/admin/components/jobs/AdminJobRegistry.tsx +9 -18
  137. package/src/admin/components/keys/AdminApiKeys.tsx +23 -41
  138. package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
  139. package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
  140. package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
  141. package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
  142. package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
  143. package/src/admin/components/parameters/ParameterTree.tsx +28 -184
  144. package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
  145. package/src/admin/components/sessions/AdminSessions.tsx +71 -71
  146. package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
  147. package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
  148. package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
  149. package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
  150. package/src/admin/components/users/AdminUserSessions.tsx +33 -31
  151. package/src/admin/components/users/AdminUsers.tsx +184 -72
  152. package/src/admin/index.ts +2 -2
  153. package/src/admin/primitives/$uiAdmin.ts +1 -1
  154. package/src/auth/components/Login.tsx +188 -121
  155. package/src/auth/components/Profile.tsx +1 -22
  156. package/src/auth/components/ProfileField.tsx +39 -0
  157. package/src/auth/components/Register.tsx +215 -158
  158. package/src/auth/components/ResetPassword.tsx +7 -11
  159. package/src/auth/components/VerifyEmail.tsx +35 -10
  160. package/src/auth/components/buttons/UserButton.tsx +20 -24
  161. package/src/auth/index.ts +1 -0
  162. package/src/core/atoms/alephaSidebarAtom.ts +1 -1
  163. package/src/core/atoms/alephaThemeListAtom.ts +14 -1
  164. package/src/core/atoms/alephaThemeOverridesAtom.ts +17 -0
  165. package/src/core/atoms/themes/editorial.ts +184 -0
  166. package/src/core/atoms/themes/monochrome.ts +197 -0
  167. package/src/core/atoms/themes/rosePine.ts +208 -0
  168. package/src/core/atoms/themes/softBrutalism.ts +221 -0
  169. package/src/core/atoms/themes/terminal.ts +186 -0
  170. package/src/core/components/Flex.tsx +101 -1
  171. package/src/core/components/Text.tsx +1 -1
  172. package/src/core/components/buttons/ActionButton.tsx +109 -87
  173. package/src/core/components/buttons/DarkModeButton.tsx +3 -3
  174. package/src/core/components/buttons/LanguageButton.tsx +1 -1
  175. package/src/core/components/buttons/OmnibarButton.tsx +1 -2
  176. package/src/core/components/buttons/ThemeButton.tsx +40 -11
  177. package/src/core/components/buttons/ThemeExpertModal.tsx +184 -0
  178. package/src/core/components/buttons/ToggleSidebarButton.tsx +1 -2
  179. package/src/core/components/data/DetailDrawer.tsx +102 -96
  180. package/src/core/components/data/DetailList.tsx +2 -1
  181. package/src/core/components/layout/AppBar.tsx +10 -0
  182. package/src/core/components/layout/Breadcrumb.tsx +3 -6
  183. package/src/core/components/layout/DashboardShell.tsx +28 -11
  184. package/src/core/components/layout/Sidebar.tsx +18 -235
  185. package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
  186. package/src/core/components/layout/SidebarItem.tsx +146 -0
  187. package/src/core/components/layout/index.ts +3 -1
  188. package/src/core/constants/ui.ts +5 -5
  189. package/src/core/form/components/Control.tsx +31 -29
  190. package/src/core/form/components/ControlArray.tsx +13 -39
  191. package/src/core/form/components/ControlDate.tsx +10 -21
  192. package/src/core/form/components/ControlNumber.tsx +4 -33
  193. package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
  194. package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
  195. package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
  196. package/src/core/form/components/ControlSelect.tsx +294 -92
  197. package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
  198. package/src/core/form/components/TypeForm.tsx +5 -2
  199. package/src/core/form/index.ts +8 -1
  200. package/src/core/form/utils/parseInput.ts +7 -3
  201. package/src/core/hooks/useTheme.ts +26 -3
  202. package/src/core/index.ts +9 -2
  203. package/src/core/interfaces/AlephaTheme.ts +2 -0
  204. package/src/core/json/components/JsonViewer.tsx +103 -319
  205. package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
  206. package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
  207. package/src/core/json/components/JsonViewerShared.ts +76 -0
  208. package/src/core/providers/ThemeProvider.ts +108 -8
  209. package/src/core/services/DialogService.tsx +24 -3
  210. package/src/core/styles.css +33 -20
  211. package/src/core/table/components/ColumnPicker.tsx +3 -3
  212. package/src/core/table/components/DataTable.tsx +233 -143
  213. package/src/core/table/components/DataTableFilters.tsx +6 -16
  214. package/src/core/table/components/DataTablePagination.tsx +58 -29
  215. package/src/core/table/components/DataTableToolbar.tsx +16 -7
  216. package/src/core/table/components/FilterPicker.tsx +3 -3
  217. package/src/core/table/index.ts +1 -0
  218. package/src/core/table/interfaces/types.ts +42 -9
  219. package/src/core/utils/icons.tsx +2 -2
  220. package/src/demo/DemoRouter.ts +8 -1
  221. package/src/demo/components/DemoLayout.tsx +12 -2
  222. package/src/demo/components/auth/DemoLogin.tsx +35 -28
  223. package/src/demo/components/auth/DemoRegister.tsx +35 -49
  224. package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
  225. package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
  226. package/src/demo/components/core/DemoButton.tsx +123 -103
  227. package/src/demo/components/core/DemoControlSelect.tsx +325 -0
  228. package/src/demo/components/core/DemoDataTable.tsx +255 -241
  229. package/src/demo/components/core/DemoTypeForm.tsx +7 -2
  230. package/src/demo/components/shared/MacWindow.tsx +5 -11
  231. package/src/demo/components/shared/Showcase.tsx +28 -42
  232. package/dist/admin/AdminApiKeys-C-6_Q-lH.js.map +0 -1
  233. package/dist/admin/AdminAudits-Bgbf04hO.js.map +0 -1
  234. package/dist/admin/AdminFiles-B9a7G3cY.js.map +0 -1
  235. package/dist/admin/AdminJobExecutions-B9cek5dl.js.map +0 -1
  236. package/dist/admin/AdminJobRegistry-DFgV3oqx.js.map +0 -1
  237. package/dist/admin/AdminLayout-DHsvWxVB.js +0 -70
  238. package/dist/admin/AdminLayout-DHsvWxVB.js.map +0 -1
  239. package/dist/admin/AdminParameters-DHw9ATgl.js.map +0 -1
  240. package/dist/admin/AdminSessions-BhGJPI3z.js.map +0 -1
  241. package/dist/admin/AdminUserLayout-BdC4Te8m.js.map +0 -1
  242. package/dist/admin/AdminUserSessions-1uzcx02z.js.map +0 -1
  243. package/dist/admin/AdminUsers-C85c3eiQ.js +0 -121
  244. package/dist/admin/AdminUsers-C85c3eiQ.js.map +0 -1
  245. package/dist/admin/Login-BGheURrg.js +0 -219
  246. package/dist/admin/Login-BGheURrg.js.map +0 -1
  247. package/dist/admin/Profile-B-c9pCPf.js.map +0 -1
  248. package/dist/admin/Register-Cs10l8vX.js.map +0 -1
  249. package/dist/admin/ResetPassword-BwDdfkGH.js.map +0 -1
  250. package/dist/admin/VerifyEmail-DfXHAiQl.js.map +0 -1
  251. package/dist/admin/auth-Dr0Cf8I7.js +0 -319
  252. package/dist/admin/auth-Dr0Cf8I7.js.map +0 -1
  253. package/dist/admin/core-2xoLiT0o.js.map +0 -1
  254. package/dist/auth/Login-Denw_UGy.js +0 -219
  255. package/dist/auth/Login-Denw_UGy.js.map +0 -1
  256. package/dist/auth/Profile-BMX_Ar_s.js.map +0 -1
  257. package/dist/auth/Register-6hi_cpfF.js.map +0 -1
  258. package/dist/auth/ResetPassword-CqfTk1FI.js.map +0 -1
  259. package/dist/auth/VerifyEmail-nWiSTMjF.js.map +0 -1
  260. package/dist/auth/core-niW0sFLv.js.map +0 -1
  261. package/dist/demo/DemoButton-BmaWZVwf.js +0 -178
  262. package/dist/demo/DemoButton-BmaWZVwf.js.map +0 -1
  263. package/dist/demo/DemoDataTable-Z9xyV221.js +0 -362
  264. package/dist/demo/DemoDataTable-Z9xyV221.js.map +0 -1
  265. package/dist/demo/DemoLayout-C56xb5EE.js.map +0 -1
  266. package/dist/demo/DemoLogin-BZwpicOS.js.map +0 -1
  267. package/dist/demo/DemoRegister-C7_qc4MJ.js.map +0 -1
  268. package/dist/demo/DemoResetPassword-BI1Ct4Dw.js.map +0 -1
  269. package/dist/demo/DemoTypeForm-DDzWoMSV.js.map +0 -1
  270. package/dist/demo/DemoVerifyEmail-C_Irdnov.js +0 -30
  271. package/dist/demo/DemoVerifyEmail-C_Irdnov.js.map +0 -1
  272. package/dist/demo/Login-hSOU3jZc.js +0 -219
  273. package/dist/demo/Login-hSOU3jZc.js.map +0 -1
  274. package/dist/demo/Profile-CWqti7FB.js.map +0 -1
  275. package/dist/demo/Register-a70LPgs2.js.map +0 -1
  276. package/dist/demo/ResetPassword-DWN0lzr5.js.map +0 -1
  277. package/dist/demo/Showcase-Dq3MISpd.js.map +0 -1
  278. package/dist/demo/VerifyEmail-DZWL72K4.js.map +0 -1
  279. package/dist/demo/core-RCUw1Q-a.js.map +0 -1
  280. package/src/demo/styles.css +0 -0
@@ -1,6 +1,7 @@
1
- import { _ as ActionButton, r as DataTable, s as Text, u as Flex } from "./core-2xoLiT0o.js";
1
+ import { _ as ActionButton, b as useToast, l as Flex$1, m as useDialog, r as DataTable, s as Text$1 } from "./core-CYaRQ8O-.js";
2
2
  import { t } from "alepha";
3
3
  import { useI18n } from "alepha/react/i18n";
4
+ import { Badge } from "@mantine/core";
4
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
6
  import { useState } from "react";
6
7
  import { IconDeviceDesktop, IconDeviceMobile, IconDeviceTablet, IconTrash } from "@tabler/icons-react";
@@ -9,30 +10,36 @@ import { useClient } from "alepha/react";
9
10
  import { sessions } from "alepha/api/users";
10
11
 
11
12
  //#region ../../src/admin/components/sessions/AdminSessions.tsx
13
+ const filters = t.object({ userId: t.optional(t.uuid({ $control: { query: t.pick(sessions.schema, ["userId"]) } })) });
14
+ const getDeviceIcon = (device) => {
15
+ switch (device) {
16
+ case "MOBILE": return /* @__PURE__ */ jsx(IconDeviceMobile, { size: 14 });
17
+ case "TABLET": return /* @__PURE__ */ jsx(IconDeviceTablet, { size: 14 });
18
+ default: return /* @__PURE__ */ jsx(IconDeviceDesktop, { size: 14 });
19
+ }
20
+ };
21
+ const isExpired = (expiresAt) => new Date(expiresAt) < /* @__PURE__ */ new Date();
12
22
  const AdminSessions = (props) => {
13
23
  const client = useClient();
14
24
  const router = useRouter();
15
25
  const { l } = useI18n();
26
+ const dialog = useDialog();
27
+ const toast = useToast();
16
28
  const [refreshKey, setRefreshKey] = useState(0);
17
- const filters = t.object({ userId: t.optional(t.uuid({ $control: { query: t.pick(sessions.schema, ["userId"]) } })) });
18
- const getDeviceIcon = (device) => {
19
- switch (device) {
20
- case "MOBILE": return /* @__PURE__ */ jsx(IconDeviceMobile, { size: 14 });
21
- case "TABLET": return /* @__PURE__ */ jsx(IconDeviceTablet, { size: 14 });
22
- default: return /* @__PURE__ */ jsx(IconDeviceDesktop, { size: 14 });
23
- }
24
- };
25
- const isExpired = (expiresAt) => {
26
- return new Date(expiresAt) < /* @__PURE__ */ new Date();
27
- };
28
- const handleDelete = async (sessionId) => {
29
+ const handleDelete = async (session) => {
30
+ if (!await dialog.confirm({
31
+ title: "Revoke session",
32
+ message: "Are you sure you want to revoke this session? The user will be signed out."
33
+ })) return;
29
34
  await client.deleteSession({
30
- params: { id: sessionId },
35
+ params: { id: session.id },
31
36
  query: { userRealmName: props.userRealmName }
32
37
  });
38
+ toast.success("Session revoked");
33
39
  setRefreshKey((k) => k + 1);
34
40
  };
35
- return /* @__PURE__ */ jsx(Flex, {
41
+ return /* @__PURE__ */ jsx(Flex$1, {
42
+ p: "md",
36
43
  flex: 1,
37
44
  direction: "column",
38
45
  children: /* @__PURE__ */ jsx(DataTable, {
@@ -46,14 +53,9 @@ const AdminSessions = (props) => {
46
53
  horizontalSpacing: "xs",
47
54
  verticalSpacing: "xs"
48
55
  },
49
- onFilterChange: (key, _value, form) => {
50
- if (key === "userId") return form.submit();
51
- },
56
+ onFilterChange: (_key, _value, form) => form.submit(),
52
57
  filters,
53
- tableTrProps: (item) => {
54
- if (isExpired(item.expiresAt)) return { opacity: .5 };
55
- return {};
56
- },
58
+ tableTrProps: (item) => ({ style: { opacity: isExpired(item.expiresAt) ? .5 : 1 } }),
57
59
  items: async (filters) => {
58
60
  return await client.findSessions({ query: {
59
61
  ...filters,
@@ -67,7 +69,7 @@ const AdminSessions = (props) => {
67
69
  variant: "subtle",
68
70
  size: "xs",
69
71
  href: router.path("adminUserProfile", { params: { userId: item.userId } }),
70
- children: /* @__PURE__ */ jsxs(Text, {
72
+ children: /* @__PURE__ */ jsxs(Text$1, {
71
73
  size: "xs",
72
74
  ff: "monospace",
73
75
  children: [item.userId.slice(0, 8), "..."]
@@ -76,68 +78,61 @@ const AdminSessions = (props) => {
76
78
  },
77
79
  userAgent: {
78
80
  label: "Device",
79
- fit: true,
80
- value: (item) => /* @__PURE__ */ jsx(Flex, {
81
+ value: (item) => /* @__PURE__ */ jsx(Flex$1, {
81
82
  gap: 4,
82
83
  align: "center",
83
- children: item.userAgent ? /* @__PURE__ */ jsxs(Fragment, { children: [getDeviceIcon(item.userAgent.device), /* @__PURE__ */ jsxs(Text, {
84
+ children: item.userAgent ? /* @__PURE__ */ jsxs(Fragment, { children: [getDeviceIcon(item.userAgent.device), /* @__PURE__ */ jsxs(Text$1, {
84
85
  size: "xs",
85
86
  children: [
86
87
  item.userAgent.browser,
87
88
  " / ",
88
89
  item.userAgent.os
89
90
  ]
90
- })] }) : /* @__PURE__ */ jsx(Text, {
91
+ })] }) : /* @__PURE__ */ jsx(Text$1, {
91
92
  size: "xs",
92
- c: "dimmed",
93
- children: "-"
93
+ muted: true,
94
+ children: ""
94
95
  })
95
96
  })
96
97
  },
97
98
  ip: {
98
99
  label: "IP",
99
- fit: true,
100
- value: (item) => /* @__PURE__ */ jsx(Text, {
100
+ value: (item) => /* @__PURE__ */ jsx(Text$1, {
101
101
  size: "xs",
102
102
  ff: "monospace",
103
- c: "dimmed",
104
- children: item.ip || "-"
103
+ muted: true,
104
+ children: item.ip || ""
105
105
  })
106
106
  },
107
107
  expiresAt: {
108
108
  label: "Status",
109
- fit: true,
110
- value: (item) => /* @__PURE__ */ jsx(Text, {
111
- size: "xs",
112
- c: isExpired(item.expiresAt) ? "dimmed" : void 0,
109
+ value: (item) => /* @__PURE__ */ jsx(Badge, {
110
+ size: "sm",
111
+ variant: "light",
112
+ color: isExpired(item.expiresAt) ? "gray" : "green",
113
113
  children: isExpired(item.expiresAt) ? "Expired" : "Active"
114
114
  })
115
115
  },
116
116
  createdAt: {
117
117
  label: "Created",
118
- fit: true,
119
- value: (item) => /* @__PURE__ */ jsx(Text, {
118
+ value: (item) => /* @__PURE__ */ jsx(Text$1, {
120
119
  size: "xs",
121
- c: "dimmed",
120
+ muted: true,
122
121
  children: l(item.createdAt, { date: "fromNow" })
123
122
  })
124
- },
125
- actions: {
126
- label: "",
127
- fit: true,
128
- value: (item) => /* @__PURE__ */ jsx(ActionButton, {
129
- size: "xs",
130
- variant: "subtle",
131
- color: "red",
132
- onClick: () => handleDelete(item.id),
133
- children: /* @__PURE__ */ jsx(IconTrash, { size: 14 })
134
- })
135
123
  }
136
- }
124
+ },
125
+ rowActions: (item) => [{
126
+ label: "Revoke session",
127
+ icon: IconTrash,
128
+ color: "red",
129
+ onClick: () => handleDelete(item),
130
+ visible: !isExpired(item.expiresAt)
131
+ }]
137
132
  }, refreshKey)
138
133
  });
139
134
  };
140
135
 
141
136
  //#endregion
142
137
  export { AdminSessions as default };
143
- //# sourceMappingURL=AdminSessions-BhGJPI3z.js.map
138
+ //# sourceMappingURL=AdminSessions-Bz5NRuoW.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminSessions-Bz5NRuoW.js","names":["Flex","Text"],"sources":["../../src/admin/components/sessions/AdminSessions.tsx"],"sourcesContent":["import {\n ActionButton,\n DataTable,\n Flex,\n Text,\n useDialog,\n useToast,\n} from \"@alepha/ui\";\nimport { Badge } from \"@mantine/core\";\nimport {\n IconDeviceDesktop,\n IconDeviceMobile,\n IconDeviceTablet,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { type Page, t } from \"alepha\";\nimport {\n type AdminSessionController,\n type SessionEntity,\n sessions,\n} from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { useState } from \"react\";\nimport type { AdminRouter } from \"../../AdminRouter.tsx\";\n\nexport interface AdminSessionsProps {\n userRealmName?: string;\n}\n\nconst filters = t.object({\n userId: t.optional(\n t.uuid({\n $control: {\n query: t.pick(sessions.schema, [\"userId\"]),\n },\n }),\n ),\n});\n\nconst getDeviceIcon = (device?: string) => {\n switch (device) {\n case \"MOBILE\":\n return <IconDeviceMobile size={14} />;\n case \"TABLET\":\n return <IconDeviceTablet size={14} />;\n default:\n return <IconDeviceDesktop size={14} />;\n }\n};\n\nconst isExpired = (expiresAt: Date | string) =>\n new Date(expiresAt) < new Date();\n\nconst AdminSessions = (props: AdminSessionsProps) => {\n const client = useClient<AdminSessionController>();\n const router = useRouter<AdminRouter>();\n const { l } = useI18n();\n const dialog = useDialog();\n const toast = useToast();\n const [refreshKey, setRefreshKey] = useState(0);\n\n const handleDelete = async (session: SessionEntity) => {\n const confirmed = await dialog.confirm({\n title: \"Revoke session\",\n message:\n \"Are you sure you want to revoke this session? The user will be signed out.\",\n });\n if (!confirmed) return;\n await client.deleteSession({\n params: { id: session.id },\n query: { userRealmName: props.userRealmName },\n });\n toast.success(\"Session revoked\");\n setRefreshKey((k) => k + 1);\n };\n\n return (\n <Flex p=\"md\" flex={1} direction=\"column\">\n <DataTable<SessionEntity, typeof filters>\n key={refreshKey}\n submitOnInit\n defaultSize={10}\n typeFormProps={{\n skipSubmitButton: true,\n columns: 3,\n }}\n tableProps={{\n horizontalSpacing: \"xs\",\n verticalSpacing: \"xs\",\n }}\n onFilterChange={(_key, _value, form) => form.submit()}\n filters={filters}\n tableTrProps={(item) => ({\n style: {\n opacity: isExpired(item.expiresAt) ? 0.5 : 1,\n },\n })}\n items={async (filters) => {\n const response = await client.findSessions({\n query: {\n ...filters,\n userRealmName: props.userRealmName,\n },\n });\n return response as Page<SessionEntity>;\n }}\n columns={{\n userId: {\n label: \"User\",\n value: (item) => (\n <ActionButton\n variant=\"subtle\"\n size=\"xs\"\n href={router.path(\"adminUserProfile\", {\n params: { userId: item.userId },\n })}\n >\n <Text size=\"xs\" ff=\"monospace\">\n {item.userId.slice(0, 8)}...\n </Text>\n </ActionButton>\n ),\n },\n userAgent: {\n label: \"Device\",\n value: (item) => (\n <Flex gap={4} align=\"center\">\n {item.userAgent ? (\n <>\n {getDeviceIcon(item.userAgent.device)}\n <Text size=\"xs\">\n {item.userAgent.browser} / {item.userAgent.os}\n </Text>\n </>\n ) : (\n <Text size=\"xs\" muted>\n —\n </Text>\n )}\n </Flex>\n ),\n },\n ip: {\n label: \"IP\",\n value: (item) => (\n <Text size=\"xs\" ff=\"monospace\" muted>\n {item.ip || \"—\"}\n </Text>\n ),\n },\n expiresAt: {\n label: \"Status\",\n value: (item) => (\n <Badge\n size=\"sm\"\n variant=\"light\"\n color={isExpired(item.expiresAt) ? \"gray\" : \"green\"}\n >\n {isExpired(item.expiresAt) ? \"Expired\" : \"Active\"}\n </Badge>\n ),\n },\n createdAt: {\n label: \"Created\",\n value: (item) => (\n <Text size=\"xs\" muted>\n {l(item.createdAt, { date: \"fromNow\" })}\n </Text>\n ),\n },\n }}\n rowActions={(item) => [\n {\n label: \"Revoke session\",\n icon: IconTrash,\n color: \"red\",\n onClick: () => handleDelete(item),\n visible: !isExpired(item.expiresAt),\n },\n ]}\n />\n </Flex>\n );\n};\n\nexport default AdminSessions;\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { _ as ActionButton, b as useToast, i as useDialog, s as Text$1, u as Flex$1 } from "./core-2xoLiT0o.js";
1
+ import { _ as ActionButton, b as useToast, l as Flex$1, m as useDialog, s as Text$1 } from "./core-CYaRQ8O-.js";
2
2
  import { t } from "alepha";
3
3
  import { ActionIcon, Avatar, Badge, Button, Flex, Loader, Menu, Tabs, Text, Tooltip } from "@mantine/core";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -7,8 +7,8 @@ import { IconBan, IconChevronDown, IconChevronLeft, IconExternalLink, IconShield
7
7
  import { NestedView, useActive, useRouter, useRouterState } from "alepha/react/router";
8
8
  import { useClient } from "alepha/react";
9
9
 
10
- //#region ../../src/admin/components/shared/AdminResourceHeader.tsx
11
- const ActionMenuItem = (props) => {
10
+ //#region ../../src/admin/components/shared/AdminResourceHeaderMenuItem.tsx
11
+ const AdminResourceHeaderMenuItem = (props) => {
12
12
  const { action } = props;
13
13
  const router = useRouter();
14
14
  const menuItemProps = {};
@@ -22,6 +22,9 @@ const ActionMenuItem = (props) => {
22
22
  children: action.label
23
23
  });
24
24
  };
25
+
26
+ //#endregion
27
+ //#region ../../src/admin/components/shared/AdminResourceHeader.tsx
25
28
  const AdminResourceHeader = (props) => {
26
29
  const { backHref, backLabel = "Back", avatar, avatarColor = "blue", title, subtitle, identifier, identifierLabel = "ID", status, badges = [], primaryAction, menuActions = [], externalUrl } = props;
27
30
  const renderAvatar = () => {
@@ -123,7 +126,7 @@ const AdminResourceHeader = (props) => {
123
126
  variant: "default",
124
127
  rightSection: /* @__PURE__ */ jsx(IconChevronDown, { size: 16 }),
125
128
  children: "Actions"
126
- }) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: menuActions.map((action, index) => /* @__PURE__ */ jsx(ActionMenuItem, { action }, index)) })]
129
+ }) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: menuActions.map((action, index) => /* @__PURE__ */ jsx(AdminResourceHeaderMenuItem, { action }, index)) })]
127
130
  })
128
131
  ]
129
132
  })]
@@ -132,8 +135,8 @@ const AdminResourceHeader = (props) => {
132
135
  };
133
136
 
134
137
  //#endregion
135
- //#region ../../src/admin/components/shared/AdminResourceTabs.tsx
136
- const TabItem = (props) => {
138
+ //#region ../../src/admin/components/shared/AdminResourceTabsItem.tsx
139
+ const AdminResourceTabsItem = (props) => {
137
140
  const { tab } = props;
138
141
  const router = useRouter();
139
142
  const { isActive, isPending } = useActive({ href: tab.href });
@@ -149,12 +152,15 @@ const TabItem = (props) => {
149
152
  children: [tab.label, tab.count !== void 0 && tab.count > 0 && ` (${tab.count})`]
150
153
  });
151
154
  };
155
+
156
+ //#endregion
157
+ //#region ../../src/admin/components/shared/AdminResourceTabs.tsx
152
158
  const AdminResourceTabs = (props) => {
153
159
  const { tabs, activeTab, children } = props;
154
160
  return /* @__PURE__ */ jsxs(Tabs, {
155
161
  value: activeTab,
156
162
  variant: "default",
157
- children: [/* @__PURE__ */ jsx(Tabs.List, { children: tabs.map((tab) => /* @__PURE__ */ jsx(TabItem, { tab }, tab.value)) }), children]
163
+ children: [/* @__PURE__ */ jsx(Tabs.List, { children: tabs.map((tab) => /* @__PURE__ */ jsx(AdminResourceTabsItem, { tab }, tab.value)) }), children]
158
164
  });
159
165
  };
160
166
 
@@ -293,4 +299,4 @@ const AdminUserLayout = (props) => {
293
299
 
294
300
  //#endregion
295
301
  export { AdminUserLayout as default, useUser };
296
- //# sourceMappingURL=AdminUserLayout-BdC4Te8m.js.map
302
+ //# sourceMappingURL=AdminUserLayout-lXT6I0Qq.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminUserLayout-lXT6I0Qq.js","names":["Flex","Text"],"sources":["../../src/admin/components/shared/AdminResourceHeaderMenuItem.tsx","../../src/admin/components/shared/AdminResourceHeader.tsx","../../src/admin/components/shared/AdminResourceTabsItem.tsx","../../src/admin/components/shared/AdminResourceTabs.tsx","../../src/admin/components/users/AdminUserLayout.tsx"],"sourcesContent":["import { Menu } from \"@mantine/core\";\nimport { useRouter } from \"alepha/react/router\";\nimport type { AdminResourceAction } from \"./AdminResourceHeader.tsx\";\n\nexport interface AdminResourceHeaderMenuItemProps {\n /**\n * Action configuration\n */\n action: AdminResourceAction;\n}\n\nconst AdminResourceHeaderMenuItem = (\n props: AdminResourceHeaderMenuItemProps,\n) => {\n const { action } = props;\n const router = useRouter();\n\n const menuItemProps: Record<string, unknown> = {};\n if (action.href) {\n Object.assign(menuItemProps, router.anchor(action.href));\n } else if (action.onClick) {\n menuItemProps.onClick = action.onClick;\n }\n\n return (\n <Menu.Item\n leftSection={action.icon ? <action.icon size={16} /> : undefined}\n color={action.color}\n disabled={action.disabled}\n {...menuItemProps}\n >\n {action.label}\n </Menu.Item>\n );\n};\n\nexport default AdminResourceHeaderMenuItem;\n","import { ActionButton } from \"@alepha/ui\";\nimport {\n ActionIcon,\n Avatar,\n Badge,\n Button,\n Flex,\n Menu,\n Text,\n Tooltip,\n} from \"@mantine/core\";\nimport {\n IconChevronDown,\n IconChevronLeft,\n IconExternalLink,\n} from \"@tabler/icons-react\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport AdminResourceHeaderMenuItem from \"./AdminResourceHeaderMenuItem.tsx\";\n\nexport interface AdminResourceAction {\n label: string;\n icon?: ComponentType<{ size?: number }>;\n onClick?: () => void;\n href?: string;\n color?: string;\n disabled?: boolean;\n loading?: boolean;\n variant?: \"filled\" | \"light\" | \"outline\" | \"subtle\";\n}\n\nexport interface AdminResourceHeaderProps {\n /**\n * Back navigation URL\n */\n backHref?: string;\n\n /**\n * Back navigation label\n */\n backLabel?: string;\n\n /**\n * Avatar content (letter, image URL, or custom node)\n */\n avatar?: string | ReactNode;\n\n /**\n * Avatar color\n */\n avatarColor?: string;\n\n /**\n * Resource title (e.g., user name)\n */\n title: string;\n\n /**\n * Secondary text (e.g., email)\n */\n subtitle?: string;\n\n /**\n * Tertiary identifier to copy (e.g., user ID)\n */\n identifier?: string;\n\n /**\n * Label for the identifier tooltip\n */\n identifierLabel?: string;\n\n /**\n * Status badge\n */\n status?: {\n label: string;\n color: \"green\" | \"red\" | \"yellow\" | \"blue\" | \"gray\";\n };\n\n /**\n * Additional badges (e.g., roles)\n */\n badges?: Array<{\n label: string;\n color?: string;\n variant?: \"filled\" | \"light\" | \"outline\" | \"dot\";\n }>;\n\n /**\n * Primary action button\n */\n primaryAction?: AdminResourceAction;\n\n /**\n * Menu actions (shown in dropdown)\n */\n menuActions?: AdminResourceAction[];\n\n /**\n * External link URL\n */\n externalUrl?: string;\n\n /**\n * Loading state\n */\n loading?: boolean;\n}\n\nconst AdminResourceHeader = (props: AdminResourceHeaderProps) => {\n const {\n backHref,\n backLabel = \"Back\",\n avatar,\n avatarColor = \"blue\",\n title,\n subtitle,\n identifier,\n identifierLabel = \"ID\",\n status,\n badges = [],\n primaryAction,\n menuActions = [],\n externalUrl,\n } = props;\n\n const renderAvatar = () => {\n if (typeof avatar === \"string\") {\n if (avatar.startsWith(\"http\") || avatar.startsWith(\"/\")) {\n return (\n <Avatar src={avatar} size={56} radius=\"md\" color={avatarColor} />\n );\n }\n return (\n <Avatar size={56} radius=\"md\" color={avatarColor}>\n {avatar}\n </Avatar>\n );\n }\n if (avatar) {\n return avatar;\n }\n return (\n <Avatar size={56} radius=\"md\" color={avatarColor}>\n {title.charAt(0).toUpperCase()}\n </Avatar>\n );\n };\n\n return (\n <Flex direction=\"column\" gap=\"xs\">\n {/* Breadcrumb / Back navigation */}\n {backHref && (\n <Flex>\n <ActionButton\n variant=\"subtle\"\n size=\"xs\"\n href={backHref}\n leftSection={<IconChevronLeft size={14} />}\n c=\"dimmed\"\n >\n {backLabel}\n </ActionButton>\n </Flex>\n )}\n\n {/* Main header */}\n <Flex justify=\"space-between\" align=\"flex-start\" wrap=\"nowrap\">\n {/* Left: Avatar + Info */}\n <Flex gap=\"md\" wrap=\"nowrap\">\n {renderAvatar()}\n\n <Flex\n direction=\"column\"\n gap={2}\n justify=\"center\"\n style={{ minHeight: 56 }}\n >\n {/* Title row */}\n <Flex gap=\"xs\" align=\"center\">\n <Text size=\"md\" fw={600} lh={1.2}>\n {title}\n </Text>\n {status && (\n <Badge\n size=\"xs\"\n variant=\"light\"\n color={status.color}\n tt=\"lowercase\"\n >\n {status.label}\n </Badge>\n )}\n </Flex>\n\n {/* Subtitle */}\n {subtitle && (\n <Text size=\"xs\" c=\"dimmed\">\n {subtitle}\n </Text>\n )}\n </Flex>\n </Flex>\n\n {/* Right: Actions */}\n <Flex gap=\"xs\">\n {externalUrl && (\n <Tooltip label=\"Open in new tab\" openDelay={500}>\n <ActionIcon\n variant=\"subtle\"\n color=\"gray\"\n component=\"a\"\n href={externalUrl}\n target=\"_blank\"\n >\n <IconExternalLink size={18} />\n </ActionIcon>\n </Tooltip>\n )}\n\n {primaryAction && (\n <ActionButton\n variant={primaryAction.variant ?? \"light\"}\n color={primaryAction.color}\n onClick={primaryAction.onClick}\n href={primaryAction.href}\n loading={primaryAction.loading}\n disabled={primaryAction.disabled}\n leftSection={\n primaryAction.icon ? (\n <primaryAction.icon size={16} />\n ) : undefined\n }\n >\n {primaryAction.label}\n </ActionButton>\n )}\n\n {menuActions.length > 0 && (\n <Menu position=\"bottom-end\" shadow=\"md\" width={220}>\n <Menu.Target>\n <Button\n variant=\"default\"\n rightSection={<IconChevronDown size={16} />}\n >\n Actions\n </Button>\n </Menu.Target>\n <Menu.Dropdown>\n {menuActions.map((action, index) => (\n <AdminResourceHeaderMenuItem key={index} action={action} />\n ))}\n </Menu.Dropdown>\n </Menu>\n )}\n </Flex>\n </Flex>\n </Flex>\n );\n};\n\nexport default AdminResourceHeader;\n","import { Tabs } from \"@mantine/core\";\nimport { useActive, useRouter } from \"alepha/react/router\";\nimport type { AdminResourceTab } from \"./AdminResourceTabs.tsx\";\n\nexport interface AdminResourceTabsItemProps {\n /**\n * Tab configuration\n */\n tab: AdminResourceTab;\n}\n\nconst AdminResourceTabsItem = (props: AdminResourceTabsItemProps) => {\n const { tab } = props;\n const router = useRouter();\n const { isActive, isPending } = useActive({ href: tab.href });\n const anchorProps = router.anchor(tab.href);\n\n return (\n <Tabs.Tab\n value={tab.value}\n component=\"a\"\n leftSection={tab.icon ? <tab.icon size={16} /> : undefined}\n disabled={tab.disabled}\n data-active={isActive || undefined}\n style={{\n opacity: isPending ? 0.6 : 1,\n }}\n {...anchorProps}\n >\n {tab.label}\n {tab.count !== undefined && tab.count > 0 && ` (${tab.count})`}\n </Tabs.Tab>\n );\n};\n\nexport default AdminResourceTabsItem;\n","import { Tabs } from \"@mantine/core\";\nimport type { ComponentType, ReactNode } from \"react\";\nimport AdminResourceTabsItem from \"./AdminResourceTabsItem.tsx\";\n\nexport interface AdminResourceTab {\n /**\n * Tab key/value\n */\n value: string;\n\n /**\n * Tab label\n */\n label: string;\n\n /**\n * Tab icon\n */\n icon?: ComponentType<{ size?: number }>;\n\n /**\n * Navigation href\n */\n href: string;\n\n /**\n * Whether tab is disabled\n */\n disabled?: boolean;\n\n /**\n * Badge count to show\n */\n count?: number;\n}\n\nexport interface AdminResourceTabsProps {\n /**\n * Array of tab configurations\n */\n tabs: AdminResourceTab[];\n\n /**\n * Currently active tab value\n */\n activeTab?: string;\n\n /**\n * Content to render below tabs\n */\n children?: ReactNode;\n}\n\nconst AdminResourceTabs = (props: AdminResourceTabsProps) => {\n const { tabs, activeTab, children } = props;\n\n return (\n <Tabs value={activeTab} variant=\"default\">\n <Tabs.List>\n {tabs.map((tab) => (\n <AdminResourceTabsItem key={tab.value} tab={tab} />\n ))}\n </Tabs.List>\n\n {children}\n </Tabs>\n );\n};\n\nexport default AdminResourceTabs;\n","import { Flex, Text, useDialog, useToast } from \"@alepha/ui\";\nimport { Loader } from \"@mantine/core\";\nimport { IconBan, IconShieldCheck, IconTrash } from \"@tabler/icons-react\";\nimport { t } from \"alepha\";\nimport type { AdminUserController, UserEntity } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { NestedView, useRouter, useRouterState } from \"alepha/react/router\";\nimport {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useState,\n} from \"react\";\nimport type { AdminRouter } from \"../../AdminRouter.ts\";\nimport AdminResourceHeader from \"../shared/AdminResourceHeader.tsx\";\nimport AdminResourceTabs from \"../shared/AdminResourceTabs.tsx\";\n\nexport interface AdminUserLayoutProps {\n userRealmName?: string;\n}\n\ninterface UserContextValue {\n user: UserEntity;\n reload: () => void;\n}\n\nconst UserContext = createContext<UserContextValue | null>(null);\n\nexport const useUser = () => {\n const ctx = useContext(UserContext);\n if (!ctx) throw new Error(\"useUser must be used within AdminUserLayout\");\n return ctx;\n};\n\nconst updateUserSchema = t.object({\n email: t.optional(t.email()),\n phoneNumber: t.optional(t.e164()),\n firstName: t.optional(t.string()),\n lastName: t.optional(t.string()),\n roles: t.optional(t.array(t.string())),\n enabled: t.optional(t.boolean()),\n});\n\nconst displayName = (u: UserEntity) =>\n u.firstName || u.lastName\n ? `${u.firstName ?? \"\"} ${u.lastName ?? \"\"}`.trim()\n : u.username || u.email || \"User\";\n\nconst AdminUserLayout = (props: AdminUserLayoutProps) => {\n const router = useRouter<AdminRouter>();\n const state = useRouterState();\n const client = useClient<AdminUserController>();\n const dialog = useDialog();\n const toast = useToast();\n const userId = state.params.userId as string;\n\n const [user, setUser] = useState<UserEntity | null>(null);\n const [loading, setLoading] = useState(true);\n\n const realmQuery = { userRealmName: props.userRealmName };\n\n const loadUser = useCallback(async () => {\n setLoading(true);\n try {\n const data = await client.getUser({\n params: { id: userId },\n query: realmQuery,\n });\n setUser(data);\n } finally {\n setLoading(false);\n }\n }, [userId, client]);\n\n useEffect(() => {\n loadUser();\n }, [loadUser]);\n\n const handleToggleEnabled = async () => {\n if (!user) return;\n const action = user.enabled ? \"disable\" : \"enable\";\n const confirmed = await dialog.confirm({\n title: `${user.enabled ? \"Disable\" : \"Enable\"} User`,\n message: `Are you sure you want to ${action} ${displayName(user)}?`,\n });\n if (confirmed) {\n const updated = await client.updateUser({\n params: { id: user.id },\n query: realmQuery,\n body: { enabled: !user.enabled },\n });\n setUser(updated);\n toast.success({ title: `User ${action}d` });\n }\n };\n\n const handleDelete = async () => {\n if (!user) return;\n const confirmed = await dialog.confirm({\n title: \"Delete User\",\n message: `Are you sure you want to delete ${displayName(user)}? This cannot be undone.`,\n confirmColor: \"red\",\n confirmLabel: \"Delete\",\n });\n if (confirmed) {\n await client.deleteUser({\n params: { id: user.id },\n query: realmQuery,\n });\n toast.success({ title: \"User deleted\" });\n router.push(\"adminUsers\");\n }\n };\n\n if (loading) {\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Loader />\n </Flex>\n );\n }\n\n if (!user) {\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Text c=\"dimmed\">User not found</Text>\n </Flex>\n );\n }\n\n return (\n <UserContext.Provider value={{ user, reload: loadUser }}>\n <Flex flex={1} direction=\"column\" gap=\"lg\" p=\"md\">\n <AdminResourceHeader\n backHref={router.path(\"adminUsers\")}\n backLabel=\"Users\"\n title={displayName(user)}\n subtitle={user.email || user.username}\n status={{\n label: user.enabled ? \"Active\" : \"Disabled\",\n color: user.enabled ? \"green\" : \"gray\",\n }}\n menuActions={[\n {\n label: user.enabled ? \"Disable\" : \"Enable\",\n icon: user.enabled ? IconBan : IconShieldCheck,\n onClick: handleToggleEnabled,\n },\n {\n label: \"Delete\",\n icon: IconTrash,\n color: \"red\",\n onClick: handleDelete,\n },\n ]}\n />\n\n <AdminResourceTabs\n tabs={[\n {\n value: \"profile\",\n label: \"Profile\",\n href: router.path(\"adminUserProfile\", {\n params: { userId },\n }),\n },\n {\n value: \"sessions\",\n label: \"Sessions\",\n href: router.path(\"adminUserSessions\", {\n params: { userId },\n }),\n },\n ]}\n />\n\n <NestedView />\n </Flex>\n </UserContext.Provider>\n );\n};\n\nexport default AdminUserLayout;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { f as DetailList, u as Flex$1 } from "./core-2xoLiT0o.js";
2
- import { useUser } from "./AdminUserLayout-BdC4Te8m.js";
1
+ import { d as DetailList, l as Flex$1 } from "./core-CYaRQ8O-.js";
2
+ import { useUser } from "./AdminUserLayout-lXT6I0Qq.js";
3
3
  import { useI18n } from "alepha/react/i18n";
4
4
  import { Badge } from "@mantine/core";
5
5
  import { jsx } from "react/jsx-runtime";
@@ -66,4 +66,4 @@ const AdminUserProfile = () => {
66
66
 
67
67
  //#endregion
68
68
  export { AdminUserProfile as default };
69
- //# sourceMappingURL=AdminUserProfile-DAt23fqY.js.map
69
+ //# sourceMappingURL=AdminUserProfile-vFBLoJ3h.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"AdminUserProfile-DAt23fqY.js","names":["Flex"],"sources":["../../src/admin/components/users/AdminUserProfile.tsx"],"sourcesContent":["import { DetailList, Flex } from \"@alepha/ui\";\nimport { Badge } from \"@mantine/core\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useUser } from \"./AdminUserLayout.tsx\";\n\nconst AdminUserProfile = () => {\n const { user } = useUser();\n const { l } = useI18n();\n\n return (\n <DetailList\n items={[\n { label: \"ID\", value: user.id, copyable: user.id },\n { label: \"Username\", value: user.username },\n { label: \"Email\", value: user.email },\n {\n label: \"Email Verified\",\n value: user.emailVerified ? \"Yes\" : \"No\",\n },\n { label: \"Phone\", value: user.phoneNumber },\n { label: \"First Name\", value: user.firstName },\n { label: \"Last Name\", value: user.lastName },\n { label: \"Realm\", value: user.realm },\n {\n label: \"Roles\",\n value:\n user.roles.length > 0 ? (\n <Flex gap={4}>\n {user.roles.map((role) => (\n <Badge key={role} size=\"xs\" variant=\"default\">\n {role}\n </Badge>\n ))}\n </Flex>\n ) : null,\n },\n {\n label: \"Created\",\n value: String(l(user.createdAt, { date: \"lll\" })),\n },\n {\n label: \"Updated\",\n value: String(l(user.updatedAt, { date: \"lll\" })),\n },\n ]}\n />\n );\n};\n\nexport default AdminUserProfile;\n"],"mappings":";;;;;;;AAKA,MAAM,yBAAyB;CAC7B,MAAM,EAAE,SAAS,SAAS;CAC1B,MAAM,EAAE,MAAM,SAAS;AAEvB,QACE,oBAAC,cACC,OAAO;EACL;GAAE,OAAO;GAAM,OAAO,KAAK;GAAI,UAAU,KAAK;GAAI;EAClD;GAAE,OAAO;GAAY,OAAO,KAAK;GAAU;EAC3C;GAAE,OAAO;GAAS,OAAO,KAAK;GAAO;EACrC;GACE,OAAO;GACP,OAAO,KAAK,gBAAgB,QAAQ;GACrC;EACD;GAAE,OAAO;GAAS,OAAO,KAAK;GAAa;EAC3C;GAAE,OAAO;GAAc,OAAO,KAAK;GAAW;EAC9C;GAAE,OAAO;GAAa,OAAO,KAAK;GAAU;EAC5C;GAAE,OAAO;GAAS,OAAO,KAAK;GAAO;EACrC;GACE,OAAO;GACP,OACE,KAAK,MAAM,SAAS,IAClB,oBAACA;IAAK,KAAK;cACR,KAAK,MAAM,KAAK,SACf,oBAAC;KAAiB,MAAK;KAAK,SAAQ;eACjC;OADS,KAEJ,CACR;KACG,GACL;GACP;EACD;GACE,OAAO;GACP,OAAO,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC;GAClD;EACD;GACE,OAAO;GACP,OAAO,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC;GAClD;EACF,GACD"}
1
+ {"version":3,"file":"AdminUserProfile-vFBLoJ3h.js","names":["Flex"],"sources":["../../src/admin/components/users/AdminUserProfile.tsx"],"sourcesContent":["import { DetailList, Flex } from \"@alepha/ui\";\nimport { Badge } from \"@mantine/core\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useUser } from \"./AdminUserLayout.tsx\";\n\nconst AdminUserProfile = () => {\n const { user } = useUser();\n const { l } = useI18n();\n\n return (\n <DetailList\n items={[\n { label: \"ID\", value: user.id, copyable: user.id },\n { label: \"Username\", value: user.username },\n { label: \"Email\", value: user.email },\n {\n label: \"Email Verified\",\n value: user.emailVerified ? \"Yes\" : \"No\",\n },\n { label: \"Phone\", value: user.phoneNumber },\n { label: \"First Name\", value: user.firstName },\n { label: \"Last Name\", value: user.lastName },\n { label: \"Realm\", value: user.realm },\n {\n label: \"Roles\",\n value:\n user.roles.length > 0 ? (\n <Flex gap={4}>\n {user.roles.map((role) => (\n <Badge key={role} size=\"xs\" variant=\"default\">\n {role}\n </Badge>\n ))}\n </Flex>\n ) : null,\n },\n {\n label: \"Created\",\n value: String(l(user.createdAt, { date: \"lll\" })),\n },\n {\n label: \"Updated\",\n value: String(l(user.updatedAt, { date: \"lll\" })),\n },\n ]}\n />\n );\n};\n\nexport default AdminUserProfile;\n"],"mappings":";;;;;;;AAKA,MAAM,yBAAyB;CAC7B,MAAM,EAAE,SAAS,SAAS;CAC1B,MAAM,EAAE,MAAM,SAAS;AAEvB,QACE,oBAAC,cACC,OAAO;EACL;GAAE,OAAO;GAAM,OAAO,KAAK;GAAI,UAAU,KAAK;GAAI;EAClD;GAAE,OAAO;GAAY,OAAO,KAAK;GAAU;EAC3C;GAAE,OAAO;GAAS,OAAO,KAAK;GAAO;EACrC;GACE,OAAO;GACP,OAAO,KAAK,gBAAgB,QAAQ;GACrC;EACD;GAAE,OAAO;GAAS,OAAO,KAAK;GAAa;EAC3C;GAAE,OAAO;GAAc,OAAO,KAAK;GAAW;EAC9C;GAAE,OAAO;GAAa,OAAO,KAAK;GAAU;EAC5C;GAAE,OAAO;GAAS,OAAO,KAAK;GAAO;EACrC;GACE,OAAO;GACP,OACE,KAAK,MAAM,SAAS,IAClB,oBAACA;IAAK,KAAK;cACR,KAAK,MAAM,KAAK,SACf,oBAAC;KAAiB,MAAK;KAAK,SAAQ;eACjC;OADS,KAEJ,CACR;KACG,GACL;GACP;EACD;GACE,OAAO;GACP,OAAO,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC;GAClD;EACD;GACE,OAAO;GACP,OAAO,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,OAAO,CAAC,CAAC;GAClD;EACF,GACD"}
@@ -1,6 +1,7 @@
1
- import { i as useDialog, r as DataTable, s as Text, u as Flex } from "./core-2xoLiT0o.js";
1
+ import { b as useToast, l as Flex$1, m as useDialog, r as DataTable, s as Text$1 } from "./core-CYaRQ8O-.js";
2
2
  import { t } from "alepha";
3
3
  import { useI18n } from "alepha/react/i18n";
4
+ import { Badge } from "@mantine/core";
4
5
  import { jsx, jsxs } from "react/jsx-runtime";
5
6
  import { useState } from "react";
6
7
  import { IconDeviceDesktop, IconDeviceMobile, IconDeviceTablet, IconTrash } from "@tabler/icons-react";
@@ -22,18 +23,19 @@ const AdminUserSessions = (props) => {
22
23
  const client = useClient();
23
24
  const { l } = useI18n();
24
25
  const dialog = useDialog();
26
+ const toast = useToast();
25
27
  const [refreshKey, setRefreshKey] = useState(0);
26
- const handleDeleteSession = async (sessionId) => {
27
- if (await dialog.confirm({
28
- title: "Revoke Session",
29
- message: "Are you sure you want to revoke this session?"
30
- })) {
31
- await client.deleteSession({
32
- params: { id: sessionId },
33
- query: { userRealmName: props.userRealmName }
34
- });
35
- setRefreshKey((k) => k + 1);
36
- }
28
+ const handleDeleteSession = async (session) => {
29
+ if (!await dialog.confirm({
30
+ title: "Revoke session",
31
+ message: "Are you sure you want to revoke this session? The user will be signed out on this device."
32
+ })) return;
33
+ await client.deleteSession({
34
+ params: { id: session.id },
35
+ query: { userRealmName: props.userRealmName }
36
+ });
37
+ toast.success("Session revoked");
38
+ setRefreshKey((k) => k + 1);
37
39
  };
38
40
  return /* @__PURE__ */ jsx(DataTable, {
39
41
  submitOnInit: true,
@@ -54,10 +56,10 @@ const AdminUserSessions = (props) => {
54
56
  columns: {
55
57
  device: {
56
58
  label: "Device",
57
- value: (item) => /* @__PURE__ */ jsxs(Flex, {
59
+ value: (item) => /* @__PURE__ */ jsxs(Flex$1, {
58
60
  gap: 4,
59
61
  align: "center",
60
- children: [getDeviceIcon(item.userAgent?.device), /* @__PURE__ */ jsx(Text, {
62
+ children: [getDeviceIcon(item.userAgent?.device), /* @__PURE__ */ jsx(Text$1, {
61
63
  size: "xs",
62
64
  children: item.userAgent ? `${item.userAgent.browser} / ${item.userAgent.os}` : "—"
63
65
  })]
@@ -65,45 +67,41 @@ const AdminUserSessions = (props) => {
65
67
  },
66
68
  ip: {
67
69
  label: "IP",
68
- fit: true,
69
- value: (item) => /* @__PURE__ */ jsx(Text, {
70
+ value: (item) => /* @__PURE__ */ jsx(Text$1, {
70
71
  size: "xs",
71
72
  ff: "monospace",
72
- c: "dimmed",
73
+ muted: true,
73
74
  children: item.ip || "—"
74
75
  })
75
76
  },
76
77
  status: {
77
78
  label: "Status",
78
- fit: true,
79
- value: (item) => /* @__PURE__ */ jsx(Text, {
80
- size: "xs",
81
- c: "dimmed",
79
+ value: (item) => /* @__PURE__ */ jsx(Badge, {
80
+ size: "sm",
81
+ variant: "light",
82
+ color: isExpired(item.expiresAt) ? "gray" : "green",
82
83
  children: isExpired(item.expiresAt) ? "Expired" : "Active"
83
84
  })
84
85
  },
85
86
  createdAt: {
86
87
  label: "Created",
87
- fit: true,
88
- value: (item) => /* @__PURE__ */ jsx(Text, {
88
+ value: (item) => /* @__PURE__ */ jsx(Text$1, {
89
89
  size: "xs",
90
- c: "dimmed",
90
+ muted: true,
91
91
  children: l(item.createdAt, { date: "fromNow" })
92
92
  })
93
- },
94
- actions: {
95
- label: "",
96
- fit: true,
97
- actions: (item) => [{
98
- icon: /* @__PURE__ */ jsx(IconTrash, { size: 14 }),
99
- onClick: () => handleDeleteSession(item.id),
100
- tooltip: "Revoke session"
101
- }]
102
93
  }
103
- }
94
+ },
95
+ rowActions: (item) => [{
96
+ label: "Revoke session",
97
+ icon: IconTrash,
98
+ color: "red",
99
+ onClick: () => handleDeleteSession(item),
100
+ visible: !isExpired(item.expiresAt)
101
+ }]
104
102
  }, refreshKey);
105
103
  };
106
104
 
107
105
  //#endregion
108
106
  export { AdminUserSessions as default };
109
- //# sourceMappingURL=AdminUserSessions-1uzcx02z.js.map
107
+ //# sourceMappingURL=AdminUserSessions-CT_YDim0.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AdminUserSessions-CT_YDim0.js","names":["Flex","Text"],"sources":["../../src/admin/components/users/AdminUserSessions.tsx"],"sourcesContent":["import { DataTable, Flex, Text, useDialog, useToast } from \"@alepha/ui\";\nimport { Badge } from \"@mantine/core\";\nimport {\n IconDeviceDesktop,\n IconDeviceMobile,\n IconDeviceTablet,\n IconTrash,\n} from \"@tabler/icons-react\";\nimport { type Page, t } from \"alepha\";\nimport type { AdminSessionController, SessionEntity } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouterState } from \"alepha/react/router\";\nimport { useState } from \"react\";\n\nexport interface AdminUserSessionsProps {\n userRealmName?: string;\n}\n\nconst emptyFilters = t.object({});\n\nconst getDeviceIcon = (device?: string) => {\n switch (device) {\n case \"MOBILE\":\n return <IconDeviceMobile size={14} />;\n case \"TABLET\":\n return <IconDeviceTablet size={14} />;\n default:\n return <IconDeviceDesktop size={14} />;\n }\n};\n\nconst isExpired = (expiresAt: Date | string) =>\n new Date(expiresAt) < new Date();\n\nconst AdminUserSessions = (props: AdminUserSessionsProps) => {\n const state = useRouterState();\n const userId = state.params.userId as string;\n const client = useClient<AdminSessionController>();\n const { l } = useI18n();\n const dialog = useDialog();\n const toast = useToast();\n const [refreshKey, setRefreshKey] = useState(0);\n\n const handleDeleteSession = async (session: SessionEntity) => {\n const confirmed = await dialog.confirm({\n title: \"Revoke session\",\n message:\n \"Are you sure you want to revoke this session? The user will be signed out on this device.\",\n });\n if (!confirmed) return;\n await client.deleteSession({\n params: { id: session.id },\n query: { userRealmName: props.userRealmName },\n });\n toast.success(\"Session revoked\");\n setRefreshKey((k) => k + 1);\n };\n\n return (\n <DataTable<SessionEntity, typeof emptyFilters>\n key={refreshKey}\n submitOnInit\n defaultSize={10}\n filters={emptyFilters}\n tableProps={{\n horizontalSpacing: \"xs\",\n verticalSpacing: \"xs\",\n }}\n tableTrProps={(item) => ({\n style: {\n opacity: isExpired(item.expiresAt) ? 0.5 : 1,\n },\n })}\n items={async (filters) => {\n const response = await client.findSessions({\n query: {\n ...filters,\n userId,\n userRealmName: props.userRealmName,\n },\n });\n return response as Page<SessionEntity>;\n }}\n columns={{\n device: {\n label: \"Device\",\n value: (item) => (\n <Flex gap={4} align=\"center\">\n {getDeviceIcon(item.userAgent?.device)}\n <Text size=\"xs\">\n {item.userAgent\n ? `${item.userAgent.browser} / ${item.userAgent.os}`\n : \"—\"}\n </Text>\n </Flex>\n ),\n },\n ip: {\n label: \"IP\",\n value: (item) => (\n <Text size=\"xs\" ff=\"monospace\" muted>\n {item.ip || \"—\"}\n </Text>\n ),\n },\n status: {\n label: \"Status\",\n value: (item) => (\n <Badge\n size=\"sm\"\n variant=\"light\"\n color={isExpired(item.expiresAt) ? \"gray\" : \"green\"}\n >\n {isExpired(item.expiresAt) ? \"Expired\" : \"Active\"}\n </Badge>\n ),\n },\n createdAt: {\n label: \"Created\",\n value: (item) => (\n <Text size=\"xs\" muted>\n {l(item.createdAt, { date: \"fromNow\" })}\n </Text>\n ),\n },\n }}\n rowActions={(item) => [\n {\n label: \"Revoke session\",\n icon: IconTrash,\n color: \"red\",\n onClick: () => handleDeleteSession(item),\n visible: !isExpired(item.expiresAt),\n },\n ]}\n />\n );\n};\n\nexport default AdminUserSessions;\n"],"mappings":";;;;;;;;;;;AAmBA,MAAM,eAAe,EAAE,OAAO,EAAE,CAAC;AAEjC,MAAM,iBAAiB,WAAoB;AACzC,SAAQ,QAAR;EACE,KAAK,SACH,QAAO,oBAAC,oBAAiB,MAAM,KAAM;EACvC,KAAK,SACH,QAAO,oBAAC,oBAAiB,MAAM,KAAM;EACvC,QACE,QAAO,oBAAC,qBAAkB,MAAM,KAAM;;;AAI5C,MAAM,aAAa,cACjB,IAAI,KAAK,UAAU,mBAAG,IAAI,MAAM;AAElC,MAAM,qBAAqB,UAAkC;CAE3D,MAAM,SADQ,gBAAgB,CACT,OAAO;CAC5B,MAAM,SAAS,WAAmC;CAClD,MAAM,EAAE,MAAM,SAAS;CACvB,MAAM,SAAS,WAAW;CAC1B,MAAM,QAAQ,UAAU;CACxB,MAAM,CAAC,YAAY,iBAAiB,SAAS,EAAE;CAE/C,MAAM,sBAAsB,OAAO,YAA2B;AAM5D,MAAI,CALc,MAAM,OAAO,QAAQ;GACrC,OAAO;GACP,SACE;GACH,CAAC,CACc;AAChB,QAAM,OAAO,cAAc;GACzB,QAAQ,EAAE,IAAI,QAAQ,IAAI;GAC1B,OAAO,EAAE,eAAe,MAAM,eAAe;GAC9C,CAAC;AACF,QAAM,QAAQ,kBAAkB;AAChC,iBAAe,MAAM,IAAI,EAAE;;AAG7B,QACE,oBAAC;EAEC;EACA,aAAa;EACb,SAAS;EACT,YAAY;GACV,mBAAmB;GACnB,iBAAiB;GAClB;EACD,eAAe,UAAU,EACvB,OAAO,EACL,SAAS,UAAU,KAAK,UAAU,GAAG,KAAM,GAC5C,EACF;EACD,OAAO,OAAO,YAAY;AAQxB,UAPiB,MAAM,OAAO,aAAa,EACzC,OAAO;IACL,GAAG;IACH;IACA,eAAe,MAAM;IACtB,EACF,CAAC;;EAGJ,SAAS;GACP,QAAQ;IACN,OAAO;IACP,QAAQ,SACN,qBAACA;KAAK,KAAK;KAAG,OAAM;gBACjB,cAAc,KAAK,WAAW,OAAO,EACtC,oBAACC;MAAK,MAAK;gBACR,KAAK,YACF,GAAG,KAAK,UAAU,QAAQ,KAAK,KAAK,UAAU,OAC9C;OACC;MACF;IAEV;GACD,IAAI;IACF,OAAO;IACP,QAAQ,SACN,oBAACA;KAAK,MAAK;KAAK,IAAG;KAAY;eAC5B,KAAK,MAAM;MACP;IAEV;GACD,QAAQ;IACN,OAAO;IACP,QAAQ,SACN,oBAAC;KACC,MAAK;KACL,SAAQ;KACR,OAAO,UAAU,KAAK,UAAU,GAAG,SAAS;eAE3C,UAAU,KAAK,UAAU,GAAG,YAAY;MACnC;IAEX;GACD,WAAW;IACT,OAAO;IACP,QAAQ,SACN,oBAACA;KAAK,MAAK;KAAK;eACb,EAAE,KAAK,WAAW,EAAE,MAAM,WAAW,CAAC;MAClC;IAEV;GACF;EACD,aAAa,SAAS,CACpB;GACE,OAAO;GACP,MAAM;GACN,OAAO;GACP,eAAe,oBAAoB,KAAK;GACxC,SAAS,CAAC,UAAU,KAAK,UAAU;GACpC,CACF;IA1EI,WA2EL"}