@alepha/ui 0.18.2 → 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 (231) hide show
  1. package/dist/admin/{AdminApiKeys-BJhIwfD6.js → AdminApiKeys-Dy_k-4Vd.js} +2 -2
  2. package/dist/admin/{AdminApiKeys-BJhIwfD6.js.map → AdminApiKeys-Dy_k-4Vd.js.map} +1 -1
  3. package/dist/admin/{AdminAudits-DzD_4cDt.js → AdminAudits-CKiFMSSU.js} +2 -2
  4. package/dist/admin/{AdminAudits-DzD_4cDt.js.map → AdminAudits-CKiFMSSU.js.map} +1 -1
  5. package/dist/admin/{AdminDashboard-C92tIc6x.js → AdminDashboard-PhC_dZqo.js} +2 -2
  6. package/dist/admin/{AdminDashboard-C92tIc6x.js.map → AdminDashboard-PhC_dZqo.js.map} +1 -1
  7. package/dist/admin/{AdminFiles-DLpfhBkf.js → AdminFiles-DFTjijGp.js} +2 -2
  8. package/dist/admin/{AdminFiles-DLpfhBkf.js.map → AdminFiles-DFTjijGp.js.map} +1 -1
  9. package/dist/admin/{AdminJobDashboard-KIOkeMgE.js → AdminJobDashboard-BL8gGPDp.js} +2 -2
  10. package/dist/admin/{AdminJobDashboard-KIOkeMgE.js.map → AdminJobDashboard-BL8gGPDp.js.map} +1 -1
  11. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js → AdminJobExecutions-D9E-CS-U.js} +2 -2
  12. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js.map → AdminJobExecutions-D9E-CS-U.js.map} +1 -1
  13. package/dist/admin/{AdminJobRegistry-PFajqaGK.js → AdminJobRegistry-Ci9ue1zC.js} +2 -2
  14. package/dist/admin/{AdminJobRegistry-PFajqaGK.js.map → AdminJobRegistry-Ci9ue1zC.js.map} +1 -1
  15. package/dist/admin/{AdminLayout-B1DXZHDn.js → AdminLayout-I6TlUMPc.js} +2 -2
  16. package/dist/admin/{AdminLayout-B1DXZHDn.js.map → AdminLayout-I6TlUMPc.js.map} +1 -1
  17. package/dist/admin/AdminNotifications-ZPHCYrv7.js +542 -0
  18. package/dist/admin/AdminNotifications-ZPHCYrv7.js.map +1 -0
  19. package/dist/admin/{AdminParameters-BspPeqp_.js → AdminParameters-CqgvhRsb.js} +120 -105
  20. package/dist/admin/AdminParameters-CqgvhRsb.js.map +1 -0
  21. package/dist/admin/{AdminSessions-BnH5CZQl.js → AdminSessions-Bz5NRuoW.js} +2 -2
  22. package/dist/admin/{AdminSessions-BnH5CZQl.js.map → AdminSessions-Bz5NRuoW.js.map} +1 -1
  23. package/dist/admin/{AdminUserLayout-DUbC6-BI.js → AdminUserLayout-lXT6I0Qq.js} +14 -8
  24. package/dist/admin/AdminUserLayout-lXT6I0Qq.js.map +1 -0
  25. package/dist/admin/{AdminUserProfile-DuTUnjdG.js → AdminUserProfile-vFBLoJ3h.js} +3 -3
  26. package/dist/admin/{AdminUserProfile-DuTUnjdG.js.map → AdminUserProfile-vFBLoJ3h.js.map} +1 -1
  27. package/dist/admin/{AdminUserSessions-DvZdAGpL.js → AdminUserSessions-CT_YDim0.js} +2 -2
  28. package/dist/admin/{AdminUserSessions-DvZdAGpL.js.map → AdminUserSessions-CT_YDim0.js.map} +1 -1
  29. package/dist/admin/{AdminUsers-CR9z0g_5.js → AdminUsers-D1UfGya9.js} +2 -2
  30. package/dist/admin/{AdminUsers-CR9z0g_5.js.map → AdminUsers-D1UfGya9.js.map} +1 -1
  31. package/dist/admin/{AuthLayout-DsUfp9RG.js → AuthLayout-_frhdgOO.js} +2 -2
  32. package/dist/admin/{AuthLayout-DsUfp9RG.js.map → AuthLayout-_frhdgOO.js.map} +1 -1
  33. package/dist/admin/Login-xtNmQtGh.js +275 -0
  34. package/dist/admin/Login-xtNmQtGh.js.map +1 -0
  35. package/dist/admin/{Profile-B2EcIDB9.js → Profile-_AtPUwAP.js} +31 -27
  36. package/dist/admin/Profile-_AtPUwAP.js.map +1 -0
  37. package/dist/admin/{Register-Z3fxRbUF.js → Register-JcCjHUUn.js} +198 -142
  38. package/dist/admin/Register-JcCjHUUn.js.map +1 -0
  39. package/dist/admin/{ResetPassword-_Y1qTTKh.js → ResetPassword-CwGBPLJO.js} +7 -7
  40. package/dist/admin/ResetPassword-CwGBPLJO.js.map +1 -0
  41. package/dist/admin/{VerifyEmail-Bg22bwcC.js → VerifyEmail-hNxWejWf.js} +23 -8
  42. package/dist/admin/VerifyEmail-hNxWejWf.js.map +1 -0
  43. package/dist/admin/{core-BVO_TQxb.js → core-CYaRQ8O-.js} +709 -556
  44. package/dist/admin/core-CYaRQ8O-.js.map +1 -0
  45. package/dist/admin/index.d.ts +83 -44
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +58 -39
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/auth/{AuthLayout-C161NeF6.js → AuthLayout-AvLlcLjS.js} +2 -2
  50. package/dist/auth/{AuthLayout-C161NeF6.js.map → AuthLayout-AvLlcLjS.js.map} +1 -1
  51. package/dist/auth/Login-BA1E8IZl.js +275 -0
  52. package/dist/auth/Login-BA1E8IZl.js.map +1 -0
  53. package/dist/auth/{Profile-BMpXJ0oi.js → Profile-YcWdeuFz.js} +31 -27
  54. package/dist/auth/Profile-YcWdeuFz.js.map +1 -0
  55. package/dist/auth/{Register-2gx8qll-.js → Register-CPhEO5MG.js} +198 -142
  56. package/dist/auth/Register-CPhEO5MG.js.map +1 -0
  57. package/dist/{demo/ResetPassword-CAPj8MO3.js → auth/ResetPassword-DCtGcneA.js} +7 -7
  58. package/dist/auth/ResetPassword-DCtGcneA.js.map +1 -0
  59. package/dist/{demo/VerifyEmail-DFmdCdYs.js → auth/VerifyEmail-DkH7NBfn.js} +23 -8
  60. package/dist/auth/VerifyEmail-DkH7NBfn.js.map +1 -0
  61. package/dist/auth/{core-DyfeVr5c.js → core-D5jIAVF2.js} +386 -294
  62. package/dist/auth/core-D5jIAVF2.js.map +1 -0
  63. package/dist/auth/index.d.ts +93 -48
  64. package/dist/auth/index.d.ts.map +1 -1
  65. package/dist/auth/index.js +28 -24
  66. package/dist/auth/index.js.map +1 -1
  67. package/dist/core/index.d.ts +116 -61
  68. package/dist/core/index.d.ts.map +1 -1
  69. package/dist/core/index.js +873 -701
  70. package/dist/core/index.js.map +1 -1
  71. package/dist/demo/{AuthLayout-DN-ClJQk.js → AuthLayout-Brri4A-L.js} +2 -2
  72. package/dist/demo/{AuthLayout-DN-ClJQk.js.map → AuthLayout-Brri4A-L.js.map} +1 -1
  73. package/dist/demo/DemoButton-wiCxZZ_L.js +182 -0
  74. package/dist/demo/DemoButton-wiCxZZ_L.js.map +1 -0
  75. package/dist/demo/DemoControlSelect-D7ILObVg.js +305 -0
  76. package/dist/demo/DemoControlSelect-D7ILObVg.js.map +1 -0
  77. package/dist/demo/DemoDataTable-DZ5Y8pFX.js +362 -0
  78. package/dist/demo/DemoDataTable-DZ5Y8pFX.js.map +1 -0
  79. package/dist/demo/{DemoDialog-DW8QEvD1.js → DemoDialog-CUWdLHim.js} +2 -2
  80. package/dist/demo/{DemoDialog-DW8QEvD1.js.map → DemoDialog-CUWdLHim.js.map} +1 -1
  81. package/dist/demo/{DemoFlex-CAhLUanT.js → DemoFlex-a8OhMMvq.js} +3 -3
  82. package/dist/demo/{DemoFlex-CAhLUanT.js.map → DemoFlex-a8OhMMvq.js.map} +1 -1
  83. package/dist/demo/{DemoHeading-yIFmNjHB.js → DemoHeading-C13OVDfS.js} +3 -3
  84. package/dist/demo/{DemoHeading-yIFmNjHB.js.map → DemoHeading-C13OVDfS.js.map} +1 -1
  85. package/dist/demo/{DemoHome-BSGuBHus.js → DemoHome-D_De3UiT.js} +2 -2
  86. package/dist/demo/{DemoHome-BSGuBHus.js.map → DemoHome-D_De3UiT.js.map} +1 -1
  87. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js → DemoJsonViewer-B50s9aGM.js} +3 -3
  88. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js.map → DemoJsonViewer-B50s9aGM.js.map} +1 -1
  89. package/dist/demo/{DemoLayout-Cy6xjn6P.js → DemoLayout-CHU8WTwO.js} +14 -5
  90. package/dist/demo/DemoLayout-CHU8WTwO.js.map +1 -0
  91. package/dist/demo/{DemoLogin-vqxgTu4P.js → DemoLogin-BBlrWpml.js} +49 -32
  92. package/dist/demo/DemoLogin-BBlrWpml.js.map +1 -0
  93. package/dist/demo/{DemoRegister-YHPvPg77.js → DemoRegister-BuNE3_-f.js} +49 -50
  94. package/dist/demo/DemoRegister-BuNE3_-f.js.map +1 -0
  95. package/dist/demo/{DemoResetPassword-mOW18Zlm.js → DemoResetPassword-D_IjjjOJ.js} +12 -16
  96. package/dist/demo/DemoResetPassword-D_IjjjOJ.js.map +1 -0
  97. package/dist/demo/{DemoSidebar-od7aLjP_.js → DemoSidebar-Giy2HRBD.js} +3 -3
  98. package/dist/demo/{DemoSidebar-od7aLjP_.js.map → DemoSidebar-Giy2HRBD.js.map} +1 -1
  99. package/dist/demo/{DemoText-DU3JeRS0.js → DemoText-ubcw-vog.js} +3 -3
  100. package/dist/demo/{DemoText-DU3JeRS0.js.map → DemoText-ubcw-vog.js.map} +1 -1
  101. package/dist/demo/{DemoToast-CUJEiPRa.js → DemoToast-9die_dYT.js} +2 -2
  102. package/dist/demo/{DemoToast-CUJEiPRa.js.map → DemoToast-9die_dYT.js.map} +1 -1
  103. package/dist/demo/{DemoTypeForm-C1dNkahD.js → DemoTypeForm-D_d6OVKL.js} +8 -4
  104. package/dist/demo/DemoTypeForm-D_d6OVKL.js.map +1 -0
  105. package/dist/demo/DemoVerifyEmail-B43KlF4F.js +34 -0
  106. package/dist/demo/DemoVerifyEmail-B43KlF4F.js.map +1 -0
  107. package/dist/demo/Login-C12N4oGs.js +275 -0
  108. package/dist/demo/Login-C12N4oGs.js.map +1 -0
  109. package/dist/demo/{Profile-BE_Y3co2.js → Profile-DS5q4vOh.js} +31 -27
  110. package/dist/demo/Profile-DS5q4vOh.js.map +1 -0
  111. package/dist/demo/{Register-fXHmBpr3.js → Register-B4hLBeEv.js} +198 -142
  112. package/dist/demo/Register-B4hLBeEv.js.map +1 -0
  113. package/dist/{auth/ResetPassword-DBxt9hKk.js → demo/ResetPassword-D8g9ha1N.js} +7 -7
  114. package/dist/demo/ResetPassword-D8g9ha1N.js.map +1 -0
  115. package/dist/demo/{Showcase-BtEU0pY9.js → Showcase-D6Fxt4X4.js} +64 -65
  116. package/dist/demo/Showcase-D6Fxt4X4.js.map +1 -0
  117. package/dist/{auth/VerifyEmail-Z80Ubajk.js → demo/VerifyEmail-BjDo0cZA.js} +23 -8
  118. package/dist/demo/VerifyEmail-BjDo0cZA.js.map +1 -0
  119. package/dist/demo/{auth-Djd7SKiw.js → auth-ByVTreDl.js} +8 -8
  120. package/dist/demo/{auth-Djd7SKiw.js.map → auth-ByVTreDl.js.map} +1 -1
  121. package/dist/demo/{core-B7LNjM78.js → core-DFgB3yU4.js} +741 -573
  122. package/dist/demo/core-DFgB3yU4.js.map +1 -0
  123. package/dist/demo/index.d.ts +1 -0
  124. package/dist/demo/index.d.ts.map +1 -1
  125. package/dist/demo/index.js +24 -18
  126. package/dist/demo/index.js.map +1 -1
  127. package/package.json +7 -7
  128. package/src/admin/AdminRouter.tsx +24 -1
  129. package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
  130. package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
  131. package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
  132. package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
  133. package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
  134. package/src/admin/components/parameters/ParameterTree.tsx +28 -184
  135. package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
  136. package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
  137. package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
  138. package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
  139. package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
  140. package/src/auth/components/Login.tsx +188 -121
  141. package/src/auth/components/Profile.tsx +1 -22
  142. package/src/auth/components/ProfileField.tsx +39 -0
  143. package/src/auth/components/Register.tsx +215 -158
  144. package/src/auth/components/ResetPassword.tsx +7 -11
  145. package/src/auth/components/VerifyEmail.tsx +35 -10
  146. package/src/auth/components/buttons/UserButton.tsx +19 -21
  147. package/src/auth/index.ts +1 -0
  148. package/src/core/components/Flex.tsx +10 -0
  149. package/src/core/components/buttons/ActionButton.tsx +104 -78
  150. package/src/core/components/data/DetailDrawer.tsx +102 -96
  151. package/src/core/components/data/DetailList.tsx +2 -1
  152. package/src/core/components/layout/Breadcrumb.tsx +3 -6
  153. package/src/core/components/layout/DashboardShell.tsx +18 -4
  154. package/src/core/components/layout/Sidebar.tsx +16 -241
  155. package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
  156. package/src/core/components/layout/SidebarItem.tsx +146 -0
  157. package/src/core/components/layout/index.ts +3 -1
  158. package/src/core/form/components/Control.tsx +31 -29
  159. package/src/core/form/components/ControlArray.tsx +13 -39
  160. package/src/core/form/components/ControlDate.tsx +10 -21
  161. package/src/core/form/components/ControlNumber.tsx +4 -33
  162. package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
  163. package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
  164. package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
  165. package/src/core/form/components/ControlSelect.tsx +294 -92
  166. package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
  167. package/src/core/form/components/TypeForm.tsx +5 -2
  168. package/src/core/form/index.ts +8 -1
  169. package/src/core/form/utils/parseInput.ts +7 -3
  170. package/src/core/index.ts +3 -1
  171. package/src/core/json/components/JsonViewer.tsx +103 -319
  172. package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
  173. package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
  174. package/src/core/json/components/JsonViewerShared.ts +76 -0
  175. package/src/core/styles.css +12 -2
  176. package/src/core/table/components/ColumnPicker.tsx +3 -3
  177. package/src/core/table/components/DataTable.tsx +89 -29
  178. package/src/core/table/components/DataTableFilters.tsx +6 -11
  179. package/src/core/table/components/DataTablePagination.tsx +9 -3
  180. package/src/core/table/components/DataTableToolbar.tsx +7 -3
  181. package/src/core/table/components/FilterPicker.tsx +3 -3
  182. package/src/core/table/interfaces/types.ts +29 -0
  183. package/src/core/utils/icons.tsx +2 -2
  184. package/src/demo/DemoRouter.ts +8 -1
  185. package/src/demo/components/DemoLayout.tsx +12 -2
  186. package/src/demo/components/auth/DemoLogin.tsx +35 -28
  187. package/src/demo/components/auth/DemoRegister.tsx +35 -49
  188. package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
  189. package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
  190. package/src/demo/components/core/DemoButton.tsx +123 -103
  191. package/src/demo/components/core/DemoControlSelect.tsx +325 -0
  192. package/src/demo/components/core/DemoDataTable.tsx +255 -237
  193. package/src/demo/components/core/DemoTypeForm.tsx +7 -2
  194. package/src/demo/components/shared/MacWindow.tsx +5 -11
  195. package/src/demo/components/shared/Showcase.tsx +28 -42
  196. package/dist/admin/AdminParameters-BspPeqp_.js.map +0 -1
  197. package/dist/admin/AdminUserLayout-DUbC6-BI.js.map +0 -1
  198. package/dist/admin/Login-DHbYJKwg.js +0 -219
  199. package/dist/admin/Login-DHbYJKwg.js.map +0 -1
  200. package/dist/admin/Profile-B2EcIDB9.js.map +0 -1
  201. package/dist/admin/Register-Z3fxRbUF.js.map +0 -1
  202. package/dist/admin/ResetPassword-_Y1qTTKh.js.map +0 -1
  203. package/dist/admin/VerifyEmail-Bg22bwcC.js.map +0 -1
  204. package/dist/admin/core-BVO_TQxb.js.map +0 -1
  205. package/dist/auth/Login-C7jIqf00.js +0 -219
  206. package/dist/auth/Login-C7jIqf00.js.map +0 -1
  207. package/dist/auth/Profile-BMpXJ0oi.js.map +0 -1
  208. package/dist/auth/Register-2gx8qll-.js.map +0 -1
  209. package/dist/auth/ResetPassword-DBxt9hKk.js.map +0 -1
  210. package/dist/auth/VerifyEmail-Z80Ubajk.js.map +0 -1
  211. package/dist/auth/core-DyfeVr5c.js.map +0 -1
  212. package/dist/demo/DemoButton-CGUyR9eM.js +0 -178
  213. package/dist/demo/DemoButton-CGUyR9eM.js.map +0 -1
  214. package/dist/demo/DemoDataTable-QFG-xXSx.js +0 -358
  215. package/dist/demo/DemoDataTable-QFG-xXSx.js.map +0 -1
  216. package/dist/demo/DemoLayout-Cy6xjn6P.js.map +0 -1
  217. package/dist/demo/DemoLogin-vqxgTu4P.js.map +0 -1
  218. package/dist/demo/DemoRegister-YHPvPg77.js.map +0 -1
  219. package/dist/demo/DemoResetPassword-mOW18Zlm.js.map +0 -1
  220. package/dist/demo/DemoTypeForm-C1dNkahD.js.map +0 -1
  221. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js +0 -30
  222. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js.map +0 -1
  223. package/dist/demo/Login-CoYf_P_F.js +0 -219
  224. package/dist/demo/Login-CoYf_P_F.js.map +0 -1
  225. package/dist/demo/Profile-BE_Y3co2.js.map +0 -1
  226. package/dist/demo/Register-fXHmBpr3.js.map +0 -1
  227. package/dist/demo/ResetPassword-CAPj8MO3.js.map +0 -1
  228. package/dist/demo/Showcase-BtEU0pY9.js.map +0 -1
  229. package/dist/demo/VerifyEmail-DFmdCdYs.js.map +0 -1
  230. package/dist/demo/core-B7LNjM78.js.map +0 -1
  231. package/src/demo/styles.css +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Profile-YcWdeuFz.js","names":[],"sources":["../../src/auth/components/ProfileField.tsx","../../src/auth/components/Profile.tsx"],"sourcesContent":["import { Flex, Text } from \"@mantine/core\";\nimport type { ReactNode } from \"react\";\n\nexport interface ProfileFieldProps {\n /**\n * Icon to display\n */\n icon: ReactNode;\n\n /**\n * Field label\n */\n label: string;\n\n /**\n * Field content\n */\n children: ReactNode;\n}\n\nconst ProfileField = (props: ProfileFieldProps) => {\n const { icon, label, children } = props;\n\n return (\n <Flex gap=\"sm\" align=\"flex-start\">\n <Flex c=\"dimmed\" mt={2}>\n {icon}\n </Flex>\n <Flex direction=\"column\" gap={2} flex={1}>\n <Text size=\"xs\" c=\"dimmed\" tt=\"uppercase\" fw={500}>\n {label}\n </Text>\n <Text size=\"sm\">{children}</Text>\n </Flex>\n </Flex>\n );\n};\n\nexport default ProfileField;\n","import { ActionButton } from \"@alepha/ui\";\nimport { Avatar, Badge, Card, Flex, Text, Title } from \"@mantine/core\";\nimport {\n IconAt,\n IconCalendar,\n IconId,\n IconShield,\n IconUser,\n} from \"@tabler/icons-react\";\nimport { useAuth } from \"alepha/react/auth\";\nimport { useRouter } from \"alepha/react/router\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\nimport ProfileField from \"./ProfileField.tsx\";\n\nconst Profile = () => {\n const auth = useAuth();\n const router = useRouter<AuthRouter>();\n\n if (!auth.user) {\n return null;\n }\n\n const { id, name, email, username, picture, roles, organizations } =\n auth.user;\n\n const displayName = name || username || email || \"User\";\n\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Flex direction=\"column\" gap=\"md\" w={400}>\n <Card withBorder p=\"xl\" bg=\"var(--alepha-elevated)\">\n <Flex direction=\"column\" gap=\"lg\">\n {/* Avatar and name */}\n <Flex direction=\"column\" align=\"center\" gap=\"md\">\n <Avatar\n src={picture ? `/api/files/${picture}` : undefined}\n size={96}\n radius=\"xl\"\n color=\"blue\"\n >\n {!picture && <IconUser size={48} />}\n </Avatar>\n <Flex direction=\"column\" gap={4} align=\"center\">\n <Title order={3}>{displayName}</Title>\n {email && username && (\n <Text size=\"sm\" c=\"dimmed\">\n @{username}\n </Text>\n )}\n </Flex>\n </Flex>\n\n {/* User details */}\n <Flex direction=\"column\" gap=\"sm\">\n {email && (\n <ProfileField icon={<IconAt size={18} />} label=\"Email\">\n {email}\n </ProfileField>\n )}\n\n {username && (\n <ProfileField icon={<IconUser size={18} />} label=\"Username\">\n {username}\n </ProfileField>\n )}\n\n {id && (\n <ProfileField icon={<IconId size={18} />} label=\"User ID\">\n <Text size=\"xs\" c=\"dimmed\" ff=\"monospace\">\n {id}\n </Text>\n </ProfileField>\n )}\n\n {/* Roles */}\n {roles && roles.length > 0 && (\n <ProfileField icon={<IconShield size={18} />} label=\"Roles\">\n <Flex gap=\"xs\">\n {roles.map((role) => (\n <Badge key={role} size=\"sm\" variant=\"light\">\n {role}\n </Badge>\n ))}\n </Flex>\n </ProfileField>\n )}\n\n {/* Organizations */}\n {organizations && organizations.length > 0 && (\n <ProfileField\n icon={<IconCalendar size={18} />}\n label=\"Organizations\"\n >\n <Flex gap=\"xs\">\n {organizations.map((org) => (\n <Badge key={org} size=\"sm\" variant=\"outline\">\n {org}\n </Badge>\n ))}\n </Flex>\n </ProfileField>\n )}\n </Flex>\n\n {/* Actions */}\n <Flex direction=\"column\" gap=\"sm\" mt=\"md\">\n <ActionButton\n variant=\"light\"\n color=\"red\"\n onClick={() => auth.logout()}\n fullWidth\n >\n Sign out\n </ActionButton>\n </Flex>\n </Flex>\n </Card>\n\n <ActionButton variant=\"subtle\" href=\"/\">\n Back to home\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default Profile;\n"],"mappings":";;;;;;;;AAoBA,MAAM,gBAAgB,UAA6B;CACjD,MAAM,EAAE,MAAM,OAAO,aAAa;AAElC,QACE,qBAAC;EAAK,KAAI;EAAK,OAAM;aACnB,oBAAC;GAAK,GAAE;GAAS,IAAI;aAClB;IACI,EACP,qBAAC;GAAK,WAAU;GAAS,KAAK;GAAG,MAAM;cACrC,oBAAC;IAAK,MAAK;IAAK,GAAE;IAAS,IAAG;IAAY,IAAI;cAC3C;KACI,EACP,oBAAC;IAAK,MAAK;IAAM;KAAgB;IAC5B;GACF;;;;;ACpBX,MAAM,gBAAgB;CACpB,MAAM,OAAO,SAAS;AACP,YAAuB;AAEtC,KAAI,CAAC,KAAK,KACR,QAAO;CAGT,MAAM,EAAE,IAAI,MAAM,OAAO,UAAU,SAAS,OAAO,kBACjD,KAAK;CAEP,MAAM,cAAc,QAAQ,YAAY,SAAS;AAEjD,QACE,oBAAC;EAAK,MAAM;EAAG,SAAQ;EAAS,OAAM;YACpC,qBAAC;GAAK,WAAU;GAAS,KAAI;GAAK,GAAG;cACnC,oBAAC;IAAK;IAAW,GAAE;IAAK,IAAG;cACzB,qBAAC;KAAK,WAAU;KAAS,KAAI;;MAE3B,qBAAC;OAAK,WAAU;OAAS,OAAM;OAAS,KAAI;kBAC1C,oBAAC;QACC,KAAK,UAAU,cAAc,YAAY;QACzC,MAAM;QACN,QAAO;QACP,OAAM;kBAEL,CAAC,WAAW,oBAAC,YAAS,MAAM,KAAM;SAC5B,EACT,qBAAC;QAAK,WAAU;QAAS,KAAK;QAAG,OAAM;mBACrC,oBAAC;SAAM,OAAO;mBAAI;UAAoB,EACrC,SAAS,YACR,qBAAC;SAAK,MAAK;SAAK,GAAE;oBAAS,KACvB;UACG;SAEJ;QACF;MAGP,qBAAC;OAAK,WAAU;OAAS,KAAI;;QAC1B,SACC,oBAAC;SAAa,MAAM,oBAAC,UAAO,MAAM,KAAM;SAAE,OAAM;mBAC7C;UACY;QAGhB,YACC,oBAAC;SAAa,MAAM,oBAAC,YAAS,MAAM,KAAM;SAAE,OAAM;mBAC/C;UACY;QAGhB,MACC,oBAAC;SAAa,MAAM,oBAAC,UAAO,MAAM,KAAM;SAAE,OAAM;mBAC9C,oBAAC;UAAK,MAAK;UAAK,GAAE;UAAS,IAAG;oBAC3B;WACI;UACM;QAIhB,SAAS,MAAM,SAAS,KACvB,oBAAC;SAAa,MAAM,oBAAC,cAAW,MAAM,KAAM;SAAE,OAAM;mBAClD,oBAAC;UAAK,KAAI;oBACP,MAAM,KAAK,SACV,oBAAC;WAAiB,MAAK;WAAK,SAAQ;qBACjC;aADS,KAEJ,CACR;WACG;UACM;QAIhB,iBAAiB,cAAc,SAAS,KACvC,oBAAC;SACC,MAAM,oBAAC,gBAAa,MAAM,KAAM;SAChC,OAAM;mBAEN,oBAAC;UAAK,KAAI;oBACP,cAAc,KAAK,QAClB,oBAAC;WAAgB,MAAK;WAAK,SAAQ;qBAChC;aADS,IAEJ,CACR;WACG;UACM;;QAEZ;MAGP,oBAAC;OAAK,WAAU;OAAS,KAAI;OAAK,IAAG;iBACnC,oBAAC;QACC,SAAQ;QACR,OAAM;QACN,eAAe,KAAK,QAAQ;QAC5B;kBACD;SAEc;QACV;;MACF;KACF,EAEP,oBAAC;IAAa,SAAQ;IAAS,MAAK;cAAI;KAEzB;IACV;GACF"}
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { i as ActionButton, n as capitalize, r as Control } from "./core-DyfeVr5c.js";
2
+ import { i as ActionButton, n as capitalize, r as Control } from "./core-D5jIAVF2.js";
3
3
  import { n as IconGithub, t as IconGoogle } from "./IconGoogle-Ch1m3Uzl.js";
