@alepha/ui 0.18.0 → 0.18.2

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 (187) hide show
  1. package/dist/admin/{AdminApiKeys-C-6_Q-lH.js → AdminApiKeys-BJhIwfD6.js} +17 -38
  2. package/dist/admin/AdminApiKeys-BJhIwfD6.js.map +1 -0
  3. package/dist/admin/{AdminAudits-Bgbf04hO.js → AdminAudits-DzD_4cDt.js} +23 -19
  4. package/dist/admin/AdminAudits-DzD_4cDt.js.map +1 -0
  5. package/dist/admin/AdminDashboard-C92tIc6x.js +67 -0
  6. package/dist/admin/AdminDashboard-C92tIc6x.js.map +1 -0
  7. package/dist/admin/{AdminFiles-B9a7G3cY.js → AdminFiles-DLpfhBkf.js} +3 -7
  8. package/dist/admin/AdminFiles-DLpfhBkf.js.map +1 -0
  9. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js → AdminJobDashboard-KIOkeMgE.js} +2 -2
  10. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js.map → AdminJobDashboard-KIOkeMgE.js.map} +1 -1
  11. package/dist/admin/{AdminJobExecutions-B9cek5dl.js → AdminJobExecutions-D0Yo_PU0.js} +24 -36
  12. package/dist/admin/AdminJobExecutions-D0Yo_PU0.js.map +1 -0
  13. package/dist/admin/{AdminJobRegistry-DFgV3oqx.js → AdminJobRegistry-PFajqaGK.js} +10 -18
  14. package/dist/admin/AdminJobRegistry-PFajqaGK.js.map +1 -0
  15. package/dist/admin/AdminLayout-B1DXZHDn.js +61 -0
  16. package/dist/admin/AdminLayout-B1DXZHDn.js.map +1 -0
  17. package/dist/admin/{AdminParameters-DHw9ATgl.js → AdminParameters-BspPeqp_.js} +2 -2
  18. package/dist/admin/{AdminParameters-DHw9ATgl.js.map → AdminParameters-BspPeqp_.js.map} +1 -1
  19. package/dist/admin/{AdminSessions-BhGJPI3z.js → AdminSessions-BnH5CZQl.js} +48 -53
  20. package/dist/admin/AdminSessions-BnH5CZQl.js.map +1 -0
  21. package/dist/admin/{AdminUserLayout-BdC4Te8m.js → AdminUserLayout-DUbC6-BI.js} +2 -2
  22. package/dist/admin/{AdminUserLayout-BdC4Te8m.js.map → AdminUserLayout-DUbC6-BI.js.map} +1 -1
  23. package/dist/admin/{AdminUserProfile-DAt23fqY.js → AdminUserProfile-DuTUnjdG.js} +3 -3
  24. package/dist/admin/{AdminUserProfile-DAt23fqY.js.map → AdminUserProfile-DuTUnjdG.js.map} +1 -1
  25. package/dist/admin/{AdminUserSessions-1uzcx02z.js → AdminUserSessions-DvZdAGpL.js} +33 -35
  26. package/dist/admin/AdminUserSessions-DvZdAGpL.js.map +1 -0
  27. package/dist/admin/AdminUsers-CR9z0g_5.js +206 -0
  28. package/dist/admin/AdminUsers-CR9z0g_5.js.map +1 -0
  29. package/dist/admin/{AuthLayout-DFJvCvzw.js → AuthLayout-DsUfp9RG.js} +2 -2
  30. package/dist/admin/{AuthLayout-DFJvCvzw.js.map → AuthLayout-DsUfp9RG.js.map} +1 -1
  31. package/dist/admin/{IconGoogle-CSQLPYwX.js → IconGoogle-Ch1m3Uzl.js} +1 -1
  32. package/dist/admin/{IconGoogle-CSQLPYwX.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
  33. package/dist/admin/{Login-BGheURrg.js → Login-DHbYJKwg.js} +3 -3
  34. package/dist/{auth/Login-Denw_UGy.js.map → admin/Login-DHbYJKwg.js.map} +1 -1
  35. package/dist/{auth/Profile-BMX_Ar_s.js → admin/Profile-B2EcIDB9.js} +2 -2
  36. package/dist/{auth/Profile-BMX_Ar_s.js.map → admin/Profile-B2EcIDB9.js.map} +1 -1
  37. package/dist/admin/{Register-Cs10l8vX.js → Register-Z3fxRbUF.js} +3 -3
  38. package/dist/{demo/Register-a70LPgs2.js.map → admin/Register-Z3fxRbUF.js.map} +1 -1
  39. package/dist/admin/{ResetPassword-BwDdfkGH.js → ResetPassword-_Y1qTTKh.js} +2 -2
  40. package/dist/admin/{ResetPassword-BwDdfkGH.js.map → ResetPassword-_Y1qTTKh.js.map} +1 -1
  41. package/dist/admin/{VerifyEmail-DfXHAiQl.js → VerifyEmail-Bg22bwcC.js} +2 -2
  42. package/dist/admin/{VerifyEmail-DfXHAiQl.js.map → VerifyEmail-Bg22bwcC.js.map} +1 -1
  43. package/dist/admin/{core-2xoLiT0o.js → core-BVO_TQxb.js} +1474 -233
  44. package/dist/admin/core-BVO_TQxb.js.map +1 -0
  45. package/dist/admin/index.d.ts +29 -4
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +448 -69
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/auth/{AuthLayout-CAE1pX9s.js → AuthLayout-C161NeF6.js} +2 -2
  50. package/dist/auth/{AuthLayout-CAE1pX9s.js.map → AuthLayout-C161NeF6.js.map} +1 -1
  51. package/dist/auth/{Login-Denw_UGy.js → Login-C7jIqf00.js} +2 -2
  52. package/dist/{admin/Login-BGheURrg.js.map → auth/Login-C7jIqf00.js.map} +1 -1
  53. package/dist/{admin/Profile-B-c9pCPf.js → auth/Profile-BMpXJ0oi.js} +2 -2
  54. package/dist/{demo/Profile-CWqti7FB.js.map → auth/Profile-BMpXJ0oi.js.map} +1 -1
  55. package/dist/auth/{Register-6hi_cpfF.js → Register-2gx8qll-.js} +2 -2
  56. package/dist/auth/{Register-6hi_cpfF.js.map → Register-2gx8qll-.js.map} +1 -1
  57. package/dist/{demo/ResetPassword-DWN0lzr5.js → auth/ResetPassword-DBxt9hKk.js} +2 -2
  58. package/dist/auth/{ResetPassword-CqfTk1FI.js.map → ResetPassword-DBxt9hKk.js.map} +1 -1
  59. package/dist/{demo/VerifyEmail-DZWL72K4.js → auth/VerifyEmail-Z80Ubajk.js} +2 -2
  60. package/dist/auth/{VerifyEmail-nWiSTMjF.js.map → VerifyEmail-Z80Ubajk.js.map} +1 -1
  61. package/dist/auth/{core-niW0sFLv.js → core-DyfeVr5c.js} +1002 -38
  62. package/dist/auth/core-DyfeVr5c.js.map +1 -0
  63. package/dist/auth/index.d.ts +12 -1
  64. package/dist/auth/index.d.ts.map +1 -1
  65. package/dist/auth/index.js +12 -13
  66. package/dist/auth/index.js.map +1 -1
  67. package/dist/core/index.d.ts +95 -14
  68. package/dist/core/index.d.ts.map +1 -1
  69. package/dist/core/index.js +1473 -232
  70. package/dist/core/index.js.map +1 -1
  71. package/dist/demo/{AuthLayout-jLa0aKsI.js → AuthLayout-DN-ClJQk.js} +2 -2
  72. package/dist/demo/{AuthLayout-jLa0aKsI.js.map → AuthLayout-DN-ClJQk.js.map} +1 -1
  73. package/dist/demo/{DemoButton-BmaWZVwf.js → DemoButton-CGUyR9eM.js} +3 -3
  74. package/dist/demo/{DemoButton-BmaWZVwf.js.map → DemoButton-CGUyR9eM.js.map} +1 -1
  75. package/dist/demo/{DemoDataTable-Z9xyV221.js → DemoDataTable-QFG-xXSx.js} +15 -19
  76. package/dist/demo/DemoDataTable-QFG-xXSx.js.map +1 -0
  77. package/dist/demo/{DemoDialog-4ItHLf9t.js → DemoDialog-DW8QEvD1.js} +2 -2
  78. package/dist/demo/{DemoDialog-4ItHLf9t.js.map → DemoDialog-DW8QEvD1.js.map} +1 -1
  79. package/dist/demo/{DemoFlex-EtVq8QfX.js → DemoFlex-CAhLUanT.js} +3 -3
  80. package/dist/demo/{DemoFlex-EtVq8QfX.js.map → DemoFlex-CAhLUanT.js.map} +1 -1
  81. package/dist/demo/{DemoHeading-BS-vGfkI.js → DemoHeading-yIFmNjHB.js} +3 -3
  82. package/dist/demo/{DemoHeading-BS-vGfkI.js.map → DemoHeading-yIFmNjHB.js.map} +1 -1
  83. package/dist/demo/{DemoHome-Clbn8AmS.js → DemoHome-BSGuBHus.js} +2 -2
  84. package/dist/demo/{DemoHome-Clbn8AmS.js.map → DemoHome-BSGuBHus.js.map} +1 -1
  85. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js → DemoJsonViewer-DsA2IpgV.js} +3 -3
  86. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js.map → DemoJsonViewer-DsA2IpgV.js.map} +1 -1
  87. package/dist/demo/{DemoLayout-C56xb5EE.js → DemoLayout-Cy6xjn6P.js} +2 -2
  88. package/dist/demo/{DemoLayout-C56xb5EE.js.map → DemoLayout-Cy6xjn6P.js.map} +1 -1
  89. package/dist/demo/{DemoLogin-BZwpicOS.js → DemoLogin-vqxgTu4P.js} +8 -8
  90. package/dist/demo/{DemoLogin-BZwpicOS.js.map → DemoLogin-vqxgTu4P.js.map} +1 -1
  91. package/dist/demo/{DemoRegister-C7_qc4MJ.js → DemoRegister-YHPvPg77.js} +8 -8
  92. package/dist/demo/{DemoRegister-C7_qc4MJ.js.map → DemoRegister-YHPvPg77.js.map} +1 -1
  93. package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js → DemoResetPassword-mOW18Zlm.js} +8 -8
  94. package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js.map → DemoResetPassword-mOW18Zlm.js.map} +1 -1
  95. package/dist/demo/{DemoSidebar-CcBo4ltC.js → DemoSidebar-od7aLjP_.js} +3 -3
  96. package/dist/demo/{DemoSidebar-CcBo4ltC.js.map → DemoSidebar-od7aLjP_.js.map} +1 -1
  97. package/dist/demo/{DemoText-CzXuUn3g.js → DemoText-DU3JeRS0.js} +3 -3
  98. package/dist/demo/{DemoText-CzXuUn3g.js.map → DemoText-DU3JeRS0.js.map} +1 -1
  99. package/dist/demo/{DemoToast-BgHDhWrX.js → DemoToast-CUJEiPRa.js} +2 -2
  100. package/dist/demo/{DemoToast-BgHDhWrX.js.map → DemoToast-CUJEiPRa.js.map} +1 -1
  101. package/dist/demo/{DemoTypeForm-DDzWoMSV.js → DemoTypeForm-C1dNkahD.js} +3 -3
  102. package/dist/demo/{DemoTypeForm-DDzWoMSV.js.map → DemoTypeForm-C1dNkahD.js.map} +1 -1
  103. package/dist/demo/{DemoVerifyEmail-C_Irdnov.js → DemoVerifyEmail-D9EcXZ38.js} +8 -8
  104. package/dist/demo/{DemoVerifyEmail-C_Irdnov.js.map → DemoVerifyEmail-D9EcXZ38.js.map} +1 -1
  105. package/dist/demo/{Login-hSOU3jZc.js → Login-CoYf_P_F.js} +2 -2
  106. package/dist/demo/{Login-hSOU3jZc.js.map → Login-CoYf_P_F.js.map} +1 -1
  107. package/dist/demo/{Profile-CWqti7FB.js → Profile-BE_Y3co2.js} +2 -2
  108. package/dist/{admin/Profile-B-c9pCPf.js.map → demo/Profile-BE_Y3co2.js.map} +1 -1
  109. package/dist/demo/{Register-a70LPgs2.js → Register-fXHmBpr3.js} +2 -2
  110. package/dist/{admin/Register-Cs10l8vX.js.map → demo/Register-fXHmBpr3.js.map} +1 -1
  111. package/dist/{auth/ResetPassword-CqfTk1FI.js → demo/ResetPassword-CAPj8MO3.js} +2 -2
  112. package/dist/demo/{ResetPassword-DWN0lzr5.js.map → ResetPassword-CAPj8MO3.js.map} +1 -1
  113. package/dist/demo/{Showcase-Dq3MISpd.js → Showcase-BtEU0pY9.js} +2 -2
  114. package/dist/demo/{Showcase-Dq3MISpd.js.map → Showcase-BtEU0pY9.js.map} +1 -1
  115. package/dist/{auth/VerifyEmail-nWiSTMjF.js → demo/VerifyEmail-DFmdCdYs.js} +2 -2
  116. package/dist/demo/{VerifyEmail-DZWL72K4.js.map → VerifyEmail-DFmdCdYs.js.map} +1 -1
  117. package/dist/demo/{auth-d6n3xbug.js → auth-Djd7SKiw.js} +8 -8
  118. package/dist/demo/{auth-d6n3xbug.js.map → auth-Djd7SKiw.js.map} +1 -1
  119. package/dist/demo/{core-RCUw1Q-a.js → core-B7LNjM78.js} +1484 -226
  120. package/dist/demo/core-B7LNjM78.js.map +1 -0
  121. package/dist/demo/index.js +17 -17
  122. package/package.json +4 -4
  123. package/src/admin/{AdminRouter.ts → AdminRouter.tsx} +128 -19
  124. package/src/admin/components/AdminDashboard.tsx +52 -0
  125. package/src/admin/components/AdminLayout.tsx +32 -40
  126. package/src/admin/components/audits/AdminAudits.tsx +22 -16
  127. package/src/admin/components/files/AdminFiles.tsx +1 -6
  128. package/src/admin/components/jobs/AdminJobExecutions.tsx +33 -39
  129. package/src/admin/components/jobs/AdminJobRegistry.tsx +9 -18
  130. package/src/admin/components/keys/AdminApiKeys.tsx +23 -41
  131. package/src/admin/components/sessions/AdminSessions.tsx +71 -71
  132. package/src/admin/components/users/AdminUserSessions.tsx +33 -31
  133. package/src/admin/components/users/AdminUsers.tsx +184 -72
  134. package/src/admin/index.ts +2 -2
  135. package/src/admin/primitives/$uiAdmin.ts +1 -1
  136. package/src/auth/components/buttons/UserButton.tsx +1 -3
  137. package/src/core/atoms/alephaSidebarAtom.ts +1 -1
  138. package/src/core/atoms/alephaThemeListAtom.ts +14 -1
  139. package/src/core/atoms/alephaThemeOverridesAtom.ts +17 -0
  140. package/src/core/atoms/themes/editorial.ts +184 -0
  141. package/src/core/atoms/themes/monochrome.ts +197 -0
  142. package/src/core/atoms/themes/rosePine.ts +208 -0
  143. package/src/core/atoms/themes/softBrutalism.ts +221 -0
  144. package/src/core/atoms/themes/terminal.ts +186 -0
  145. package/src/core/components/Flex.tsx +91 -1
  146. package/src/core/components/Text.tsx +1 -1
  147. package/src/core/components/buttons/ActionButton.tsx +15 -19
  148. package/src/core/components/buttons/DarkModeButton.tsx +3 -3
  149. package/src/core/components/buttons/LanguageButton.tsx +1 -1
  150. package/src/core/components/buttons/OmnibarButton.tsx +1 -2
  151. package/src/core/components/buttons/ThemeButton.tsx +40 -11
  152. package/src/core/components/buttons/ThemeExpertModal.tsx +184 -0
  153. package/src/core/components/buttons/ToggleSidebarButton.tsx +1 -2
  154. package/src/core/components/layout/AppBar.tsx +10 -0
  155. package/src/core/components/layout/DashboardShell.tsx +10 -7
  156. package/src/core/components/layout/Sidebar.tsx +60 -52
  157. package/src/core/constants/ui.ts +5 -5
  158. package/src/core/hooks/useTheme.ts +26 -3
  159. package/src/core/index.ts +6 -1
  160. package/src/core/interfaces/AlephaTheme.ts +2 -0
  161. package/src/core/providers/ThemeProvider.ts +108 -8
  162. package/src/core/services/DialogService.tsx +24 -3
  163. package/src/core/styles.css +26 -23
  164. package/src/core/table/components/DataTable.tsx +167 -137
  165. package/src/core/table/components/DataTableFilters.tsx +1 -6
  166. package/src/core/table/components/DataTablePagination.tsx +51 -28
  167. package/src/core/table/components/DataTableToolbar.tsx +9 -4
  168. package/src/core/table/index.ts +1 -0
  169. package/src/core/table/interfaces/types.ts +13 -9
  170. package/src/demo/components/core/DemoDataTable.tsx +15 -19
  171. package/dist/admin/AdminApiKeys-C-6_Q-lH.js.map +0 -1
  172. package/dist/admin/AdminAudits-Bgbf04hO.js.map +0 -1
  173. package/dist/admin/AdminFiles-B9a7G3cY.js.map +0 -1
  174. package/dist/admin/AdminJobExecutions-B9cek5dl.js.map +0 -1
  175. package/dist/admin/AdminJobRegistry-DFgV3oqx.js.map +0 -1
  176. package/dist/admin/AdminLayout-DHsvWxVB.js +0 -70
  177. package/dist/admin/AdminLayout-DHsvWxVB.js.map +0 -1
  178. package/dist/admin/AdminSessions-BhGJPI3z.js.map +0 -1
  179. package/dist/admin/AdminUserSessions-1uzcx02z.js.map +0 -1
  180. package/dist/admin/AdminUsers-C85c3eiQ.js +0 -121
  181. package/dist/admin/AdminUsers-C85c3eiQ.js.map +0 -1
  182. package/dist/admin/auth-Dr0Cf8I7.js +0 -319
  183. package/dist/admin/auth-Dr0Cf8I7.js.map +0 -1
  184. package/dist/admin/core-2xoLiT0o.js.map +0 -1
  185. package/dist/auth/core-niW0sFLv.js.map +0 -1
  186. package/dist/demo/DemoDataTable-Z9xyV221.js.map +0 -1
  187. package/dist/demo/core-RCUw1Q-a.js.map +0 -1