4
4
  import { TypeBoxError, t } from "alepha";
5
5
  import { useForm } from "alepha/react/form";
@@ -7,7 +7,7 @@ import { useI18n } from "alepha/react/i18n";
7
7
  import { Alert, Card, Flex, Image, PinInput, Text, Title } from "@mantine/core";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { useMemo, useState } from "react";
10
- import { IconAlertCircle, IconLock, IconMail, IconPhone, IconUser } from "@tabler/icons-react";
10
+ import { IconAlertCircle, IconLock, IconMail, IconPhone, IconPhoto, IconUser } from "@tabler/icons-react";
11
11
  import { useRouter } from "alepha/react/router";
12
12
  import { useClient } from "alepha/react";
13
13
  import { useAuth } from "alepha/react/auth";
@@ -41,9 +41,9 @@ const Register = (props) => {
41
41
  confirmPassword: t.string({ minLength: 8 })
42
42
  });
43
43
  const required = registerSchema.required;
44
- if (settings.usernameRequired) required.push("username");
45
- if (settings.emailRequired) required.push("email");
46
- if (settings.phoneRequired) required.push("phoneNumber");
44
+ if (settings.username === "required") required.push("username");
45
+ if (settings.email === "required") required.push("email");
46
+ if (settings.phoneNumber === "required") required.push("phoneNumber");
47
47
  return registerSchema;
48
48
  }, []),
49
49
  handler: async (data) => {
@@ -209,6 +209,197 @@ const Register = (props) => {
209
209
  });
210
210
  const externalMethods = props.realmConfig.authenticationMethods.filter((method) => method.type !== "CREDENTIALS");
211
211
  const showOrDivider = credentialsProvider && externalMethods.length > 0;
212
+ const realmQuery = props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : "";
213
+ const formContent = /* @__PURE__ */ jsxs(Flex, {
214
+ direction: "column",
215
+ gap: "md",
216
+ children: [(settings.logoUrl || settings.displayName || settings.description) && /* @__PURE__ */ jsxs(Flex, {
217
+ direction: "column",
218
+ gap: "xs",
219
+ align: "center",
220
+ mb: "xs",
221
+ children: [
222
+ settings.logoUrl && /* @__PURE__ */ jsx(Image, {
223
+ src: settings.logoUrl,
224
+ alt: settings.displayName || props.realmConfig.realmName,
225
+ h: 48,
226
+ w: "auto",
227
+ fit: "contain"
228
+ }),
229
+ settings.displayName && /* @__PURE__ */ jsx(Title, {
230
+ order: 4,
231
+ ta: "center",
232
+ children: settings.displayName
233
+ }),
234
+ settings.description && /* @__PURE__ */ jsx(Text, {
235
+ size: "sm",
236
+ c: "dimmed",
237
+ ta: "center",
238
+ children: settings.description
239
+ })
240
+ ]
241
+ }), !isRegistrationAllowed ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Alert, {
242
+ variant: "light",
243
+ color: "yellow",
244
+ icon: /* @__PURE__ */ jsx(IconAlertCircle, {}),
245
+ children: /* @__PURE__ */ jsx(Text, {
246
+ size: "sm",
247
+ children: tr("registerDisabled")
248
+ })
249
+ }), /* @__PURE__ */ jsx(ActionButton, {
250
+ href: `${props.loginPath ?? "/auth/login"}${realmQuery}`,
251
+ children: tr("registerBackToSignIn")
252
+ })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
253
+ credentialsProvider && /* @__PURE__ */ jsx("form", {
254
+ ...form.props,
255
+ children: /* @__PURE__ */ jsxs(Flex, {
256
+ direction: "column",
257
+ flex: 1,
258
+ gap: "md",
259
+ children: [
260
+ settings.username !== "none" && form.input.username && /* @__PURE__ */ jsx(Control, {
261
+ label: tr("registerUsername"),
262
+ input: form.input.username,
263
+ icon: /* @__PURE__ */ jsx(IconUser, {}),
264
+ text: { autoComplete: "username" }
265
+ }),
266
+ settings.email !== "none" && form.input.email && /* @__PURE__ */ jsx(Control, {
267
+ label: tr("registerEmail"),
268
+ input: form.input.email,
269
+ icon: /* @__PURE__ */ jsx(IconMail, {}),
270
+ text: { autoComplete: "email" }
271
+ }),
272
+ settings.phoneNumber !== "none" && form.input.phoneNumber && /* @__PURE__ */ jsx(Control, {
273
+ label: tr("registerPhone"),
274
+ input: form.input.phoneNumber,
275
+ icon: /* @__PURE__ */ jsx(IconPhone, {}),
276
+ text: { autoComplete: "tel" }
277
+ }),
278
+ /* @__PURE__ */ jsx(Control, {
279
+ label: tr("registerPassword"),
280
+ input: form.input.password,
281
+ icon: /* @__PURE__ */ jsx(IconLock, {}),
282
+ password: { autoComplete: "new-password" }
283
+ }),
284
+ /* @__PURE__ */ jsx(Control, {
285
+ label: tr("registerConfirmPassword"),
286
+ input: form.input.confirmPassword,
287
+ icon: /* @__PURE__ */ jsx(IconLock, {}),
288
+ password: { autoComplete: "new-password" }
289
+ }),
290
+ /* @__PURE__ */ jsx(ActionButton, {
291
+ form,
292
+ color: "blue",
293
+ variant: "filled",
294
+ children: tr("registerCreateAccount")
295
+ })
296
+ ]
297
+ })
298
+ }),
299
+ showOrDivider && /* @__PURE__ */ jsxs(Flex, {
300
+ align: "center",
301
+ justify: "center",
302
+ gap: "md",
303
+ children: [
304
+ /* @__PURE__ */ jsx(Flex, {
305
+ flex: 1,
306
+ h: "1px",
307
+ bg: "var(--alepha-border)"
308
+ }),
309
+ /* @__PURE__ */ jsx(Text, {
310
+ size: "xs",
311
+ c: "dimmed",
312
+ children: tr("registerOr")
313
+ }),
314
+ /* @__PURE__ */ jsx(Flex, {
315
+ flex: 1,
316
+ h: "1px",
317
+ bg: "var(--alepha-border)"
318
+ })
319
+ ]
320
+ }),
321
+ externalMethods.length > 0 && /* @__PURE__ */ jsx(Flex, {
322
+ direction: "column",
323
+ gap: "sm",
324
+ children: externalMethods.map((method) => /* @__PURE__ */ jsx(ActionButton, {
325
+ variant: "default",
326
+ leftSection: leftSection(method.name.toLowerCase()),
327
+ onClick: () => auth.login(method.name, {
328
+ redirect,
329
+ realm: props.realmConfig.realmName
330
+ }),
331
+ children: tr("registerContinueWith", { args: [capitalize(method.name)] })
332
+ }, method.type))
333
+ }),
334
+ /* @__PURE__ */ jsxs(Text, {
335
+ size: "sm",
336
+ ta: "center",
337
+ children: [
338
+ tr("registerHaveAccount"),
339
+ " ",
340
+ /* @__PURE__ */ jsx(ActionButton, {
341
+ href: `${props.loginPath ?? "/auth/login"}${realmQuery}`,
342
+ anchorProps: { inherit: true },
343
+ children: tr("registerSignIn")
344
+ })
345
+ ]
346
+ })
347
+ ] })]
348
+ });
349
+ if (props.variant === "split") return /* @__PURE__ */ jsx(Flex, {
350
+ flex: 1,
351
+ justify: "center",
352
+ align: "center",
353
+ children: /* @__PURE__ */ jsx(Card, {
354
+ withBorder: true,
355
+ p: 0,
356
+ w: 720,
357
+ bg: "var(--alepha-elevated)",
358
+ style: { overflow: "hidden" },
359
+ children: /* @__PURE__ */ jsxs(Flex, {
360
+ mih: 480,
361
+ children: [props.image ? /* @__PURE__ */ jsx(Flex, {
362
+ flex: 1,
363
+ style: {
364
+ backgroundImage: `url(${props.image})`,
365
+ backgroundSize: "cover",
366
+ backgroundPosition: "center"
367
+ }
368
+ }) : /* @__PURE__ */ jsx(Flex, {
369
+ flex: 1,
370
+ justify: "center",
371
+ align: "center",
372
+ bg: "var(--mantine-color-gray-light)",
373
+ style: { borderRight: "1px solid var(--mantine-color-default-border)" },
374
+ children: /* @__PURE__ */ jsx(Flex, {
375
+ justify: "center",
376
+ align: "center",
377
+ w: 120,
378
+ h: 80,
379
+ style: {
380
+ border: "2px dashed var(--mantine-color-default-border)",
381
+ borderRadius: "var(--mantine-radius-sm)"
382
+ },
383
+ children: /* @__PURE__ */ jsx(IconPhoto, {
384
+ size: 32,
385
+ style: { opacity: .3 }
386
+ })
387
+ })
388
+ }), /* @__PURE__ */ jsxs(Flex, {
389
+ flex: 1,
390
+ direction: "column",
391
+ gap: "md",
392
+ p: "xl",
393
+ justify: "center",
394
+ children: [formContent, /* @__PURE__ */ jsx(ActionButton, {
395
+ variant: "subtle",
396
+ href: redirect,
397
+ children: tr("registerCancel")
398
+ })]
399
+ })]
400
+ })
401
+ })
402
+ });
212
403
  return /* @__PURE__ */ jsx(Flex, {
213
404
  flex: 1,
214
405
  justify: "center",
@@ -221,142 +412,7 @@ const Register = (props) => {
221
412
  withBorder: true,
222
413
  p: "lg",
223
414
  bg: "var(--alepha-elevated)",
224
- children: /* @__PURE__ */ jsxs(Flex, {
225
- direction: "column",
226
- gap: "md",
227
- children: [(settings.logoUrl || settings.displayName || settings.description) && /* @__PURE__ */ jsxs(Flex, {
228
- direction: "column",
229
- gap: "xs",
230
- align: "center",
231
- mb: "xs",
232
- children: [
233
- settings.logoUrl && /* @__PURE__ */ jsx(Image, {
234
- src: settings.logoUrl,
235
- alt: settings.displayName || props.realmConfig.realmName,
236
- h: 48,
237
- w: "auto",
238
- fit: "contain"
239
- }),
240
- settings.displayName && /* @__PURE__ */ jsx(Title, {
241
- order: 4,
242
- ta: "center",
243
- children: settings.displayName
244
- }),
245
- settings.description && /* @__PURE__ */ jsx(Text, {
246
- size: "sm",
247
- c: "dimmed",
248
- ta: "center",
249
- children: settings.description
250
- })
251
- ]
252
- }), !isRegistrationAllowed ? /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(Alert, {
253
- variant: "light",
254
- color: "yellow",
255
- icon: /* @__PURE__ */ jsx(IconAlertCircle, {}),
256
- children: /* @__PURE__ */ jsx(Text, {
257
- size: "sm",
258
- children: tr("registerDisabled")
259
- })
260
- }), /* @__PURE__ */ jsx(ActionButton, {
261
- href: router.path("login", { query: { realm: props.realmConfig.realmName } }),
262
- children: tr("registerBackToSignIn")
263
- })] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
264
- credentialsProvider && /* @__PURE__ */ jsx("form", {
265
- ...form.props,
266
- children: /* @__PURE__ */ jsxs(Flex, {
267
- direction: "column",
268
- flex: 1,
269
- gap: "md",
270
- children: [
271
- settings.usernameEnabled !== false && form.input.username && /* @__PURE__ */ jsx(Control, {
272
- title: tr("registerUsername"),
273
- input: form.input.username,
274
- icon: /* @__PURE__ */ jsx(IconUser, {}),
275
- text: { autoComplete: "username" }
276
- }),
277
- settings.emailEnabled !== false && form.input.email && /* @__PURE__ */ jsx(Control, {
278
- title: tr("registerEmail"),
279
- input: form.input.email,
280
- icon: /* @__PURE__ */ jsx(IconMail, {}),
281
- text: { autoComplete: "email" }
282
- }),
283
- settings.phoneEnabled === true && form.input.phoneNumber && /* @__PURE__ */ jsx(Control, {
284
- title: tr("registerPhone"),
285
- input: form.input.phoneNumber,
286
- icon: /* @__PURE__ */ jsx(IconPhone, {}),
287
- text: { autoComplete: "tel" }
288
- }),
289
- /* @__PURE__ */ jsx(Control, {
290
- title: tr("registerPassword"),
291
- input: form.input.password,
292
- icon: /* @__PURE__ */ jsx(IconLock, {}),
293
- password: { autoComplete: "new-password" }
294
- }),
295
- /* @__PURE__ */ jsx(Control, {
296
- title: tr("registerConfirmPassword"),
297
- input: form.input.confirmPassword,
298
- icon: /* @__PURE__ */ jsx(IconLock, {}),
299
- password: { autoComplete: "new-password" }
300
- }),
301
- /* @__PURE__ */ jsx(ActionButton, {
302
- form,
303
- color: "blue",
304
- variant: "filled",
305
- children: tr("registerCreateAccount")
306
- })
307
- ]
308
- })
309
- }),
310
- showOrDivider && /* @__PURE__ */ jsxs(Flex, {
311
- align: "center",
312
- justify: "center",
313
- gap: "md",
314
- children: [
315
- /* @__PURE__ */ jsx(Flex, {
316
- flex: 1,
317
- h: "1px",
318
- bg: "var(--alepha-border)"
319
- }),
320
- /* @__PURE__ */ jsx(Text, {
321
- size: "xs",
322
- c: "dimmed",
323
- children: tr("registerOr")
324
- }),
325
- /* @__PURE__ */ jsx(Flex, {
326
- flex: 1,
327
- h: "1px",
328
- bg: "var(--alepha-border)"
329
- })
330
- ]
331
- }),
332
- externalMethods.length > 0 && /* @__PURE__ */ jsx(Flex, {
333
- direction: "column",
334
- gap: "sm",
335
- children: externalMethods.map((method) => /* @__PURE__ */ jsx(ActionButton, {
336
- variant: "default",
337
- leftSection: leftSection(method.name.toLowerCase()),
338
- onClick: () => auth.login(method.name, {
339
- redirect,
340
- realm: props.realmConfig.realmName
341
- }),
342
- children: tr("registerContinueWith", { args: [capitalize(method.name)] })
343
- }, method.type))
344
- }),
345
- /* @__PURE__ */ jsxs(Text, {
346
- size: "sm",
347
- ta: "center",
348
- children: [
349
- tr("registerHaveAccount"),
350
- " ",
351
- /* @__PURE__ */ jsx(ActionButton, {
352
- href: router.path("login", { query: { realm: props.realmConfig.realmName } }),
353
- anchorProps: { inherit: true },
354
- children: tr("registerSignIn")
355
- })
356
- ]
357
- })
358
- ] })]
359
- })
415
+ children: formContent
360
416
  }), /* @__PURE__ */ jsx(ActionButton, {
361
417
  variant: "subtle",
362
418
  href: redirect,
@@ -372,4 +428,4 @@ const leftSection = (name) => {
372
428
 
373
429
  //#endregion
374
430
  export { Register_exports as n, Register as t };
375
- //# sourceMappingURL=Register-2gx8qll-.js.map
431
+ //# sourceMappingURL=Register-CPhEO5MG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Register-CPhEO5MG.js","names":[],"sources":["../../src/auth/components/Register.tsx"],"sourcesContent":["import { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconLock,\n IconMail,\n IconPhone,\n IconPhoto,\n IconUser,\n} from \"@tabler/icons-react\";\nimport { TypeBoxError, t } from \"alepha\";\nimport type {\n RealmConfig,\n RegistrationIntentResponse,\n UserController,\n} from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useAuth } from \"alepha/react/auth\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { useMemo, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface RegisterProps {\n realmConfig: RealmConfig;\n loginPath?: string;\n variant?: \"card\" | \"split\";\n image?: string;\n}\n\ntype RegistrationPhase = \"form\" | \"verification\";\n\ninterface RegistrationState {\n phase: RegistrationPhase;\n intent?: RegistrationIntentResponse;\n credentials?: {\n identifier: string;\n password: string;\n };\n}\n\nconst Register = (props: RegisterProps) => {\n const auth = useAuth();\n const userCtrl = useClient<UserController>();\n const router = useRouter();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const [registrationState, setRegistrationState] = useState<RegistrationState>(\n {\n phase: \"form\",\n },\n );\n const [emailCode, setEmailCode] = useState(\"\");\n const [phoneCode, setPhoneCode] = useState(\"\");\n const [verificationError, setVerificationError] = useState<string | null>(\n null,\n );\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings || {};\n const isRegistrationAllowed = settings.registrationAllowed !== false;\n\n const registerSchema = useMemo(() => {\n const registerSchema = t.object({\n username: t.optional(\n t.text({\n trim: true,\n pattern: settings.usernameRegExp,\n }),\n ),\n email: t.optional(t.email()),\n phoneNumber: t.optional(t.e164()),\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n });\n\n const required = registerSchema.required as string[];\n\n if (settings.username === \"required\") required.push(\"username\");\n if (settings.email === \"required\") required.push(\"email\");\n if (settings.phoneNumber === \"required\") required.push(\"phoneNumber\");\n\n return registerSchema;\n }, []);\n\n const form = useForm({\n schema: registerSchema,\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new TypeBoxError({\n message: \"Passwords do not match\",\n instancePath: \"/confirmPassword\",\n keyword: \"not\",\n schemaPath: \"\",\n params: {},\n });\n }\n\n // Phase 1: Create registration intent\n const intent = await userCtrl.createRegistrationIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: {\n username: data.username,\n email: data.email,\n phoneNumber: data.phoneNumber,\n password: data.password,\n },\n });\n\n const identifier = data.username ?? data.email ?? data.phoneNumber;\n\n // Check if verification is needed\n if (\n intent.expectEmailVerification ||\n intent.expectPhoneVerification ||\n intent.expectCaptcha\n ) {\n // Move to verification phase\n setRegistrationState({\n phase: \"verification\",\n intent,\n credentials: identifier\n ? { identifier, password: data.password }\n : undefined,\n });\n return;\n }\n\n // No verification needed - complete registration immediately\n await userCtrl.createUserFromIntent({\n body: { intentId: intent.intentId },\n });\n\n // Auto-login after registration\n if (identifier && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.push(router.query.r || \"/\");\n },\n });\n\n const handleVerificationSubmit = async () => {\n if (!registrationState.intent) return;\n\n setIsSubmitting(true);\n setVerificationError(null);\n\n try {\n // Phase 2: Complete registration with verification codes\n await userCtrl.createUserFromIntent({\n body: {\n intentId: registrationState.intent.intentId,\n emailCode: registrationState.intent.expectEmailVerification\n ? emailCode\n : undefined,\n phoneCode: registrationState.intent.expectPhoneVerification\n ? phoneCode\n : undefined,\n },\n });\n\n // Auto-login after registration\n if (registrationState.credentials && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: registrationState.credentials.identifier,\n password: registrationState.credentials.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.push(router.query.r || \"/\");\n } catch (error) {\n setVerificationError(\n error instanceof Error ? error.message : \"Verification failed\",\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const canSubmitVerification = () => {\n if (!registrationState.intent) return false;\n\n if (\n registrationState.intent.expectEmailVerification &&\n emailCode.length !== 6\n ) {\n return false;\n }\n\n if (\n registrationState.intent.expectPhoneVerification &&\n phoneCode.length !== 6\n ) {\n return false;\n }\n\n return true;\n };\n\n // Verification phase UI (always card layout)\n if (registrationState.phase === \"verification\" && registrationState.intent) {\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"registerVerifyTitle\") ?? \"Verify your account\"}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"registerVerifyDescription\") ??\n \"Please enter the verification code(s) sent to you.\"}\n </Text>\n\n {verificationError && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{verificationError}</Text>\n </Alert>\n )}\n\n {registrationState.intent.expectEmailVerification && (\n <Flex direction=\"column\" gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerEmailCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={emailCode}\n onChange={setEmailCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Email verification code\"\n />\n </Flex>\n </Flex>\n )}\n\n {registrationState.intent.expectPhoneVerification && (\n <Flex direction=\"column\" gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerPhoneCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={phoneCode}\n onChange={setPhoneCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Phone verification code\"\n />\n </Flex>\n </Flex>\n )}\n\n <ActionButton\n color={\"blue\"}\n onClick={handleVerificationSubmit}\n loading={isSubmitting}\n disabled={!canSubmitVerification()}\n >\n {tr(\"registerVerifySubmit\")}\n </ActionButton>\n\n <ActionButton\n variant=\"subtle\"\n onClick={() =>\n setRegistrationState({ phase: \"form\", intent: undefined })\n }\n >\n {tr(\"registerVerifyBack\") ?? \"Back to registration\"}\n </ActionButton>\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n }\n\n // External login methods\n const externalMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalMethods.length > 0;\n\n const realmQuery = props.realmConfig.realmName\n ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}`\n : \"\";\n\n const formContent = (\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl || settings.displayName || settings.description) && (\n <Flex direction=\"column\" gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Flex>\n )}\n\n {!isRegistrationAllowed ? (\n <>\n <Alert variant=\"light\" color=\"yellow\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{tr(\"registerDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${realmQuery}`}\n >\n {tr(\"registerBackToSignIn\")}\n </ActionButton>\n </>\n ) : (\n <>\n {/* Credentials registration form */}\n {credentialsProvider && (\n <form {...form.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n {settings.username !== \"none\" && form.input.username && (\n <Control\n label={tr(\"registerUsername\")}\n input={form.input.username}\n icon={<IconUser />}\n text={{\n autoComplete: \"username\",\n }}\n />\n )}\n {settings.email !== \"none\" && form.input.email && (\n <Control\n label={tr(\"registerEmail\")}\n input={form.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n }}\n />\n )}\n {settings.phoneNumber !== \"none\" && form.input.phoneNumber && (\n <Control\n label={tr(\"registerPhone\")}\n input={form.input.phoneNumber}\n icon={<IconPhone />}\n text={{\n autoComplete: \"tel\",\n }}\n />\n )}\n <Control\n label={tr(\"registerPassword\")}\n input={form.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <Control\n label={tr(\"registerConfirmPassword\")}\n input={form.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={form} color={\"blue\"} variant={\"filled\"}>\n {tr(\"registerCreateAccount\")}\n </ActionButton>\n </Flex>\n </form>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Flex align=\"center\" justify=\"center\" gap={\"md\"}>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n <Text size=\"xs\" c=\"dimmed\">\n {tr(\"registerOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Flex>\n )}\n\n {/* External login methods */}\n {externalMethods.length > 0 && (\n <Flex direction=\"column\" gap={\"sm\"}>\n {externalMethods.map((method) => (\n <ActionButton\n variant={\"default\"}\n key={method.type}\n leftSection={leftSection(method.name.toLowerCase())}\n onClick={() =>\n auth.login(method.name, {\n redirect,\n realm: props.realmConfig.realmName,\n })\n }\n >\n {tr(\"registerContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Flex>\n )}\n\n {/* Sign in link */}\n <Text size=\"sm\" ta=\"center\">\n {tr(\"registerHaveAccount\")}{\" \"}\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${realmQuery}`}\n anchorProps={{ inherit: true }}\n >\n {tr(\"registerSignIn\")}\n </ActionButton>\n </Text>\n </>\n )}\n </Flex>\n );\n\n if (props.variant === \"split\") {\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Card\n withBorder\n p={0}\n w={720}\n bg={\"var(--alepha-elevated)\"}\n style={{ overflow: \"hidden\" }}\n >\n <Flex mih={480}>\n {props.image ? (\n <Flex\n flex={1}\n style={{\n backgroundImage: `url(${props.image})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n }}\n />\n ) : (\n <Flex\n flex={1}\n justify=\"center\"\n align=\"center\"\n bg=\"var(--mantine-color-gray-light)\"\n style={{\n borderRight: \"1px solid var(--mantine-color-default-border)\",\n }}\n >\n <Flex\n justify=\"center\"\n align=\"center\"\n w={120}\n h={80}\n style={{\n border: \"2px dashed var(--mantine-color-default-border)\",\n borderRadius: \"var(--mantine-radius-sm)\",\n }}\n >\n <IconPhoto size={32} style={{ opacity: 0.3 }} />\n </Flex>\n </Flex>\n )}\n <Flex\n flex={1}\n direction=\"column\"\n gap={\"md\"}\n p={\"xl\"}\n justify={\"center\"}\n >\n {formContent}\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n </Card>\n </Flex>\n );\n }\n\n // Default card variant\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n {formContent}\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default Register;\n\nconst leftSection = (name: string) => {\n if (name === \"google\") {\n return <IconGoogle />;\n }\n\n if (name === \"github\") {\n return <IconGithub />;\n }\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { h as ActionButton, o as Control } from "./core-B7LNjM78.js";
2
+ import { i as ActionButton, r as Control } from "./core-D5jIAVF2.js";
3
3
  import { AlephaError, t } from "alepha";
4
4
  import { useForm } from "alepha/react/form";
5
5
  import { useI18n } from "alepha/react/i18n";
@@ -139,7 +139,7 @@ const ResetPassword = (props) => {
139
139
  children: tr("resetPasswordDisabled")
140
140
  })
141
141
  }), /* @__PURE__ */ jsx(ActionButton, {
142
- href: router.path("login", { query: { realm: props.realmConfig.realmName } }),
142
+ href: `${props.loginPath ?? "/auth/login"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : ""}`,
143
143
  children: tr("resetPasswordBackToSignIn")
144
144
  })] }) : resetState.step === "email" ? /* @__PURE__ */ jsx("form", {
145
145
  ...emailForm.props,
@@ -160,7 +160,7 @@ const ResetPassword = (props) => {
160
160
  children: tr("resetPasswordEnterEmail")
161
161
  }),
162
162
  /* @__PURE__ */ jsx(Control, {
163
- title: tr("resetPasswordEmail"),
163
+ label: tr("resetPasswordEmail"),
164
164
  input: emailForm.input.email,
165
165
  icon: /* @__PURE__ */ jsx(IconMail, {}),
166
166
  text: {
@@ -238,7 +238,7 @@ const ResetPassword = (props) => {
238
238
  children: tr("resetPasswordEnterNewPassword")
239
239
  }),
240
240
  /* @__PURE__ */ jsx(Control, {
241
- title: tr("resetPasswordNewPassword"),
241
+ label: tr("resetPasswordNewPassword"),
242
242
  input: passwordForm.input.password,
243
243
  icon: /* @__PURE__ */ jsx(IconLock, {}),
244
244
  password: {
@@ -247,7 +247,7 @@ const ResetPassword = (props) => {
247
247
  }
248
248
  }),
249
249
  /* @__PURE__ */ jsx(Control, {
250
- title: tr("resetPasswordConfirmPassword"),
250
+ label: tr("resetPasswordConfirmPassword"),
251
251
  input: passwordForm.input.confirmPassword,
252
252
  icon: /* @__PURE__ */ jsx(IconLock, {}),
253
253
  password: { autoComplete: "new-password" }
@@ -267,7 +267,7 @@ const ResetPassword = (props) => {
267
267
  children: tr("resetPasswordSuccess")
268
268
  })
269
269
  }), /* @__PURE__ */ jsx(ActionButton, {
270
- href: router.path("login", { query: { realm: props.realmConfig.realmName } }),
270
+ href: `${props.loginPath ?? "/auth/login"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : ""}`,
271
271
  children: tr("resetPasswordBackToSignIn")
272
272
  })] })