@@ -1,4 +1,4 @@
1
- import { c as Text, h as ActionButton, p as Flex, v as useToast } from "./core-RCUw1Q-a.js";
1
+ import { f as Flex, h as ActionButton, s as Text, v as useToast } from "./core-B7LNjM78.js";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { IconCheck, IconExclamationMark, IconInfoCircle, IconX } from "@tabler/icons-react";
4
4
 
@@ -92,4 +92,4 @@ const DemoToast = () => {
92
92
 
93
93
  //#endregion
94
94
  export { DemoToast as default };
95
- //# sourceMappingURL=DemoToast-BgHDhWrX.js.map
95
+ //# sourceMappingURL=DemoToast-CUJEiPRa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DemoToast-BgHDhWrX.js","names":[],"sources":["../../src/demo/components/layout/DemoToast.tsx"],"sourcesContent":["import { ActionButton, Flex, Text, useToast } from \"@alepha/ui\";\nimport {\n IconCheck,\n IconExclamationMark,\n IconInfoCircle,\n IconX,\n} from \"@tabler/icons-react\";\n\nconst DemoToast = () => {\n const toast = useToast();\n\n return (\n <Flex col gap=\"xl\" p=\"xl\">\n <Text bold size=\"lg\">\n Toast Service\n </Text>\n <Text muted small>\n Notification toasts via the ToastService. Fire-and-forget notifications\n for user feedback.\n </Text>\n\n <Flex gap=\"md\" wrap=\"wrap\">\n <ActionButton\n icon={IconCheck}\n variant=\"light\"\n intent=\"success\"\n onClick={() => toast.success(\"Operation completed successfully.\")}\n >\n Success\n </ActionButton>\n\n <ActionButton\n icon={IconX}\n variant=\"light\"\n intent=\"danger\"\n onClick={() => toast.danger(\"Something went wrong.\")}\n >\n Error\n </ActionButton>\n\n <ActionButton\n icon={IconExclamationMark}\n variant=\"light\"\n intent=\"warning\"\n onClick={() => toast.warning(\"Please check your input.\")}\n >\n Warning\n </ActionButton>\n\n <ActionButton\n icon={IconInfoCircle}\n variant=\"light\"\n intent=\"info\"\n onClick={() => toast.info(\"Here is some useful information.\")}\n >\n Info\n </ActionButton>\n </Flex>\n\n <Flex col gap=\"md\">\n <Text bold small uppercase muted>\n With Title\n </Text>\n <Flex gap=\"md\" wrap=\"wrap\">\n <ActionButton\n variant=\"light\"\n intent=\"success\"\n onClick={() =>\n toast.success({\n message: \"Your changes have been saved.\",\n title: \"Saved\",\n })\n }\n >\n With Title\n </ActionButton>\n <ActionButton\n variant=\"light\"\n intent=\"danger\"\n onClick={() =>\n toast.danger({\n message: \"Failed to connect to the server.\",\n title: \"Connection Error\",\n autoClose: false,\n })\n }\n >\n Persistent\n </ActionButton>\n </Flex>\n </Flex>\n </Flex>\n );\n};\n\nexport default DemoToast;\n"],"mappings":";;;;;AAQA,MAAM,kBAAkB;CACtB,MAAM,QAAQ,UAAU;AAExB,QACE,qBAAC;EAAK;EAAI,KAAI;EAAK,GAAE;;GACnB,oBAAC;IAAK;IAAK,MAAK;cAAK;KAEd;GACP,oBAAC;IAAK;IAAM;cAAM;KAGX;GAEP,qBAAC;IAAK,KAAI;IAAK,MAAK;;KAClB,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,QAAQ,oCAAoC;gBAClE;OAEc;KAEf,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,OAAO,wBAAwB;gBACrD;OAEc;KAEf,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,QAAQ,2BAA2B;gBACzD;OAEc;KAEf,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,KAAK,mCAAmC;gBAC9D;OAEc;;KACV;GAEP,qBAAC;IAAK;IAAI,KAAI;eACZ,oBAAC;KAAK;KAAK;KAAM;KAAU;eAAM;MAE1B,EACP,qBAAC;KAAK,KAAI;KAAK,MAAK;gBAClB,oBAAC;MACC,SAAQ;MACR,QAAO;MACP,eACE,MAAM,QAAQ;OACZ,SAAS;OACT,OAAO;OACR,CAAC;gBAEL;OAEc,EACf,oBAAC;MACC,SAAQ;MACR,QAAO;MACP,eACE,MAAM,OAAO;OACX,SAAS;OACT,OAAO;OACP,WAAW;OACZ,CAAC;gBAEL;OAEc;MACV;KACF;;GACF"}
1
+ {"version":3,"file":"DemoToast-CUJEiPRa.js","names":[],"sources":["../../src/demo/components/layout/DemoToast.tsx"],"sourcesContent":["import { ActionButton, Flex, Text, useToast } from \"@alepha/ui\";\nimport {\n IconCheck,\n IconExclamationMark,\n IconInfoCircle,\n IconX,\n} from \"@tabler/icons-react\";\n\nconst DemoToast = () => {\n const toast = useToast();\n\n return (\n <Flex col gap=\"xl\" p=\"xl\">\n <Text bold size=\"lg\">\n Toast Service\n </Text>\n <Text muted small>\n Notification toasts via the ToastService. Fire-and-forget notifications\n for user feedback.\n </Text>\n\n <Flex gap=\"md\" wrap=\"wrap\">\n <ActionButton\n icon={IconCheck}\n variant=\"light\"\n intent=\"success\"\n onClick={() => toast.success(\"Operation completed successfully.\")}\n >\n Success\n </ActionButton>\n\n <ActionButton\n icon={IconX}\n variant=\"light\"\n intent=\"danger\"\n onClick={() => toast.danger(\"Something went wrong.\")}\n >\n Error\n </ActionButton>\n\n <ActionButton\n icon={IconExclamationMark}\n variant=\"light\"\n intent=\"warning\"\n onClick={() => toast.warning(\"Please check your input.\")}\n >\n Warning\n </ActionButton>\n\n <ActionButton\n icon={IconInfoCircle}\n variant=\"light\"\n intent=\"info\"\n onClick={() => toast.info(\"Here is some useful information.\")}\n >\n Info\n </ActionButton>\n </Flex>\n\n <Flex col gap=\"md\">\n <Text bold small uppercase muted>\n With Title\n </Text>\n <Flex gap=\"md\" wrap=\"wrap\">\n <ActionButton\n variant=\"light\"\n intent=\"success\"\n onClick={() =>\n toast.success({\n message: \"Your changes have been saved.\",\n title: \"Saved\",\n })\n }\n >\n With Title\n </ActionButton>\n <ActionButton\n variant=\"light\"\n intent=\"danger\"\n onClick={() =>\n toast.danger({\n message: \"Failed to connect to the server.\",\n title: \"Connection Error\",\n autoClose: false,\n })\n }\n >\n Persistent\n </ActionButton>\n </Flex>\n </Flex>\n </Flex>\n );\n};\n\nexport default DemoToast;\n"],"mappings":";;;;;AAQA,MAAM,kBAAkB;CACtB,MAAM,QAAQ,UAAU;AAExB,QACE,qBAAC;EAAK;EAAI,KAAI;EAAK,GAAE;;GACnB,oBAAC;IAAK;IAAK,MAAK;cAAK;KAEd;GACP,oBAAC;IAAK;IAAM;cAAM;KAGX;GAEP,qBAAC;IAAK,KAAI;IAAK,MAAK;;KAClB,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,QAAQ,oCAAoC;gBAClE;OAEc;KAEf,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,OAAO,wBAAwB;gBACrD;OAEc;KAEf,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,QAAQ,2BAA2B;gBACzD;OAEc;KAEf,oBAAC;MACC,MAAM;MACN,SAAQ;MACR,QAAO;MACP,eAAe,MAAM,KAAK,mCAAmC;gBAC9D;OAEc;;KACV;GAEP,qBAAC;IAAK;IAAI,KAAI;eACZ,oBAAC;KAAK;KAAK;KAAM;KAAU;eAAM;MAE1B,EACP,qBAAC;KAAK,KAAI;KAAK,MAAK;gBAClB,oBAAC;MACC,SAAQ;MACR,QAAO;MACP,eACE,MAAM,QAAQ;OACZ,SAAS;OACT,OAAO;OACR,CAAC;gBAEL;OAEc,EACf,oBAAC;MACC,SAAQ;MACR,QAAO;MACP,eACE,MAAM,OAAO;OACX,SAAS;OACT,OAAO;OACP,WAAW;OACZ,CAAC;gBAEL;OAEc;MACV;KACF;;GACF"}
@@ -1,5 +1,5 @@
1
- import { o as TypeForm } from "./core-RCUw1Q-a.js";
2
- import { t as Showcase } from "./Showcase-Dq3MISpd.js";
1
+ import { a as TypeForm } from "./core-B7LNjM78.js";
2
+ import { t as Showcase } from "./Showcase-BtEU0pY9.js";
3
3
  import { t } from "alepha";
4
4
  import { useForm } from "alepha/react/form";
5
5
  import { jsx } from "react/jsx-runtime";
@@ -79,4 +79,4 @@ const DemoTypeForm = () => {
79
79
 
80
80
  //#endregion
81
81
  export { DemoTypeForm as default };
82
- //# sourceMappingURL=DemoTypeForm-DDzWoMSV.js.map
82
+ //# sourceMappingURL=DemoTypeForm-C1dNkahD.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DemoTypeForm-DDzWoMSV.js","names":[],"sources":["../../src/demo/components/core/DemoTypeForm.tsx"],"sourcesContent":["import { TypeForm } from \"@alepha/ui\";\nimport { t } from \"alepha\";\nimport { useForm } from \"alepha/react/form\";\nimport Showcase from \"../shared/Showcase.tsx\";\n\nconst formSchema = t.object({\n username: t.text({ title: \"Username\", default: \"\" }),\n email: t.email({ title: \"Email\", default: \"\" }),\n age: t.integer({ title: \"Age\", minimum: 0, maximum: 120 }),\n role: t.enum([\"admin\", \"user\", \"guest\"], { title: \"Role\", default: \"user\" }),\n subscribe: t.boolean({ title: \"Subscribe\", default: false }),\n});\n\nconst showcaseSchema = t.object({\n columns: t.integer({\n title: \"Columns\",\n default: 1,\n minimum: 1,\n maximum: 4,\n $control: { slider: true },\n }),\n fill: t.boolean({\n title: \"Fill Width\",\n default: false,\n $control: { switch: true },\n }),\n skipSubmitButton: t.boolean({\n title: \"Hide Submit\",\n default: false,\n $control: { switch: true },\n }),\n});\n\nconst DemoTypeForm = () => {\n const form = useForm(\n {\n schema: formSchema,\n handler: (values) => {\n alert(JSON.stringify(values, null, 2));\n },\n },\n [],\n );\n\n return (\n <Showcase\n title=\"TypeForm\"\n schema={showcaseSchema}\n initialValues={{\n columns: 1,\n fill: false,\n skipSubmitButton: false,\n }}\n columns={1}\n >\n {(props) => (\n <TypeForm\n form={form}\n columns={props.columns}\n fill={props.fill}\n skipSubmitButton={props.skipSubmitButton}\n submitButtonProps={{ children: \"Submit\" }}\n />\n )}\n </Showcase>\n );\n};\n\nexport default DemoTypeForm;\n"],"mappings":";;;;;;;AAKA,MAAM,aAAa,EAAE,OAAO;CAC1B,UAAU,EAAE,KAAK;EAAE,OAAO;EAAY,SAAS;EAAI,CAAC;CACpD,OAAO,EAAE,MAAM;EAAE,OAAO;EAAS,SAAS;EAAI,CAAC;CAC/C,KAAK,EAAE,QAAQ;EAAE,OAAO;EAAO,SAAS;EAAG,SAAS;EAAK,CAAC;CAC1D,MAAM,EAAE,KAAK;EAAC;EAAS;EAAQ;EAAQ,EAAE;EAAE,OAAO;EAAQ,SAAS;EAAQ,CAAC;CAC5E,WAAW,EAAE,QAAQ;EAAE,OAAO;EAAa,SAAS;EAAO,CAAC;CAC7D,CAAC;AAEF,MAAM,iBAAiB,EAAE,OAAO;CAC9B,SAAS,EAAE,QAAQ;EACjB,OAAO;EACP,SAAS;EACT,SAAS;EACT,SAAS;EACT,UAAU,EAAE,QAAQ,MAAM;EAC3B,CAAC;CACF,MAAM,EAAE,QAAQ;EACd,OAAO;EACP,SAAS;EACT,UAAU,EAAE,QAAQ,MAAM;EAC3B,CAAC;CACF,kBAAkB,EAAE,QAAQ;EAC1B,OAAO;EACP,SAAS;EACT,UAAU,EAAE,QAAQ,MAAM;EAC3B,CAAC;CACH,CAAC;AAEF,MAAM,qBAAqB;CACzB,MAAM,OAAO,QACX;EACE,QAAQ;EACR,UAAU,WAAW;AACnB,SAAM,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;;EAEzC,EACD,EAAE,CACH;AAED,QACE,oBAAC;EACC,OAAM;EACN,QAAQ;EACR,eAAe;GACb,SAAS;GACT,MAAM;GACN,kBAAkB;GACnB;EACD,SAAS;aAEP,UACA,oBAAC;GACO;GACN,SAAS,MAAM;GACf,MAAM,MAAM;GACZ,kBAAkB,MAAM;GACxB,mBAAmB,EAAE,UAAU,UAAU;IACzC;GAEK"}
1
+ {"version":3,"file":"DemoTypeForm-C1dNkahD.js","names":[],"sources":["../../src/demo/components/core/DemoTypeForm.tsx"],"sourcesContent":["import { TypeForm } from \"@alepha/ui\";\nimport { t } from \"alepha\";\nimport { useForm } from \"alepha/react/form\";\nimport Showcase from \"../shared/Showcase.tsx\";\n\nconst formSchema = t.object({\n username: t.text({ title: \"Username\", default: \"\" }),\n email: t.email({ title: \"Email\", default: \"\" }),\n age: t.integer({ title: \"Age\", minimum: 0, maximum: 120 }),\n role: t.enum([\"admin\", \"user\", \"guest\"], { title: \"Role\", default: \"user\" }),\n subscribe: t.boolean({ title: \"Subscribe\", default: false }),\n});\n\nconst showcaseSchema = t.object({\n columns: t.integer({\n title: \"Columns\",\n default: 1,\n minimum: 1,\n maximum: 4,\n $control: { slider: true },\n }),\n fill: t.boolean({\n title: \"Fill Width\",\n default: false,\n $control: { switch: true },\n }),\n skipSubmitButton: t.boolean({\n title: \"Hide Submit\",\n default: false,\n $control: { switch: true },\n }),\n});\n\nconst DemoTypeForm = () => {\n const form = useForm(\n {\n schema: formSchema,\n handler: (values) => {\n alert(JSON.stringify(values, null, 2));\n },\n },\n [],\n );\n\n return (\n <Showcase\n title=\"TypeForm\"\n schema={showcaseSchema}\n initialValues={{\n columns: 1,\n fill: false,\n skipSubmitButton: false,\n }}\n columns={1}\n >\n {(props) => (\n <TypeForm\n form={form}\n columns={props.columns}\n fill={props.fill}\n skipSubmitButton={props.skipSubmitButton}\n submitButtonProps={{ children: \"Submit\" }}\n />\n )}\n </Showcase>\n );\n};\n\nexport default DemoTypeForm;\n"],"mappings":";;;;;;;AAKA,MAAM,aAAa,EAAE,OAAO;CAC1B,UAAU,EAAE,KAAK;EAAE,OAAO;EAAY,SAAS;EAAI,CAAC;CACpD,OAAO,EAAE,MAAM;EAAE,OAAO;EAAS,SAAS;EAAI,CAAC;CAC/C,KAAK,EAAE,QAAQ;EAAE,OAAO;EAAO,SAAS;EAAG,SAAS;EAAK,CAAC;CAC1D,MAAM,EAAE,KAAK;EAAC;EAAS;EAAQ;EAAQ,EAAE;EAAE,OAAO;EAAQ,SAAS;EAAQ,CAAC;CAC5E,WAAW,EAAE,QAAQ;EAAE,OAAO;EAAa,SAAS;EAAO,CAAC;CAC7D,CAAC;AAEF,MAAM,iBAAiB,EAAE,OAAO;CAC9B,SAAS,EAAE,QAAQ;EACjB,OAAO;EACP,SAAS;EACT,SAAS;EACT,SAAS;EACT,UAAU,EAAE,QAAQ,MAAM;EAC3B,CAAC;CACF,MAAM,EAAE,QAAQ;EACd,OAAO;EACP,SAAS;EACT,UAAU,EAAE,QAAQ,MAAM;EAC3B,CAAC;CACF,kBAAkB,EAAE,QAAQ;EAC1B,OAAO;EACP,SAAS;EACT,UAAU,EAAE,QAAQ,MAAM;EAC3B,CAAC;CACH,CAAC;AAEF,MAAM,qBAAqB;CACzB,MAAM,OAAO,QACX;EACE,QAAQ;EACR,UAAU,WAAW;AACnB,SAAM,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC;;EAEzC,EACD,EAAE,CACH;AAED,QACE,oBAAC;EACC,OAAM;EACN,QAAQ;EACR,eAAe;GACb,SAAS;GACT,MAAM;GACN,kBAAkB;GACnB;EACD,SAAS;aAEP,UACA,oBAAC;GACO;GACN,SAAS,MAAM;GACf,MAAM,MAAM;GACZ,kBAAkB,MAAM;GACxB,mBAAmB,EAAE,UAAU,UAAU;IACzC;GAEK"}
@@ -1,11 +1,11 @@
1
- import "./core-RCUw1Q-a.js";
1
+ import "./core-B7LNjM78.js";
2
2
  import "./IconGoogle-CSQLPYwX.js";
3
- import "./Login-hSOU3jZc.js";
4
- import "./Register-a70LPgs2.js";
5
- import "./ResetPassword-DWN0lzr5.js";
6
- import { t as VerifyEmail } from "./VerifyEmail-DZWL72K4.js";
7
- import "./auth-d6n3xbug.js";
8
- import { t as Showcase } from "./Showcase-Dq3MISpd.js";
3
+ import "./Login-CoYf_P_F.js";
4
+ import "./Register-fXHmBpr3.js";
5
+ import "./ResetPassword-CAPj8MO3.js";
6
+ import { t as VerifyEmail } from "./VerifyEmail-DFmdCdYs.js";
7
+ import "./auth-Djd7SKiw.js";
8
+ import { t as Showcase } from "./Showcase-BtEU0pY9.js";
9
9
  import { t } from "alepha";
10
10
  import { jsx } from "react/jsx-runtime";
11
11
 
@@ -27,4 +27,4 @@ const DemoVerifyEmail = () => {
27
27
 
28
28
  //#endregion
29
29
  export { DemoVerifyEmail as default };
30
- //# sourceMappingURL=DemoVerifyEmail-C_Irdnov.js.map
30
+ //# sourceMappingURL=DemoVerifyEmail-D9EcXZ38.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"DemoVerifyEmail-C_Irdnov.js","names":[],"sources":["../../src/demo/components/auth/DemoVerifyEmail.tsx"],"sourcesContent":["import { VerifyEmail } from \"@alepha/ui/auth\";\nimport { t } from \"alepha\";\nimport Showcase from \"../shared/Showcase.tsx\";\n\nconst showcaseSchema = t.object({\n placeholder: t.boolean({\n title: \"Demo Mode\",\n default: true,\n $control: { switch: true },\n }),\n});\n\nconst DemoVerifyEmail = () => {\n return (\n <Showcase\n title=\"VerifyEmail\"\n schema={showcaseSchema}\n initialValues={{\n placeholder: true,\n }}\n columns={1}\n >\n {() => <VerifyEmail />}\n </Showcase>\n );\n};\n\nexport default DemoVerifyEmail;\n"],"mappings":";;;;;;;;;;;;AAIA,MAAM,iBAAiB,EAAE,OAAO,EAC9B,aAAa,EAAE,QAAQ;CACrB,OAAO;CACP,SAAS;CACT,UAAU,EAAE,QAAQ,MAAM;CAC3B,CAAC,EACH,CAAC;AAEF,MAAM,wBAAwB;AAC5B,QACE,oBAAC;EACC,OAAM;EACN,QAAQ;EACR,eAAe,EACb,aAAa,MACd;EACD,SAAS;kBAEF,oBAAC,gBAAc;GACb"}
1
+ {"version":3,"file":"DemoVerifyEmail-D9EcXZ38.js","names":[],"sources":["../../src/demo/components/auth/DemoVerifyEmail.tsx"],"sourcesContent":["import { VerifyEmail } from \"@alepha/ui/auth\";\nimport { t } from \"alepha\";\nimport Showcase from \"../shared/Showcase.tsx\";\n\nconst showcaseSchema = t.object({\n placeholder: t.boolean({\n title: \"Demo Mode\",\n default: true,\n $control: { switch: true },\n }),\n});\n\nconst DemoVerifyEmail = () => {\n return (\n <Showcase\n title=\"VerifyEmail\"\n schema={showcaseSchema}\n initialValues={{\n placeholder: true,\n }}\n columns={1}\n >\n {() => <VerifyEmail />}\n </Showcase>\n );\n};\n\nexport default DemoVerifyEmail;\n"],"mappings":";;;;;;;;;;;;AAIA,MAAM,iBAAiB,EAAE,OAAO,EAC9B,aAAa,EAAE,QAAQ;CACrB,OAAO;CACP,SAAS;CACT,UAAU,EAAE,QAAQ,MAAM;CAC3B,CAAC,EACH,CAAC;AAEF,MAAM,wBAAwB;AAC5B,QACE,oBAAC;EACC,OAAM;EACN,QAAQ;EACR,eAAe,EACb,aAAa,MACd;EACD,SAAS;kBAEF,oBAAC,gBAAc;GACb"}
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { h as ActionButton, n as capitalize, s as Control } from "./core-RCUw1Q-a.js";
2
+ import { h as ActionButton, n as capitalize, o as Control } from "./core-B7LNjM78.js";
3
3
  import { n as IconGithub, t as IconGoogle } from "./IconGoogle-CSQLPYwX.js";
4
4
  import { AlephaError, t } from "alepha";
5
5
  import { FormValidationError, useForm } from "alepha/react/form";
@@ -216,4 +216,4 @@ const leftSection = (name) => {
216
216
 
217
217
  //#endregion
218
218
  export { Login_exports as n, Login as t };
219
- //# sourceMappingURL=Login-hSOU3jZc.js.map
219
+ //# sourceMappingURL=Login-CoYf_P_F.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Login-hSOU3jZc.js","names":[],"sources":["../../src/auth/components/Login.tsx"],"sourcesContent":["import { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Card, Flex, Image, Text, Title } from \"@mantine/core\";\nimport { IconLock, IconUser } from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type { RealmConfig } from \"alepha/api/users\";\nimport { useAuth } from \"alepha/react/auth\";\nimport { FormValidationError, useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { HttpError } from \"alepha/server\";\nimport { useMemo } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface LoginProps {\n realmConfig: RealmConfig;\n}\n\nconst Login = (props: LoginProps) => {\n const auth = useAuth();\n const router = useRouter<AuthRouter>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings;\n\n // Determine what login methods are available\n const loginMethods = useMemo(() => {\n const methods = [];\n if (settings.usernameEnabled !== false) methods.push(\"username\");\n if (settings.emailEnabled !== false) methods.push(\"email\");\n if (settings.phoneEnabled === true) methods.push(\"phone\");\n return methods;\n }, [settings]);\n\n // Create identifier title based on enabled methods\n const identifierTitle = useMemo(() => {\n if (loginMethods.length === 0) return tr(\"loginUsername\");\n if (loginMethods.length === 1) {\n if (loginMethods[0] === \"username\") return tr(\"loginUsername\");\n if (loginMethods[0] === \"email\") return tr(\"loginEmail\");\n if (loginMethods[0] === \"phone\") return tr(\"loginPhone\");\n }\n const labels = loginMethods.map((m) => {\n if (m === \"username\") return tr(\"loginUsername\").toLowerCase();\n if (m === \"email\") return tr(\"loginEmail\").toLowerCase();\n if (m === \"phone\") return tr(\"loginPhone\").toLowerCase();\n return m;\n });\n return capitalize(\n `${labels.slice(0, -1).join(\", \")} or ${labels[labels.length - 1]}`,\n );\n }, [loginMethods, tr]);\n\n const form = useForm({\n schema: t.object({\n identifier: t.string({\n minLength: 1,\n }),\n password: t.string({\n minLength: settings.passwordPolicy?.minLength || 6,\n }),\n }),\n handler: async (data) => {\n if (!credentialsProvider) {\n throw new AlephaError(\"Credentials provider not configured\");\n }\n\n try {\n await auth.login(credentialsProvider.name, {\n username: data.identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n await router.push(router.query.r || \"/\");\n } catch (error) {\n if (\n error instanceof HttpError &&\n error.error === \"InvalidCredentialsError\"\n ) {\n throw new FormValidationError({\n message: \"Invalid identifier or password\",\n path: \"/password\",\n });\n }\n throw error;\n }\n },\n });\n\n const getAutoCompleteType = () => {\n if (loginMethods.includes(\"email\")) {\n return \"email\";\n }\n if (loginMethods.includes(\"username\")) {\n return \"username\";\n }\n if (loginMethods.includes(\"phone\")) {\n return \"tel\";\n }\n return \"username\";\n };\n\n const externalLoginMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalLoginMethods.length > 0;\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 {/* Credentials login form */}\n {credentialsProvider && (\n <>\n <form {...form.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Control\n title={identifierTitle}\n input={form.input.identifier}\n icon={IconUser}\n text={{\n autoComplete: getAutoCompleteType(),\n }}\n />\n <Control\n title={tr(\"loginPassword\")}\n input={form.input.password}\n icon={IconLock}\n password={{\n autoComplete: \"current-password\",\n }}\n />\n <ActionButton variant={\"filled\"} form={form}>\n {tr(\"loginSignIn\")}\n </ActionButton>\n </Flex>\n </form>\n {settings.resetPasswordAllowed && (\n <Text size=\"sm\" ta=\"center\">\n <ActionButton\n href={router.path(\"resetPassword\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginForgotPassword\")}\n </ActionButton>\n </Text>\n )}\n </>\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(\"loginOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Flex>\n )}\n\n {/* External login methods */}\n {externalLoginMethods.length > 0 && (\n <Flex direction=\"column\" gap={\"sm\"}>\n {externalLoginMethods.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(\"loginContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Flex>\n )}\n\n {/* Registration link */}\n {settings.registrationAllowed && (\n <Text size=\"sm\" ta=\"center\">\n {tr(\"loginNoAccount\")}{\" \"}\n <ActionButton\n href={router.path(\"register\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginSignUp\")}\n </ActionButton>\n </Text>\n )}\n </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={\"/\"}>\n {tr(\"loginCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default Login;\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
+ {"version":3,"file":"Login-CoYf_P_F.js","names":[],"sources":["../../src/auth/components/Login.tsx"],"sourcesContent":["import { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Card, Flex, Image, Text, Title } from \"@mantine/core\";\nimport { IconLock, IconUser } from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type { RealmConfig } from \"alepha/api/users\";\nimport { useAuth } from \"alepha/react/auth\";\nimport { FormValidationError, useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { HttpError } from \"alepha/server\";\nimport { useMemo } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface LoginProps {\n realmConfig: RealmConfig;\n}\n\nconst Login = (props: LoginProps) => {\n const auth = useAuth();\n const router = useRouter<AuthRouter>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings;\n\n // Determine what login methods are available\n const loginMethods = useMemo(() => {\n const methods = [];\n if (settings.usernameEnabled !== false) methods.push(\"username\");\n if (settings.emailEnabled !== false) methods.push(\"email\");\n if (settings.phoneEnabled === true) methods.push(\"phone\");\n return methods;\n }, [settings]);\n\n // Create identifier title based on enabled methods\n const identifierTitle = useMemo(() => {\n if (loginMethods.length === 0) return tr(\"loginUsername\");\n if (loginMethods.length === 1) {\n if (loginMethods[0] === \"username\") return tr(\"loginUsername\");\n if (loginMethods[0] === \"email\") return tr(\"loginEmail\");\n if (loginMethods[0] === \"phone\") return tr(\"loginPhone\");\n }\n const labels = loginMethods.map((m) => {\n if (m === \"username\") return tr(\"loginUsername\").toLowerCase();\n if (m === \"email\") return tr(\"loginEmail\").toLowerCase();\n if (m === \"phone\") return tr(\"loginPhone\").toLowerCase();\n return m;\n });\n return capitalize(\n `${labels.slice(0, -1).join(\", \")} or ${labels[labels.length - 1]}`,\n );\n }, [loginMethods, tr]);\n\n const form = useForm({\n schema: t.object({\n identifier: t.string({\n minLength: 1,\n }),\n password: t.string({\n minLength: settings.passwordPolicy?.minLength || 6,\n }),\n }),\n handler: async (data) => {\n if (!credentialsProvider) {\n throw new AlephaError(\"Credentials provider not configured\");\n }\n\n try {\n await auth.login(credentialsProvider.name, {\n username: data.identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n await router.push(router.query.r || \"/\");\n } catch (error) {\n if (\n error instanceof HttpError &&\n error.error === \"InvalidCredentialsError\"\n ) {\n throw new FormValidationError({\n message: \"Invalid identifier or password\",\n path: \"/password\",\n });\n }\n throw error;\n }\n },\n });\n\n const getAutoCompleteType = () => {\n if (loginMethods.includes(\"email\")) {\n return \"email\";\n }\n if (loginMethods.includes(\"username\")) {\n return \"username\";\n }\n if (loginMethods.includes(\"phone\")) {\n return \"tel\";\n }\n return \"username\";\n };\n\n const externalLoginMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalLoginMethods.length > 0;\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 {/* Credentials login form */}\n {credentialsProvider && (\n <>\n <form {...form.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Control\n title={identifierTitle}\n input={form.input.identifier}\n icon={IconUser}\n text={{\n autoComplete: getAutoCompleteType(),\n }}\n />\n <Control\n title={tr(\"loginPassword\")}\n input={form.input.password}\n icon={IconLock}\n password={{\n autoComplete: \"current-password\",\n }}\n />\n <ActionButton variant={\"filled\"} form={form}>\n {tr(\"loginSignIn\")}\n </ActionButton>\n </Flex>\n </form>\n {settings.resetPasswordAllowed && (\n <Text size=\"sm\" ta=\"center\">\n <ActionButton\n href={router.path(\"resetPassword\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginForgotPassword\")}\n </ActionButton>\n </Text>\n )}\n </>\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(\"loginOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Flex>\n )}\n\n {/* External login methods */}\n {externalLoginMethods.length > 0 && (\n <Flex direction=\"column\" gap={\"sm\"}>\n {externalLoginMethods.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(\"loginContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Flex>\n )}\n\n {/* Registration link */}\n {settings.registrationAllowed && (\n <Text size=\"sm\" ta=\"center\">\n {tr(\"loginNoAccount\")}{\" \"}\n <ActionButton\n href={router.path(\"register\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"loginSignUp\")}\n </ActionButton>\n </Text>\n )}\n </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={\"/\"}>\n {tr(\"loginCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default Login;\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,4 +1,4 @@
1
- import { h as ActionButton } from "./core-RCUw1Q-a.js";
1
+ import { h as ActionButton } from "./core-B7LNjM78.js";
2
2
  import { Avatar, Badge, Card, Flex, Text, Title } from "@mantine/core";
3
3
  import { jsx, jsxs } from "react/jsx-runtime";
4
4
  import { IconAt, IconCalendar, IconId, IconShield, IconUser } from "@tabler/icons-react";
@@ -152,4 +152,4 @@ const ProfileField = ({ icon, label, children }) => {
152
152
 
153
153
  //#endregion
154
154
  export { Profile as default };
155
- //# sourceMappingURL=Profile-CWqti7FB.js.map
155
+ //# sourceMappingURL=Profile-BE_Y3co2.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Profile-B-c9pCPf.js","names":[],"sources":["../../src/auth/components/Profile.tsx"],"sourcesContent":["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\";\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\ninterface ProfileFieldProps {\n icon: React.ReactNode;\n label: string;\n children: React.ReactNode;\n}\n\nconst ProfileField = ({ icon, label, children }: ProfileFieldProps) => {\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 Profile;\n"],"mappings":";;;;;;;;AAaA,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;;AAUX,MAAM,gBAAgB,EAAE,MAAM,OAAO,eAAkC;AACrE,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"}
1
+ {"version":3,"file":"Profile-BE_Y3co2.js","names":[],"sources":["../../src/auth/components/Profile.tsx"],"sourcesContent":["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\";\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\ninterface ProfileFieldProps {\n icon: React.ReactNode;\n label: string;\n children: React.ReactNode;\n}\n\nconst ProfileField = ({ icon, label, children }: ProfileFieldProps) => {\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 Profile;\n"],"mappings":";;;;;;;;AAaA,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;;AAUX,MAAM,gBAAgB,EAAE,MAAM,OAAO,eAAkC;AACrE,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"}
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { h as ActionButton, n as capitalize, s as Control } from "./core-RCUw1Q-a.js";
2
+ import { h as ActionButton, n as capitalize, o as Control } from "./core-B7LNjM78.js";
3
3
  import { n as IconGithub, t as IconGoogle } from "./IconGoogle-CSQLPYwX.js";
4
4
  import { TypeBoxError, t } from "alepha";
5
5
  import { useForm } from "alepha/react/form";
@@ -372,4 +372,4 @@ const leftSection = (name) => {
372
372
 
373
373
  //#endregion
374
374
  export { Register_exports as n, Register as t };
375
- //# sourceMappingURL=Register-a70LPgs2.js.map
375
+ //# sourceMappingURL=Register-fXHmBpr3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Register-Cs10l8vX.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 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 type { AuthRouter } from \"../AuthRouter.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface RegisterProps {\n realmConfig: RealmConfig;\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<AuthRouter>();\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.usernameRequired) required.push(\"username\");\n if (settings.emailRequired) required.push(\"email\");\n if (settings.phoneRequired) 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\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 // Registration form phase UI\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 {!isRegistrationAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"registerDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\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.usernameEnabled !== false &&\n form.input.username && (\n <Control\n title={tr(\"registerUsername\")}\n input={form.input.username}\n icon={<IconUser />}\n text={{\n autoComplete: \"username\",\n }}\n />\n )}\n {settings.emailEnabled !== false && form.input.email && (\n <Control\n title={tr(\"registerEmail\")}\n input={form.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n }}\n />\n )}\n {settings.phoneEnabled === true &&\n form.input.phoneNumber && (\n <Control\n title={tr(\"registerPhone\")}\n input={form.input.phoneNumber}\n icon={<IconPhone />}\n text={{\n autoComplete: \"tel\",\n }}\n />\n )}\n <Control\n title={tr(\"registerPassword\")}\n input={form.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <Control\n title={tr(\"registerConfirmPassword\")}\n input={form.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton\n form={form}\n color={\"blue\"}\n variant={\"filled\"}\n >\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={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"registerSignIn\")}\n </ActionButton>\n </Text>\n </>\n )}\n </Flex>\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
+ {"version":3,"file":"Register-fXHmBpr3.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 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 type { AuthRouter } from \"../AuthRouter.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface RegisterProps {\n realmConfig: RealmConfig;\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<AuthRouter>();\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.usernameRequired) required.push(\"username\");\n if (settings.emailRequired) required.push(\"email\");\n if (settings.phoneRequired) 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\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 // Registration form phase UI\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 {!isRegistrationAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"registerDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\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.usernameEnabled !== false &&\n form.input.username && (\n <Control\n title={tr(\"registerUsername\")}\n input={form.input.username}\n icon={<IconUser />}\n text={{\n autoComplete: \"username\",\n }}\n />\n )}\n {settings.emailEnabled !== false && form.input.email && (\n <Control\n title={tr(\"registerEmail\")}\n input={form.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n }}\n />\n )}\n {settings.phoneEnabled === true &&\n form.input.phoneNumber && (\n <Control\n title={tr(\"registerPhone\")}\n input={form.input.phoneNumber}\n icon={<IconPhone />}\n text={{\n autoComplete: \"tel\",\n }}\n />\n )}\n <Control\n title={tr(\"registerPassword\")}\n input={form.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <Control\n title={tr(\"registerConfirmPassword\")}\n input={form.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton\n form={form}\n color={\"blue\"}\n variant={\"filled\"}\n >\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={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\n anchorProps={{ inherit: true }}\n >\n {tr(\"registerSignIn\")}\n </ActionButton>\n </Text>\n </>\n )}\n </Flex>\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 { i as ActionButton, r as Control } from "./core-niW0sFLv.js";
2
+ import { h as ActionButton, o as Control } from "./core-B7LNjM78.js";
3
3
  import { AlephaError, t } from "alepha";
4
4
  import { useForm } from "alepha/react/form";
5
5
  import { useI18n } from "alepha/react/i18n";
@@ -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-CqfTk1FI.js.map
286
+ //# sourceMappingURL=ResetPassword-CAPj8MO3.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResetPassword-DWN0lzr5.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\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\n\nexport interface ResetPasswordProps {\n realmConfig: RealmConfig;\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<AuthRouter>();\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={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\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 title={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 title={tr(\"resetPasswordNewPassword\")}\n input={passwordForm.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n autoFocus: true,\n }}\n />\n <Control\n title={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={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\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
+ {"version":3,"file":"ResetPassword-CAPj8MO3.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\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\n\nexport interface ResetPasswordProps {\n realmConfig: RealmConfig;\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<AuthRouter>();\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={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\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 title={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 title={tr(\"resetPasswordNewPassword\")}\n input={passwordForm.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n autoFocus: true,\n }}\n />\n <Control\n title={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={router.path(\"login\", {\n query: { realm: props.realmConfig.realmName },\n })}\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":";;;;;;;;;;;;;;;AAqCA,MAAM,iBAAiB,UAA8B;CACnD,MAAM,SAAS,WAAuB;CACtC,MAAM,WAAW,WAA2B;CAC5C,MAAM,EAAE,OAAO,SAAyB;CACxC,MAAM,CAAC,YAAY,iBAAiB,SAAqB,EAAE,MAAM,SAAS,CAAC;CAC3E,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CACvD,MAAM,CAAC,cAAc,mBAAmB,SAAS,MAAM;CACvD,MAAM,WAAW,OAAO,MAAM,KAAK;CAEnC,MAAM,WAAW,MAAM,YAAY;CACnC,MAAM,yBAAyB,UAAU,yBAAyB;CAGlE,MAAM,YAAY,QAAQ;EACxB,QAAQ;EACR,SAAS,OAAO,SAAS;AACvB,YAAS,KAAK;AAMd,iBAAc;IACZ,MAAM;IACN,QAPa,MAAM,SAAS,0BAA0B;KACtD,OAAO,EAAE,eAAe,MAAM,YAAY,WAAW;KACrD,MAAM,EAAE,OAAO,KAAK,OAAO;KAC5B,CAAC;IAKA,OAAO,KAAK;IACb,CAAC;;EAEL,CAAC;CAGF,MAAM,eAAe,QACnB;EACE,QAAQ,EAAE,OAAO;GACf,UAAU,EAAE,OAAO,EAAE,WAAW,GAAG,CAAC;GACpC,iBAAiB,EAAE,OAAO,EAAE,WAAW,GAAG,CAAC;GAC5C,CAAC;EACF,SAAS,OAAO,SAAS;AACvB,OAAI,KAAK,aAAa,KAAK,gBACzB,OAAM,IAAI,YAAY,yBAAyB;AAGjD,OAAI,CAAC,WAAW,UAAU,CAAC,WAAW,KACpC,OAAM,IAAI,YAAY,sBAAsB;AAG9C,SAAM,SAAS,sBAAsB,EACnC,MAAM;IACJ,UAAU,WAAW,OAAO;IAC5B,MAAM,WAAW;IACjB,aAAa,KAAK;IACnB,EACF,CAAC;AAEF,iBAAc,EAAE,MAAM,WAAW,CAAC;;EAErC,EACD,CAAC,WAAW,QAAQ,WAAW,KAAK,CACrC;CAED,MAAM,sBAAsB,UAAkB;AAC5C,MAAI,MAAM,WAAW,EACnB,gBAAe,UAAU;GACvB,GAAG;GACH,MAAM;GACN,MAAM;GACP,EAAE;;CAIP,MAAM,mBAAmB,YAAY;AACnC,MAAI,CAAC,WAAW,MAAO;AAEvB,kBAAgB,KAAK;AACrB,WAAS,KAAK;AAEd,MAAI;GACF,MAAM,SAAS,MAAM,SAAS,0BAA0B;IACtD,OAAO,EAAE,eAAe,MAAM,YAAY,WAAW;IACrD,MAAM,EAAE,OAAO,WAAW,OAAO;IAClC,CAAC;AAEF,kBAAe,UAAU;IACvB,GAAG;IACH;IACD,EAAE;WACI,KAAK;AACZ,YAAS,eAAe,QAAQ,IAAI,UAAU,wBAAwB;YAC9D;AACR,mBAAgB,MAAM;;;AAI1B,QACE,oBAAC;EAAK,MAAM;EAAG,SAAS;EAAU,OAAO;YACvC,qBAAC;GAAK,WAAU;GAAS,KAAK;GAAM,GAAG;cACrC,oBAAC;IAAK;IAAW,GAAG;IAAM,IAAI;cAC5B,qBAAC;KAAK,WAAU;KAAS,KAAK;;OAE1B,SAAS,WACT,SAAS,eACT,SAAS,gBACT,qBAAC;OAAK,WAAU;OAAS,KAAK;OAAM,OAAM;OAAS,IAAG;;QACnD,SAAS,WACR,oBAAC;SACC,KAAK,SAAS;SACd,KAAK,SAAS,eAAe,MAAM,YAAY;SAC/C,GAAG;SACH,GAAE;SACF,KAAI;UACJ;QAEH,SAAS,eACR,oBAAC;SAAM,OAAO;SAAG,IAAG;mBACjB,SAAS;UACJ;QAET,SAAS,eACR,oBAAC;SAAK,MAAK;SAAK,GAAE;SAAS,IAAG;mBAC3B,SAAS;UACL;;QAEJ;MAGR,SACC,oBAAC;OAAM,SAAQ;OAAQ,OAAM;OAAM,MAAM,oBAAC,oBAAkB;iBAC1D,oBAAC;QAAK,MAAK;kBAAM;SAAa;QACxB;MAGT,CAAC,yBACA,4CACE,oBAAC;OACC,SAAQ;OACR,OAAM;OACN,MAAM,oBAAC,oBAAkB;iBAEzB,oBAAC;QAAK,MAAK;kBAAM,GAAG,wBAAwB;SAAQ;QAC9C,EACR,oBAAC;OACC,MAAM,OAAO,KAAK,SAAS,EACzB,OAAO,EAAE,OAAO,MAAM,YAAY,WAAW,EAC9C,CAAC;iBAED,GAAG,4BAA4B;QACnB,IACd,GACD,WAAW,SAAS,UACtB,oBAAC;OAAK,GAAI,UAAU;iBAClB,qBAAC;QAAK,WAAU;QAAS,MAAM;QAAG,KAAK;;SACrC,oBAAC;UAAK,MAAK;UAAK,IAAI;UAAK,IAAG;oBACzB,GAAG,qBAAqB;WACpB;SACP,oBAAC;UAAK,MAAK;UAAK,GAAE;oBACf,GAAG,0BAA0B;WACzB;SACP,oBAAC;UACC,OAAO,GAAG,qBAAqB;UAC/B,OAAO,UAAU,MAAM;UACvB,MAAM,oBAAC,aAAW;UAClB,MAAM;WACJ,cAAc;WACd,WAAW;WACX,UAAU,CAAC;WACZ;WACD;SACF,oBAAC;UACC,MAAM;UACN,UAAU,CAAC;oBAEV,GAAG,wBAAwB;WACf;;SACV;QACF,GACL,WAAW,SAAS,SACtB,qBAAC;OAAK,WAAU;OAAS,KAAK;;QAC5B,oBAAC;SAAK,MAAK;SAAK,IAAI;SAAK,IAAG;mBACzB,GAAG,qBAAqB;UACpB;QACP,oBAAC;SAAM,SAAQ;SAAQ,OAAM;SAAO,MAAM,oBAAC,mBAAiB;mBAC1D,oBAAC;UAAK,MAAK;oBAAM,GAAG,wBAAwB;WAAQ;UAC9C;QACR,oBAAC;SAAK,MAAK;SAAK,GAAE;SAAS,IAAG;mBAC3B,GAAG,yBAAyB;UACxB;QACP,oBAAC;SAAK,SAAQ;mBACZ,oBAAC;UACC,QAAQ;UACR,MAAK;UACL;UACA;UACA,YAAY;UACZ,cAAW;WACX;UACG;QACP,oBAAC;SACC,SAAQ;SACR,SAAS;SACT,SAAS;mBAER,GAAG,0BAA0B;UACjB;;QACV,GACL,WAAW,SAAS,aACtB,oBAAC;OAAK,GAAI,aAAa;iBACrB,qBAAC;QAAK,WAAU;QAAS,MAAM;QAAG,KAAK;;SACrC,oBAAC;UAAK,MAAK;UAAK,IAAI;UAAK,IAAG;oBACzB,GAAG,qBAAqB;WACpB;SACP,oBAAC;UAAK,MAAK;UAAK,GAAE;oBACf,GAAG,gCAAgC;WAC/B;SACP,oBAAC;UACC,OAAO,GAAG,2BAA2B;UACrC,OAAO,aAAa,MAAM;UAC1B,MAAM,oBAAC,aAAW;UAClB,UAAU;WACR,cAAc;WACd,WAAW;WACZ;WACD;SACF,oBAAC;UACC,OAAO,GAAG,+BAA+B;UACzC,OAAO,aAAa,MAAM;UAC1B,MAAM,oBAAC,aAAW;UAClB,UAAU,EACR,cAAc,gBACf;WACD;SACF,oBAAC;UAAa,MAAM;oBACjB,GAAG,8BAA8B;WACrB;;SACV;QACF,GAEP,4CACE,oBAAC;OAAM,SAAQ;OAAQ,OAAM;OAAQ,MAAM,oBAAC,cAAY;iBACtD,oBAAC;QAAK,MAAK;kBAAM,GAAG,uBAAuB;SAAQ;QAC7C,EACR,oBAAC;OACC,MAAM,OAAO,KAAK,SAAS,EACzB,OAAO,EAAE,OAAO,MAAM,YAAY,WAAW,EAC9C,CAAC;iBAED,GAAG,4BAA4B;QACnB,IACd;;MAEA;KACF,EACP,oBAAC;IAAa,SAAS;IAAU,MAAM;cACpC,GAAG,sBAAsB;KACb;IACV;GACF"}
@@ -1,4 +1,4 @@
1
- import { g as ui, o as TypeForm } from "./core-RCUw1Q-a.js";
1
+ import { a as TypeForm, g as ui } from "./core-B7LNjM78.js";
2
2
  import { useForm } from "alepha/react/form";
3
3
  import { Card, Flex, Portal, SegmentedControl, Text, Tooltip } from "@mantine/core";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -229,4 +229,4 @@ const Showcase = ({ title, schema, initialValues, columns = 3, children, windowP
229
229
 
230
230
  //#endregion
231
231
  export { Showcase as t };
232
- //# sourceMappingURL=Showcase-Dq3MISpd.js.map
232
+ //# sourceMappingURL=Showcase-BtEU0pY9.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Showcase-Dq3MISpd.js","names":[],"sources":["../../src/demo/components/shared/MacWindow.tsx","../../src/demo/components/shared/Showcase.tsx"],"sourcesContent":["import {\n Flex,\n type FlexProps,\n Portal,\n SegmentedControl,\n Tooltip,\n} from \"@mantine/core\";\nimport {\n IconArrowsMaximize,\n IconDeviceDesktop,\n IconDeviceMobile,\n IconDeviceTablet,\n} from \"@tabler/icons-react\";\nimport { type ReactNode, useState } from \"react\";\n\nexport interface MacWindowProps {\n children: ReactNode;\n title?: string;\n containerProps?: FlexProps;\n}\n\ntype DeviceSize = \"phone\" | \"tablet\" | \"desktop\" | \"full\";\n\nconst DEVICE_WIDTHS: Record<DeviceSize, string> = {\n phone: \"375px\",\n tablet: \"768px\",\n desktop: \"100%\",\n full: \"100%\",\n};\n\nconst MacWindow = ({ children, title, containerProps }: MacWindowProps) => {\n const [device, setDevice] = useState<DeviceSize>(\"desktop\");\n const isFullPage = device === \"full\";\n\n const controls = (\n <SegmentedControl\n size=\"xs\"\n value={device}\n onChange={(v) => setDevice(v as DeviceSize)}\n data={[\n {\n label: (\n <Tooltip label=\"Phone (375px)\" openDelay={400}>\n <Flex align=\"center\">\n <IconDeviceMobile size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"phone\",\n },\n {\n label: (\n <Tooltip label=\"Tablet (768px)\" openDelay={400}>\n <Flex align=\"center\">\n <IconDeviceTablet size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"tablet\",\n },\n {\n label: (\n <Tooltip label=\"Desktop (100%)\" openDelay={400}>\n <Flex align=\"center\">\n <IconDeviceDesktop size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"desktop\",\n },\n {\n label: (\n <Tooltip label=\"Full page\" openDelay={400}>\n <Flex align=\"center\">\n <IconArrowsMaximize size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"full\",\n },\n ]}\n />\n );\n\n const header = (\n <Flex\n h={36}\n px=\"sm\"\n align=\"center\"\n gap={8}\n style={{\n background: \"var(--mantine-color-default)\",\n borderBottom: \"1px solid var(--mantine-color-default-border)\",\n }}\n >\n <Flex gap={6}>\n <Flex\n w={12}\n h={12}\n style={{ borderRadius: \"50%\", background: \"#ff5f57\" }}\n />\n <Flex\n w={12}\n h={12}\n style={{ borderRadius: \"50%\", background: \"#febc2e\" }}\n />\n <Flex\n w={12}\n h={12}\n style={{ borderRadius: \"50%\", background: \"#28c840\" }}\n />\n </Flex>\n\n <Flex\n style={{\n flex: 1,\n textAlign: \"center\",\n fontSize: 13,\n color: \"var(--mantine-color-dimmed)\",\n }}\n >\n {title}\n </Flex>\n\n {controls}\n </Flex>\n );\n\n const body = (\n <Flex\n direction={\"column\"}\n flex={1}\n p=\"md\"\n style={{ overflow: \"auto\" }}\n {...containerProps}\n >\n {children}\n </Flex>\n );\n\n if (isFullPage) {\n return (\n <Portal>\n <Flex\n direction=\"column\"\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 1000,\n background: \"var(--mantine-color-body)\",\n }}\n >\n {header}\n {body}\n </Flex>\n </Portal>\n );\n }\n\n return (\n <Flex\n direction=\"column\"\n bdrs={\"md\"}\n style={{\n width: DEVICE_WIDTHS[device],\n maxWidth: \"100%\",\n border: \"1px solid var(--mantine-color-default-border)\",\n overflow: \"hidden\",\n background: \"var(--mantine-color-body)\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n transition: \"width 0.3s ease\",\n }}\n >\n {header}\n {body}\n </Flex>\n );\n};\n\nexport default MacWindow;\n","import { TypeForm, ui } from \"@alepha/ui\";\nimport { Card, Flex, Text } from \"@mantine/core\";\nimport type { Static, TObject } from \"alepha\";\nimport { useForm } from \"alepha/react/form\";\nimport { type ReactNode, useState } from \"react\";\nimport MacWindow, { type MacWindowProps } from \"./MacWindow.tsx\";\n\nexport interface ShowcaseProps<T extends TObject> {\n /**\n * Component title\n */\n title: string;\n /**\n * Schema for the props configuration\n */\n schema: T;\n /**\n * Initial values for the props\n */\n initialValues?: Partial<Static<T>>;\n /**\n * Number of columns for the props form\n */\n columns?: number;\n /**\n * Render function that receives the current props values\n */\n children: (props: Static<T>) => ReactNode;\n /**\n * Additional props for the MacWindow container\n */\n windowProps?: Partial<MacWindowProps>;\n}\n\n/**\n * Showcase component for demonstrating UI components with interactive props configuration.\n * Uses TypeForm to render a form based on the props schema and displays the component preview.\n */\nconst Showcase = <T extends TObject>({\n title,\n schema,\n initialValues,\n columns = 3,\n children,\n windowProps,\n}: ShowcaseProps<T>) => {\n const [values, setValues] = useState<Record<string, any>>(\n initialValues ?? {},\n );\n\n const form = useForm(\n {\n schema,\n initialValues,\n handler: (values) => {\n setValues(values as Record<string, any>);\n },\n onChange: (key, value) => {\n return form.submit();\n },\n },\n [schema],\n );\n\n return (\n <Flex flex={1} px={\"md\"} gap={\"md\"}>\n <Flex\n flex={1}\n bg={ui.colors.background}\n h={\"100%\"}\n justify=\"center\"\n align=\"flex-start\"\n style={{ flex: 1, minWidth: 0, overflow: \"auto\" }}\n >\n <MacWindow title={title} {...windowProps}>\n {children(values as Static<T>)}\n </MacWindow>\n </Flex>\n\n <Flex\n h={\"100%\"}\n style={{\n flex: \"0 0 300px\",\n overflow: \"auto\",\n }}\n >\n <Card shadow=\"sm\" radius=\"md\">\n <Card.Section withBorder py={\"xs\"} inheritPadding>\n <Text size={\"xs\"} fw={500}>\n {title} Props\n </Text>\n </Card.Section>\n\n <Card.Section p={\"sm\"}>\n <TypeForm\n form={form}\n columns={{ base: 1, xs: 1, sm: 1, md: 1, lg: 1, xl: 1 }}\n skipSubmitButton\n skipFormElement\n />\n </Card.Section>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nexport default Showcase;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Showcase-BtEU0pY9.js","names":[],"sources":["../../src/demo/components/shared/MacWindow.tsx","../../src/demo/components/shared/Showcase.tsx"],"sourcesContent":["import {\n Flex,\n type FlexProps,\n Portal,\n SegmentedControl,\n Tooltip,\n} from \"@mantine/core\";\nimport {\n IconArrowsMaximize,\n IconDeviceDesktop,\n IconDeviceMobile,\n IconDeviceTablet,\n} from \"@tabler/icons-react\";\nimport { type ReactNode, useState } from \"react\";\n\nexport interface MacWindowProps {\n children: ReactNode;\n title?: string;\n containerProps?: FlexProps;\n}\n\ntype DeviceSize = \"phone\" | \"tablet\" | \"desktop\" | \"full\";\n\nconst DEVICE_WIDTHS: Record<DeviceSize, string> = {\n phone: \"375px\",\n tablet: \"768px\",\n desktop: \"100%\",\n full: \"100%\",\n};\n\nconst MacWindow = ({ children, title, containerProps }: MacWindowProps) => {\n const [device, setDevice] = useState<DeviceSize>(\"desktop\");\n const isFullPage = device === \"full\";\n\n const controls = (\n <SegmentedControl\n size=\"xs\"\n value={device}\n onChange={(v) => setDevice(v as DeviceSize)}\n data={[\n {\n label: (\n <Tooltip label=\"Phone (375px)\" openDelay={400}>\n <Flex align=\"center\">\n <IconDeviceMobile size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"phone\",\n },\n {\n label: (\n <Tooltip label=\"Tablet (768px)\" openDelay={400}>\n <Flex align=\"center\">\n <IconDeviceTablet size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"tablet\",\n },\n {\n label: (\n <Tooltip label=\"Desktop (100%)\" openDelay={400}>\n <Flex align=\"center\">\n <IconDeviceDesktop size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"desktop\",\n },\n {\n label: (\n <Tooltip label=\"Full page\" openDelay={400}>\n <Flex align=\"center\">\n <IconArrowsMaximize size={14} />\n </Flex>\n </Tooltip>\n ),\n value: \"full\",\n },\n ]}\n />\n );\n\n const header = (\n <Flex\n h={36}\n px=\"sm\"\n align=\"center\"\n gap={8}\n style={{\n background: \"var(--mantine-color-default)\",\n borderBottom: \"1px solid var(--mantine-color-default-border)\",\n }}\n >\n <Flex gap={6}>\n <Flex\n w={12}\n h={12}\n style={{ borderRadius: \"50%\", background: \"#ff5f57\" }}\n />\n <Flex\n w={12}\n h={12}\n style={{ borderRadius: \"50%\", background: \"#febc2e\" }}\n />\n <Flex\n w={12}\n h={12}\n style={{ borderRadius: \"50%\", background: \"#28c840\" }}\n />\n </Flex>\n\n <Flex\n style={{\n flex: 1,\n textAlign: \"center\",\n fontSize: 13,\n color: \"var(--mantine-color-dimmed)\",\n }}\n >\n {title}\n </Flex>\n\n {controls}\n </Flex>\n );\n\n const body = (\n <Flex\n direction={\"column\"}\n flex={1}\n p=\"md\"\n style={{ overflow: \"auto\" }}\n {...containerProps}\n >\n {children}\n </Flex>\n );\n\n if (isFullPage) {\n return (\n <Portal>\n <Flex\n direction=\"column\"\n style={{\n position: \"fixed\",\n inset: 0,\n zIndex: 1000,\n background: \"var(--mantine-color-body)\",\n }}\n >\n {header}\n {body}\n </Flex>\n </Portal>\n );\n }\n\n return (\n <Flex\n direction=\"column\"\n bdrs={\"md\"}\n style={{\n width: DEVICE_WIDTHS[device],\n maxWidth: \"100%\",\n border: \"1px solid var(--mantine-color-default-border)\",\n overflow: \"hidden\",\n background: \"var(--mantine-color-body)\",\n boxShadow: \"0 4px 12px rgba(0, 0, 0, 0.15)\",\n transition: \"width 0.3s ease\",\n }}\n >\n {header}\n {body}\n </Flex>\n );\n};\n\nexport default MacWindow;\n","import { TypeForm, ui } from \"@alepha/ui\";\nimport { Card, Flex, Text } from \"@mantine/core\";\nimport type { Static, TObject } from \"alepha\";\nimport { useForm } from \"alepha/react/form\";\nimport { type ReactNode, useState } from \"react\";\nimport MacWindow, { type MacWindowProps } from \"./MacWindow.tsx\";\n\nexport interface ShowcaseProps<T extends TObject> {\n /**\n * Component title\n */\n title: string;\n /**\n * Schema for the props configuration\n */\n schema: T;\n /**\n * Initial values for the props\n */\n initialValues?: Partial<Static<T>>;\n /**\n * Number of columns for the props form\n */\n columns?: number;\n /**\n * Render function that receives the current props values\n */\n children: (props: Static<T>) => ReactNode;\n /**\n * Additional props for the MacWindow container\n */\n windowProps?: Partial<MacWindowProps>;\n}\n\n/**\n * Showcase component for demonstrating UI components with interactive props configuration.\n * Uses TypeForm to render a form based on the props schema and displays the component preview.\n */\nconst Showcase = <T extends TObject>({\n title,\n schema,\n initialValues,\n columns = 3,\n children,\n windowProps,\n}: ShowcaseProps<T>) => {\n const [values, setValues] = useState<Record<string, any>>(\n initialValues ?? {},\n );\n\n const form = useForm(\n {\n schema,\n initialValues,\n handler: (values) => {\n setValues(values as Record<string, any>);\n },\n onChange: (key, value) => {\n return form.submit();\n },\n },\n [schema],\n );\n\n return (\n <Flex flex={1} px={\"md\"} gap={\"md\"}>\n <Flex\n flex={1}\n bg={ui.colors.background}\n h={\"100%\"}\n justify=\"center\"\n align=\"flex-start\"\n style={{ flex: 1, minWidth: 0, overflow: \"auto\" }}\n >\n <MacWindow title={title} {...windowProps}>\n {children(values as Static<T>)}\n </MacWindow>\n </Flex>\n\n <Flex\n h={\"100%\"}\n style={{\n flex: \"0 0 300px\",\n overflow: \"auto\",\n }}\n >\n <Card shadow=\"sm\" radius=\"md\">\n <Card.Section withBorder py={\"xs\"} inheritPadding>\n <Text size={\"xs\"} fw={500}>\n {title} Props\n </Text>\n </Card.Section>\n\n <Card.Section p={\"sm\"}>\n <TypeForm\n form={form}\n columns={{ base: 1, xs: 1, sm: 1, md: 1, lg: 1, xl: 1 }}\n skipSubmitButton\n skipFormElement\n />\n </Card.Section>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nexport default Showcase;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { i as ActionButton } from "./core-niW0sFLv.js";
2
+ import { h as ActionButton } from "./core-B7LNjM78.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";
@@ -132,4 +132,4 @@ const VerifyEmail = (_props) => {
132
132
 
133
133
  //#endregion
134
134
  export { VerifyEmail_exports as n, VerifyEmail as t };
135
- //# sourceMappingURL=VerifyEmail-nWiSTMjF.js.map
135
+ //# sourceMappingURL=VerifyEmail-DFmdCdYs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VerifyEmail-DZWL72K4.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 { useRouter, useRouterState } from \"alepha/react/router\";\nimport { useEffect, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\n\nexport type VerifyEmailProps = {};\n\ntype Step = \"verifying\" | \"success\" | \"error\";\n\nconst VerifyEmail = (_props: VerifyEmailProps) => {\n const router = useRouter<AuthRouter>();\n const state = useRouterState();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n\n const [step, setStep] = useState<Step>(\"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 <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={router.path(\"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\">{error || tr(\"verifyEmailFailed\")}</Text>\n </Alert>\n <ActionButton href={router.path(\"login\")} fullWidth>\n {tr(\"verifyEmailBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nexport default VerifyEmail;\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,eAAe,WAA6B;CAChD,MAAM,SAAS,WAAuB;CACtC,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,WAAW,WAA2B;CAC5C,MAAM,EAAE,OAAO,SAAyB;CAExC,MAAM,CAAC,MAAM,WAAW,SAAe,YAAY;CACnD,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;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,OAAO,KAAK,QAAQ;QAAE;kBACvC,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;mBAAM,SAAS,GAAG,oBAAoB;UAAQ;SACnD;OACR,oBAAC;QAAa,MAAM,OAAO,KAAK,QAAQ;QAAE;kBACvC,GAAG,0BAA0B;SACjB;UACd;;MAEA;KACF;IACF;GACF"}
1
+ {"version":3,"file":"VerifyEmail-DFmdCdYs.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 { useRouter, useRouterState } from \"alepha/react/router\";\nimport { useEffect, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport type { AuthRouter } from \"../AuthRouter.ts\";\n\nexport type VerifyEmailProps = {};\n\ntype Step = \"verifying\" | \"success\" | \"error\";\n\nconst VerifyEmail = (_props: VerifyEmailProps) => {\n const router = useRouter<AuthRouter>();\n const state = useRouterState();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n\n const [step, setStep] = useState<Step>(\"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 <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={router.path(\"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\">{error || tr(\"verifyEmailFailed\")}</Text>\n </Alert>\n <ActionButton href={router.path(\"login\")} fullWidth>\n {tr(\"verifyEmailBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nexport default VerifyEmail;\n"],"mappings":";;;;;;;;;;;;AAeA,MAAM,eAAe,WAA6B;CAChD,MAAM,SAAS,WAAuB;CACtC,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,WAAW,WAA2B;CAC5C,MAAM,EAAE,OAAO,SAAyB;CAExC,MAAM,CAAC,MAAM,WAAW,SAAe,YAAY;CACnD,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;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,OAAO,KAAK,QAAQ;QAAE;kBACvC,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;mBAAM,SAAS,GAAG,oBAAoB;UAAQ;SACnD;OACR,oBAAC;QAAa,MAAM,OAAO,KAAK,QAAQ;QAAE;kBACvC,GAAG,0BAA0B;SACjB;UACd;;MAEA;KACF;IACF;GACF"}