273
273
  ]
@@ -283,4 +283,4 @@ const ResetPassword = (props) => {
283
283
 
284
284
  //#endregion
285
285
  export { ResetPassword_exports as n, ResetPassword as t };
286
- //# sourceMappingURL=ResetPassword-CAPj8MO3.js.map
286
+ //# sourceMappingURL=ResetPassword-DCtGcneA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResetPassword-DCtGcneA.js","names":[],"sources":["../../src/auth/components/ResetPassword.tsx"],"sourcesContent":["import { ActionButton, Control } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconCheck,\n IconInfoCircle,\n IconLock,\n IconMail,\n} from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type {\n PasswordResetIntentResponse,\n RealmConfig,\n UserController,\n} from \"alepha/api/users\";\nimport { resetPasswordRequestSchema } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\n\nexport interface ResetPasswordProps {\n realmConfig: RealmConfig;\n loginPath?: string;\n}\n\ntype Step = \"email\" | \"code\" | \"password\" | \"success\";\n\ninterface ResetState {\n step: Step;\n intent?: PasswordResetIntentResponse;\n email?: string;\n code?: string;\n}\n\nconst ResetPassword = (props: ResetPasswordProps) => {\n const router = useRouter();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const [resetState, setResetState] = useState<ResetState>({ step: \"email\" });\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const redirect = router.query.r || \"/\";\n\n const settings = props.realmConfig.settings;\n const isResetPasswordAllowed = settings?.resetPasswordAllowed !== false;\n\n // Phase 1: Request password reset intent\n const emailForm = useForm({\n schema: resetPasswordRequestSchema,\n handler: async (data) => {\n setError(null);\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: data.email },\n });\n\n setResetState({\n step: \"code\",\n intent,\n email: data.email,\n });\n },\n });\n\n // Phase 2: Complete password reset\n const passwordForm = useForm(\n {\n schema: t.object({\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n }),\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new AlephaError(\"Passwords do not match\");\n }\n\n if (!resetState.intent || !resetState.code) {\n throw new AlephaError(\"Invalid reset state\");\n }\n\n await userCtrl.completePasswordReset({\n body: {\n intentId: resetState.intent.intentId,\n code: resetState.code,\n newPassword: data.password,\n },\n });\n\n setResetState({ step: \"success\" });\n },\n },\n [resetState.intent, resetState.code],\n );\n\n const handleCodeComplete = (value: string) => {\n if (value.length === 6) {\n setResetState((prev) => ({\n ...prev,\n step: \"password\",\n code: value,\n }));\n }\n };\n\n const handleResendCode = async () => {\n if (!resetState.email) return;\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: resetState.email },\n });\n\n setResetState((prev) => ({\n ...prev,\n intent,\n }));\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to resend code\");\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Flex direction=\"column\" gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Flex>\n )}\n\n {error && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{error}</Text>\n </Alert>\n )}\n\n {!isResetPasswordAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"resetPasswordDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : \"\"}`}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n ) : resetState.step === \"email\" ? (\n <form {...emailForm.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterEmail\")}\n </Text>\n <Control\n label={tr(\"resetPasswordEmail\")}\n input={emailForm.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n autoFocus: true,\n disabled: !isResetPasswordAllowed,\n }}\n />\n <ActionButton\n form={emailForm}\n disabled={!isResetPasswordAllowed}\n >\n {tr(\"resetPasswordSendCode\")}\n </ActionButton>\n </Flex>\n </form>\n ) : resetState.step === \"code\" ? (\n <Flex direction=\"column\" gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"blue\" icon={<IconInfoCircle />}>\n <Text size=\"sm\">{tr(\"resetPasswordCodeSent\")}</Text>\n </Alert>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"resetPasswordEnterCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n type=\"number\"\n autoFocus\n oneTimeCode\n onComplete={handleCodeComplete}\n aria-label=\"Password reset verification code\"\n />\n </Flex>\n <ActionButton\n variant=\"subtle\"\n onClick={handleResendCode}\n loading={isSubmitting}\n >\n {tr(\"resetPasswordResendCode\")}\n </ActionButton>\n </Flex>\n ) : resetState.step === \"password\" ? (\n <form {...passwordForm.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterNewPassword\")}\n </Text>\n <Control\n label={tr(\"resetPasswordNewPassword\")}\n input={passwordForm.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n autoFocus: true,\n }}\n />\n <Control\n label={tr(\"resetPasswordConfirmPassword\")}\n input={passwordForm.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={passwordForm}>\n {tr(\"resetPasswordSetNewPassword\")}\n </ActionButton>\n </Flex>\n </form>\n ) : (\n <>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"resetPasswordSuccess\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : \"\"}`}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"resetPasswordCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default ResetPassword;\n"],"mappings":"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"}
@@ -1,17 +1,16 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { h as ActionButton } from "./core-B7LNjM78.js";
2
+ import { i as ActionButton } from "./core-D5jIAVF2.js";
3
3
  import { useI18n } from "alepha/react/i18n";
4
4
  import { Alert, Card, Flex, Loader, Text } from "@mantine/core";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useEffect, useState } from "react";
7
7
  import { IconAlertCircle, IconCheck, IconMailCheck } from "@tabler/icons-react";
8
- import { useRouter, useRouterState } from "alepha/react/router";
8
+ import { useRouterState } from "alepha/react/router";
9
9
  import { useClient } from "alepha/react";
10
10
 
11
11
  //#region ../../src/auth/components/VerifyEmail.tsx
12
12
  var VerifyEmail_exports = /* @__PURE__ */ __exportAll({ default: () => VerifyEmail });
13
- const VerifyEmail = (_props) => {
14
- const router = useRouter();
13
+ const VerifyEmailStateful = (props) => {
15
14
  const state = useRouterState();
16
15
  const userCtrl = useClient();
17
16
  const { tr } = useI18n();
@@ -39,6 +38,15 @@ const VerifyEmail = (_props) => {
39
38
  };
40
39
  verify();
41
40
  }, [email, token]);
41
+ return /* @__PURE__ */ jsx(VerifyEmailView, {
42
+ step,
43
+ error,
44
+ loginPath: props.loginPath
45
+ });
46
+ };
47
+ const VerifyEmailView = (props) => {
48
+ const { tr } = useI18n();
49
+ const { step } = props;
42
50
  return /* @__PURE__ */ jsx(Flex, {
43
51
  flex: 1,
44
52
  justify: "center",
@@ -92,7 +100,7 @@ const VerifyEmail = (_props) => {
92
100
  })
93
101
  }),
94
102
  /* @__PURE__ */ jsx(ActionButton, {
95
- href: router.path("login"),
103
+ href: props.loginPath ?? "/auth/login",
96
104
  fullWidth: true,
97
105
  children: tr("verifyEmailSignIn")
98
106
  })
@@ -114,11 +122,11 @@ const VerifyEmail = (_props) => {
114
122
  icon: /* @__PURE__ */ jsx(IconAlertCircle, {}),
115
123
  children: /* @__PURE__ */ jsx(Text, {
116
124
  size: "sm",
117
- children: error || tr("verifyEmailFailed")
125
+ children: props.error || tr("verifyEmailFailed")
118
126
  })
119
127
  }),
120
128
  /* @__PURE__ */ jsx(ActionButton, {
121
- href: router.path("login"),
129
+ href: props.loginPath ?? "/auth/login",
122
130
  fullWidth: true,
123
131
  children: tr("verifyEmailBackToSignIn")
124
132
  })
@@ -129,7 +137,14 @@ const VerifyEmail = (_props) => {
129
137
  })
130
138
  });
131
139
  };
140
+ const VerifyEmail = (props) => {
141
+ if (props.step) return /* @__PURE__ */ jsx(VerifyEmailView, {
142
+ step: props.step,
143
+ loginPath: props.loginPath
144
+ });
145
+ return /* @__PURE__ */ jsx(VerifyEmailStateful, { ...props });
146
+ };
132
147
 
133
148
  //#endregion
134
149
  export { VerifyEmail_exports as n, VerifyEmail as t };
135
- //# sourceMappingURL=VerifyEmail-DFmdCdYs.js.map
150
+ //# sourceMappingURL=VerifyEmail-DkH7NBfn.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VerifyEmail-DkH7NBfn.js","names":[],"sources":["../../src/auth/components/VerifyEmail.tsx"],"sourcesContent":["import { ActionButton } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Loader, Text } from \"@mantine/core\";\nimport { IconAlertCircle, IconCheck, IconMailCheck } from \"@tabler/icons-react\";\nimport type { UserController } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouterState } from \"alepha/react/router\";\nimport { useEffect, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\n\nexport type VerifyEmailStep = \"verifying\" | \"success\" | \"error\";\n\nexport interface VerifyEmailProps {\n loginPath?: string;\n step?: VerifyEmailStep;\n}\n\nconst VerifyEmailStateful = (props: VerifyEmailProps) => {\n const state = useRouterState();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n\n const [step, setStep] = useState<VerifyEmailStep>(\"verifying\");\n const [error, setError] = useState<string | null>(null);\n\n const email = state.query.email as string | undefined;\n const token = state.query.token as string | undefined;\n\n useEffect(() => {\n const verify = async () => {\n if (!email || !token) {\n setError(tr(\"verifyEmailMissingParams\"));\n setStep(\"error\");\n return;\n }\n\n try {\n await userCtrl.verifyEmail({\n body: { email, token },\n });\n setStep(\"success\");\n } catch (err) {\n setError(err instanceof Error ? err.message : tr(\"verifyEmailFailed\"));\n setStep(\"error\");\n }\n };\n\n verify();\n }, [email, token]);\n\n return (\n <VerifyEmailView step={step} error={error} loginPath={props.loginPath} />\n );\n};\n\ninterface VerifyEmailViewProps {\n step: VerifyEmailStep;\n error?: string | null;\n loginPath?: string;\n}\n\nconst VerifyEmailView = (props: VerifyEmailViewProps) => {\n const { tr } = useI18n<AuthI18n, \"en\">();\n const { step } = props;\n\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Flex direction=\"column\" gap=\"sm\" w={400}>\n <Card withBorder p=\"lg\" bg=\"var(--alepha-elevated)\">\n <Flex direction=\"column\" gap=\"md\" align=\"center\">\n {step === \"verifying\" && (\n <>\n <Loader size=\"lg\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailVerifying\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"verifyEmailPleaseWait\")}\n </Text>\n </>\n )}\n\n {step === \"success\" && (\n <>\n <IconMailCheck size={48} color=\"var(--mantine-color-green-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"verifyEmailSuccess\")}</Text>\n </Alert>\n <ActionButton href={props.loginPath ?? \"/auth/login\"} fullWidth>\n {tr(\"verifyEmailSignIn\")}\n </ActionButton>\n </>\n )}\n\n {step === \"error\" && (\n <>\n <IconAlertCircle size={48} color=\"var(--mantine-color-red-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">\n {props.error || tr(\"verifyEmailFailed\")}\n </Text>\n </Alert>\n <ActionButton href={props.loginPath ?? \"/auth/login\"} fullWidth>\n {tr(\"verifyEmailBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nconst VerifyEmail = (props: VerifyEmailProps) => {\n if (props.step) {\n return <VerifyEmailView step={props.step} loginPath={props.loginPath} />;\n }\n return <VerifyEmailStateful {...props} />;\n};\n\nexport default VerifyEmail;\n"],"mappings":";;;;;;;;;;;;AAiBA,MAAM,uBAAuB,UAA4B;CACvD,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,WAAW,WAA2B;CAC5C,MAAM,EAAE,OAAO,SAAyB;CAExC,MAAM,CAAC,MAAM,WAAW,SAA0B,YAAY;CAC9D,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CAEvD,MAAM,QAAQ,MAAM,MAAM;CAC1B,MAAM,QAAQ,MAAM,MAAM;AAE1B,iBAAgB;EACd,MAAM,SAAS,YAAY;AACzB,OAAI,CAAC,SAAS,CAAC,OAAO;AACpB,aAAS,GAAG,2BAA2B,CAAC;AACxC,YAAQ,QAAQ;AAChB;;AAGF,OAAI;AACF,UAAM,SAAS,YAAY,EACzB,MAAM;KAAE;KAAO;KAAO,EACvB,CAAC;AACF,YAAQ,UAAU;YACX,KAAK;AACZ,aAAS,eAAe,QAAQ,IAAI,UAAU,GAAG,oBAAoB,CAAC;AACtE,YAAQ,QAAQ;;;AAIpB,UAAQ;IACP,CAAC,OAAO,MAAM,CAAC;AAElB,QACE,oBAAC;EAAsB;EAAa;EAAO,WAAW,MAAM;GAAa;;AAU7E,MAAM,mBAAmB,UAAgC;CACvD,MAAM,EAAE,OAAO,SAAyB;CACxC,MAAM,EAAE,SAAS;AAEjB,QACE,oBAAC;EAAK,MAAM;EAAG,SAAQ;EAAS,OAAM;YACpC,oBAAC;GAAK,WAAU;GAAS,KAAI;GAAK,GAAG;aACnC,oBAAC;IAAK;IAAW,GAAE;IAAK,IAAG;cACzB,qBAAC;KAAK,WAAU;KAAS,KAAI;KAAK,OAAM;;MACrC,SAAS,eACR;OACE,oBAAC,UAAO,MAAK,OAAO;OACpB,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,uBAAuB;SACtB;OACP,oBAAC;QAAK,MAAK;QAAK,GAAE;QAAS,IAAG;kBAC3B,GAAG,wBAAwB;SACvB;UACN;MAGJ,SAAS,aACR;OACE,oBAAC;QAAc,MAAM;QAAI,OAAM;SAAiC;OAChE,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;SAClB;OACP,oBAAC;QAAM,SAAQ;QAAQ,OAAM;QAAQ,MAAM,oBAAC,cAAY;kBACtD,oBAAC;SAAK,MAAK;mBAAM,GAAG,qBAAqB;UAAQ;SAC3C;OACR,oBAAC;QAAa,MAAM,MAAM,aAAa;QAAe;kBACnD,GAAG,oBAAoB;SACX;UACd;MAGJ,SAAS,WACR;OACE,oBAAC;QAAgB,MAAM;QAAI,OAAM;SAA+B;OAChE,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;SAClB;OACP,oBAAC;QAAM,SAAQ;QAAQ,OAAM;QAAM,MAAM,oBAAC,oBAAkB;kBAC1D,oBAAC;SAAK,MAAK;mBACR,MAAM,SAAS,GAAG,oBAAoB;UAClC;SACD;OACR,oBAAC;QAAa,MAAM,MAAM,aAAa;QAAe;kBACnD,GAAG,0BAA0B;SACjB;UACd;;MAEA;KACF;IACF;GACF;;AAIX,MAAM,eAAe,UAA4B;AAC/C,KAAI,MAAM,KACR,QAAO,oBAAC;EAAgB,MAAM,MAAM;EAAM,WAAW,MAAM;GAAa;AAE1E,QAAO,oBAAC,uBAAoB,GAAI,QAAS"}