@alepha/ui 0.18.3 → 0.19.0

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 (163) hide show
  1. package/dist/admin/{AdminApiKeys-Dy_k-4Vd.js → AdminApiKeys-Bt1PjO6o.js} +3 -4
  2. package/dist/admin/{AdminApiKeys-Dy_k-4Vd.js.map → AdminApiKeys-Bt1PjO6o.js.map} +1 -1
  3. package/dist/admin/{AdminAudits-CKiFMSSU.js → AdminAudits-C7c1CN4c.js} +3 -4
  4. package/dist/admin/{AdminAudits-CKiFMSSU.js.map → AdminAudits-C7c1CN4c.js.map} +1 -1
  5. package/dist/admin/{AdminDashboard-PhC_dZqo.js → AdminDashboard-C3RXpTp6.js} +3 -4
  6. package/dist/admin/{AdminDashboard-PhC_dZqo.js.map → AdminDashboard-C3RXpTp6.js.map} +1 -1
  7. package/dist/admin/{AdminFiles-DFTjijGp.js → AdminFiles-31ivR6Wq.js} +3 -4
  8. package/dist/admin/{AdminFiles-DFTjijGp.js.map → AdminFiles-31ivR6Wq.js.map} +1 -1
  9. package/dist/admin/{AdminJobDashboard-BL8gGPDp.js → AdminJobDashboard-BABLe7hL.js} +73 -25
  10. package/dist/admin/AdminJobDashboard-BABLe7hL.js.map +1 -0
  11. package/dist/admin/{AdminJobExecutions-D9E-CS-U.js → AdminJobExecutions-D-G8RIlr.js} +3 -4
  12. package/dist/admin/{AdminJobExecutions-D9E-CS-U.js.map → AdminJobExecutions-D-G8RIlr.js.map} +1 -1
  13. package/dist/admin/{AdminJobRegistry-Ci9ue1zC.js → AdminJobRegistry-oIS3K9NX.js} +3 -4
  14. package/dist/admin/{AdminJobRegistry-Ci9ue1zC.js.map → AdminJobRegistry-oIS3K9NX.js.map} +1 -1
  15. package/dist/admin/{AdminLayout-I6TlUMPc.js → AdminLayout-BmZ9mtXh.js} +8 -25
  16. package/dist/admin/AdminLayout-BmZ9mtXh.js.map +1 -0
  17. package/dist/admin/{AdminNotifications-ZPHCYrv7.js → AdminNotifications-DHdzksww.js} +3 -4
  18. package/dist/admin/{AdminNotifications-ZPHCYrv7.js.map → AdminNotifications-DHdzksww.js.map} +1 -1
  19. package/dist/admin/{AdminParameters-CqgvhRsb.js → AdminParameters-CyZQSXnN.js} +3 -12
  20. package/dist/admin/{AdminParameters-CqgvhRsb.js.map → AdminParameters-CyZQSXnN.js.map} +1 -1
  21. package/dist/admin/{AdminSessions-Bz5NRuoW.js → AdminSessions--xwELDSO.js} +3 -4
  22. package/dist/admin/{AdminSessions-Bz5NRuoW.js.map → AdminSessions--xwELDSO.js.map} +1 -1
  23. package/dist/admin/{AdminUserLayout-lXT6I0Qq.js → AdminUserLayout-DvBTG5gd.js} +72 -111
  24. package/dist/admin/AdminUserLayout-DvBTG5gd.js.map +1 -0
  25. package/dist/admin/{AdminUserProfile-vFBLoJ3h.js → AdminUserProfile-CzsPBl6Z.js} +7 -6
  26. package/dist/admin/AdminUserProfile-CzsPBl6Z.js.map +1 -0
  27. package/dist/admin/{AdminUserSessions-CT_YDim0.js → AdminUserSessions-C-aUnhVN.js} +3 -4
  28. package/dist/admin/{AdminUserSessions-CT_YDim0.js.map → AdminUserSessions-C-aUnhVN.js.map} +1 -1
  29. package/dist/admin/{AdminUsers-D1UfGya9.js → AdminUsers-BYwei5sj.js} +4 -4
  30. package/dist/admin/AdminUsers-BYwei5sj.js.map +1 -0
  31. package/dist/admin/{AuthLayout-_frhdgOO.js → AuthLayout-CkPGLJku.js} +3 -4
  32. package/dist/admin/{AuthLayout-_frhdgOO.js.map → AuthLayout-CkPGLJku.js.map} +1 -1
  33. package/dist/{demo/IconGoogle-CSQLPYwX.js → admin/IconGoogle-8Nkx6yax.js} +2 -4
  34. package/dist/admin/{IconGoogle-Ch1m3Uzl.js.map → IconGoogle-8Nkx6yax.js.map} +1 -1
  35. package/dist/admin/{Login-xtNmQtGh.js → Login-DSBqNsZc.js} +5 -6
  36. package/dist/{auth/Login-BA1E8IZl.js.map → admin/Login-DSBqNsZc.js.map} +1 -1
  37. package/dist/admin/{Profile-_AtPUwAP.js → Profile-CDRjJo0P.js} +3 -5
  38. package/dist/{demo/Profile-DS5q4vOh.js.map → admin/Profile-CDRjJo0P.js.map} +1 -1
  39. package/dist/admin/{Register-JcCjHUUn.js → Register-4QGFOnfh.js} +5 -6
  40. package/dist/{demo/Register-B4hLBeEv.js.map → admin/Register-4QGFOnfh.js.map} +1 -1
  41. package/dist/admin/{ResetPassword-CwGBPLJO.js → ResetPassword-Gxc9L_mY.js} +4 -5
  42. package/dist/{auth/ResetPassword-DCtGcneA.js.map → admin/ResetPassword-Gxc9L_mY.js.map} +1 -1
  43. package/dist/admin/{VerifyEmail-hNxWejWf.js → VerifyEmail-D7G5NnaN.js} +4 -5
  44. package/dist/{auth/VerifyEmail-DkH7NBfn.js.map → admin/VerifyEmail-D7G5NnaN.js.map} +1 -1
  45. package/dist/admin/adminUserAtom-DCi4wf-v.js +11 -0
  46. package/dist/admin/adminUserAtom-DCi4wf-v.js.map +1 -0
  47. package/dist/admin/{core-CYaRQ8O-.js → core-D1AbU50V.js} +24 -85
  48. package/dist/admin/core-D1AbU50V.js.map +1 -0
  49. package/dist/admin/index.d.ts +59 -10
  50. package/dist/admin/index.d.ts.map +1 -1
  51. package/dist/admin/index.js +35 -36
  52. package/dist/admin/index.js.map +1 -1
  53. package/dist/admin/rolldown-runtime-CiIaOW0V.js +13 -0
  54. package/dist/{demo/AuthLayout-Brri4A-L.js → auth/AuthLayout-CfRKcTqP.js} +3 -4
  55. package/dist/auth/{AuthLayout-AvLlcLjS.js.map → AuthLayout-CfRKcTqP.js.map} +1 -1
  56. package/dist/{admin/IconGoogle-Ch1m3Uzl.js → auth/IconGoogle-8Nkx6yax.js} +2 -4
  57. package/dist/auth/{IconGoogle-Ch1m3Uzl.js.map → IconGoogle-8Nkx6yax.js.map} +1 -1
  58. package/dist/auth/{Login-BA1E8IZl.js → Login-DJyweoPS.js} +5 -6
  59. package/dist/{demo/Login-C12N4oGs.js.map → auth/Login-DJyweoPS.js.map} +1 -1
  60. package/dist/{demo/Profile-DS5q4vOh.js → auth/Profile-Cy93pNTw.js} +3 -5
  61. package/dist/auth/{Profile-YcWdeuFz.js.map → Profile-Cy93pNTw.js.map} +1 -1
  62. package/dist/auth/{Register-CPhEO5MG.js → Register-CSqzzitW.js} +5 -6
  63. package/dist/{admin/Register-JcCjHUUn.js.map → auth/Register-CSqzzitW.js.map} +1 -1
  64. package/dist/{demo/ResetPassword-D8g9ha1N.js → auth/ResetPassword-B61QPlQi.js} +4 -5
  65. package/dist/{admin/ResetPassword-CwGBPLJO.js.map → auth/ResetPassword-B61QPlQi.js.map} +1 -1
  66. package/dist/auth/{VerifyEmail-DkH7NBfn.js → VerifyEmail-CqBJ11id.js} +4 -5
  67. package/dist/{admin/VerifyEmail-hNxWejWf.js.map → auth/VerifyEmail-CqBJ11id.js.map} +1 -1
  68. package/dist/auth/{core-D5jIAVF2.js → core-C6D3pazL.js} +22 -54
  69. package/dist/auth/core-C6D3pazL.js.map +1 -0
  70. package/dist/auth/index.d.ts +0 -6
  71. package/dist/auth/index.d.ts.map +1 -1
  72. package/dist/auth/index.js +13 -18
  73. package/dist/auth/index.js.map +1 -1
  74. package/dist/auth/rolldown-runtime-CiIaOW0V.js +13 -0
  75. package/dist/core/index.d.ts +10 -4
  76. package/dist/core/index.d.ts.map +1 -1
  77. package/dist/core/index.js +21 -91
  78. package/dist/core/index.js.map +1 -1
  79. package/dist/{auth/AuthLayout-AvLlcLjS.js → demo/AuthLayout-Dq5tSLSc.js} +3 -4
  80. package/dist/demo/{AuthLayout-Brri4A-L.js.map → AuthLayout-Dq5tSLSc.js.map} +1 -1
  81. package/dist/demo/{DemoButton-wiCxZZ_L.js → DemoButton-_Ws2w-J0.js} +4 -5
  82. package/dist/demo/{DemoButton-wiCxZZ_L.js.map → DemoButton-_Ws2w-J0.js.map} +1 -1
  83. package/dist/demo/{DemoControlSelect-D7ILObVg.js → DemoControlSelect-ChP4ZOpQ.js} +4 -5
  84. package/dist/demo/{DemoControlSelect-D7ILObVg.js.map → DemoControlSelect-ChP4ZOpQ.js.map} +1 -1
  85. package/dist/demo/{DemoDataTable-DZ5Y8pFX.js → DemoDataTable-Hwf_UUni.js} +4 -5
  86. package/dist/demo/{DemoDataTable-DZ5Y8pFX.js.map → DemoDataTable-Hwf_UUni.js.map} +1 -1
  87. package/dist/demo/{DemoDialog-CUWdLHim.js → DemoDialog-B01OMVRd.js} +3 -4
  88. package/dist/demo/{DemoDialog-CUWdLHim.js.map → DemoDialog-B01OMVRd.js.map} +1 -1
  89. package/dist/demo/{DemoFlex-a8OhMMvq.js → DemoFlex-870PEl0V.js} +4 -5
  90. package/dist/demo/{DemoFlex-a8OhMMvq.js.map → DemoFlex-870PEl0V.js.map} +1 -1
  91. package/dist/demo/{DemoHeading-C13OVDfS.js → DemoHeading-C1YR27fz.js} +4 -5
  92. package/dist/demo/{DemoHeading-C13OVDfS.js.map → DemoHeading-C1YR27fz.js.map} +1 -1
  93. package/dist/demo/{DemoHome-D_De3UiT.js → DemoHome-DRbL2eGf.js} +4 -5
  94. package/dist/demo/{DemoHome-D_De3UiT.js.map → DemoHome-DRbL2eGf.js.map} +1 -1
  95. package/dist/demo/{DemoJsonViewer-B50s9aGM.js → DemoJsonViewer-DoABiqBW.js} +4 -5
  96. package/dist/demo/{DemoJsonViewer-B50s9aGM.js.map → DemoJsonViewer-DoABiqBW.js.map} +1 -1
  97. package/dist/demo/{DemoLayout-CHU8WTwO.js → DemoLayout-CN_PDCX2.js} +4 -5
  98. package/dist/demo/DemoLayout-CN_PDCX2.js.map +1 -0
  99. package/dist/demo/{DemoLogin-BBlrWpml.js → DemoLogin-B5x-ug3Q.js} +10 -11
  100. package/dist/demo/{DemoLogin-BBlrWpml.js.map → DemoLogin-B5x-ug3Q.js.map} +1 -1
  101. package/dist/demo/{DemoRegister-BuNE3_-f.js → DemoRegister-Q6sg2xuV.js} +10 -11
  102. package/dist/demo/{DemoRegister-BuNE3_-f.js.map → DemoRegister-Q6sg2xuV.js.map} +1 -1
  103. package/dist/demo/{DemoResetPassword-D_IjjjOJ.js → DemoResetPassword-DrqZfmEw.js} +10 -11
  104. package/dist/demo/{DemoResetPassword-D_IjjjOJ.js.map → DemoResetPassword-DrqZfmEw.js.map} +1 -1
  105. package/dist/demo/{DemoSidebar-Giy2HRBD.js → DemoSidebar-CfKS6w1o.js} +4 -5
  106. package/dist/demo/{DemoSidebar-Giy2HRBD.js.map → DemoSidebar-CfKS6w1o.js.map} +1 -1
  107. package/dist/demo/{DemoText-ubcw-vog.js → DemoText-pT6Gi5b5.js} +4 -5
  108. package/dist/demo/{DemoText-ubcw-vog.js.map → DemoText-pT6Gi5b5.js.map} +1 -1
  109. package/dist/demo/{DemoToast-9die_dYT.js → DemoToast-I13NBzQQ.js} +3 -4
  110. package/dist/demo/{DemoToast-9die_dYT.js.map → DemoToast-I13NBzQQ.js.map} +1 -1
  111. package/dist/demo/{DemoTypeForm-D_d6OVKL.js → DemoTypeForm-BqzcrtvN.js} +4 -5
  112. package/dist/demo/{DemoTypeForm-D_d6OVKL.js.map → DemoTypeForm-BqzcrtvN.js.map} +1 -1
  113. package/dist/demo/{DemoVerifyEmail-B43KlF4F.js → DemoVerifyEmail-HwD8xfQw.js} +10 -11
  114. package/dist/demo/{DemoVerifyEmail-B43KlF4F.js.map → DemoVerifyEmail-HwD8xfQw.js.map} +1 -1
  115. package/dist/{auth/IconGoogle-Ch1m3Uzl.js → demo/IconGoogle-CwQy4G9y.js} +2 -4
  116. package/dist/demo/{IconGoogle-CSQLPYwX.js.map → IconGoogle-CwQy4G9y.js.map} +1 -1
  117. package/dist/demo/{Login-C12N4oGs.js → Login-CqG1iJbn.js} +5 -6
  118. package/dist/{admin/Login-xtNmQtGh.js.map → demo/Login-CqG1iJbn.js.map} +1 -1
  119. package/dist/{auth/Profile-YcWdeuFz.js → demo/Profile-C0ojJCaG.js} +3 -5
  120. package/dist/{admin/Profile-_AtPUwAP.js.map → demo/Profile-C0ojJCaG.js.map} +1 -1
  121. package/dist/demo/{Register-B4hLBeEv.js → Register-KKZwr_lL.js} +5 -6
  122. package/dist/{auth/Register-CPhEO5MG.js.map → demo/Register-KKZwr_lL.js.map} +1 -1
  123. package/dist/{auth/ResetPassword-DCtGcneA.js → demo/ResetPassword-DMrLFEtr.js} +4 -5
  124. package/dist/demo/{ResetPassword-D8g9ha1N.js.map → ResetPassword-DMrLFEtr.js.map} +1 -1
  125. package/dist/demo/{Showcase-D6Fxt4X4.js → Showcase-D49Wud2v.js} +3 -5
  126. package/dist/demo/{Showcase-D6Fxt4X4.js.map → Showcase-D49Wud2v.js.map} +1 -1
  127. package/dist/demo/{VerifyEmail-BjDo0cZA.js → VerifyEmail-BFCAFz6T.js} +4 -5
  128. package/dist/demo/{VerifyEmail-BjDo0cZA.js.map → VerifyEmail-BFCAFz6T.js.map} +1 -1
  129. package/dist/demo/{auth-ByVTreDl.js → auth-D9qTZzCa.js} +18 -35
  130. package/dist/demo/{auth-ByVTreDl.js.map → auth-D9qTZzCa.js.map} +1 -1
  131. package/dist/demo/{core-DFgB3yU4.js → core-DRtQklr3.js} +23 -86
  132. package/dist/demo/core-DRtQklr3.js.map +1 -0
  133. package/dist/demo/index.js +19 -22
  134. package/dist/demo/index.js.map +1 -1
  135. package/dist/demo/rolldown-runtime-CiIaOW0V.js +13 -0
  136. package/package.json +17 -17
  137. package/src/admin/AdminRouter.tsx +18 -1
  138. package/src/admin/atoms/adminUserAtom.ts +7 -0
  139. package/src/admin/components/AdminLayout.tsx +2 -14
  140. package/src/admin/components/jobs/AdminJobDashboard.tsx +51 -20
  141. package/src/admin/components/users/AdminUserLayout.tsx +84 -127
  142. package/src/admin/components/users/AdminUserProfile.tsx +5 -2
  143. package/src/admin/components/users/AdminUsers.tsx +1 -1
  144. package/src/core/components/Flex.tsx +24 -0
  145. package/src/core/components/buttons/ActionButton.tsx +1 -0
  146. package/src/core/components/dialogs/PromptDialog.tsx +1 -1
  147. package/src/core/components/layout/Breadcrumb.tsx +2 -2
  148. package/src/core/components/layout/DashboardShell.tsx +1 -1
  149. package/src/core/services/DialogService.tsx +2 -2
  150. package/src/core/styles.css +2 -1
  151. package/src/core/table/components/DataTable.tsx +0 -1
  152. package/dist/admin/AdminJobDashboard-BL8gGPDp.js.map +0 -1
  153. package/dist/admin/AdminLayout-I6TlUMPc.js.map +0 -1
  154. package/dist/admin/AdminUserLayout-lXT6I0Qq.js.map +0 -1
  155. package/dist/admin/AdminUserProfile-vFBLoJ3h.js.map +0 -1
  156. package/dist/admin/AdminUsers-D1UfGya9.js.map +0 -1
  157. package/dist/admin/core-CYaRQ8O-.js.map +0 -1
  158. package/dist/admin/rolldown-runtime-CjeV3_4I.js +0 -18
  159. package/dist/auth/core-D5jIAVF2.js.map +0 -1
  160. package/dist/auth/rolldown-runtime-CjeV3_4I.js +0 -18
  161. package/dist/demo/DemoLayout-CHU8WTwO.js.map +0 -1
  162. package/dist/demo/core-DFgB3yU4.js.map +0 -1
  163. package/dist/demo/rolldown-runtime-CjeV3_4I.js +0 -18
@@ -1 +1 @@
1
- {"version":3,"file":"Register-CPhEO5MG.js","names":[],"sources":["../../src/auth/components/Register.tsx"],"sourcesContent":["import { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconLock,\n IconMail,\n IconPhone,\n IconPhoto,\n IconUser,\n} from \"@tabler/icons-react\";\nimport { TypeBoxError, t } from \"alepha\";\nimport type {\n RealmConfig,\n RegistrationIntentResponse,\n UserController,\n} from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useAuth } from \"alepha/react/auth\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { useMemo, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface RegisterProps {\n realmConfig: RealmConfig;\n loginPath?: string;\n variant?: \"card\" | \"split\";\n image?: string;\n}\n\ntype RegistrationPhase = \"form\" | \"verification\";\n\ninterface RegistrationState {\n phase: RegistrationPhase;\n intent?: RegistrationIntentResponse;\n credentials?: {\n identifier: string;\n password: string;\n };\n}\n\nconst Register = (props: RegisterProps) => {\n const auth = useAuth();\n const userCtrl = useClient<UserController>();\n const router = useRouter();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const [registrationState, setRegistrationState] = useState<RegistrationState>(\n {\n phase: \"form\",\n },\n );\n const [emailCode, setEmailCode] = useState(\"\");\n const [phoneCode, setPhoneCode] = useState(\"\");\n const [verificationError, setVerificationError] = useState<string | null>(\n null,\n );\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings || {};\n const isRegistrationAllowed = settings.registrationAllowed !== false;\n\n const registerSchema = useMemo(() => {\n const registerSchema = t.object({\n username: t.optional(\n t.text({\n trim: true,\n pattern: settings.usernameRegExp,\n }),\n ),\n email: t.optional(t.email()),\n phoneNumber: t.optional(t.e164()),\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n });\n\n const required = registerSchema.required as string[];\n\n if (settings.username === \"required\") required.push(\"username\");\n if (settings.email === \"required\") required.push(\"email\");\n if (settings.phoneNumber === \"required\") required.push(\"phoneNumber\");\n\n return registerSchema;\n }, []);\n\n const form = useForm({\n schema: registerSchema,\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new TypeBoxError({\n message: \"Passwords do not match\",\n instancePath: \"/confirmPassword\",\n keyword: \"not\",\n schemaPath: \"\",\n params: {},\n });\n }\n\n // Phase 1: Create registration intent\n const intent = await userCtrl.createRegistrationIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: {\n username: data.username,\n email: data.email,\n phoneNumber: data.phoneNumber,\n password: data.password,\n },\n });\n\n const identifier = data.username ?? data.email ?? data.phoneNumber;\n\n // Check if verification is needed\n if (\n intent.expectEmailVerification ||\n intent.expectPhoneVerification ||\n intent.expectCaptcha\n ) {\n // Move to verification phase\n setRegistrationState({\n phase: \"verification\",\n intent,\n credentials: identifier\n ? { identifier, password: data.password }\n : undefined,\n });\n return;\n }\n\n // No verification needed - complete registration immediately\n await userCtrl.createUserFromIntent({\n body: { intentId: intent.intentId },\n });\n\n // Auto-login after registration\n if (identifier && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.push(router.query.r || \"/\");\n },\n });\n\n const handleVerificationSubmit = async () => {\n if (!registrationState.intent) return;\n\n setIsSubmitting(true);\n setVerificationError(null);\n\n try {\n // Phase 2: Complete registration with verification codes\n await userCtrl.createUserFromIntent({\n body: {\n intentId: registrationState.intent.intentId,\n emailCode: registrationState.intent.expectEmailVerification\n ? emailCode\n : undefined,\n phoneCode: registrationState.intent.expectPhoneVerification\n ? phoneCode\n : undefined,\n },\n });\n\n // Auto-login after registration\n if (registrationState.credentials && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: registrationState.credentials.identifier,\n password: registrationState.credentials.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.push(router.query.r || \"/\");\n } catch (error) {\n setVerificationError(\n error instanceof Error ? error.message : \"Verification failed\",\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const canSubmitVerification = () => {\n if (!registrationState.intent) return false;\n\n if (\n registrationState.intent.expectEmailVerification &&\n emailCode.length !== 6\n ) {\n return false;\n }\n\n if (\n registrationState.intent.expectPhoneVerification &&\n phoneCode.length !== 6\n ) {\n return false;\n }\n\n return true;\n };\n\n // Verification phase UI (always card layout)\n if (registrationState.phase === \"verification\" && registrationState.intent) {\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"registerVerifyTitle\") ?? \"Verify your account\"}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"registerVerifyDescription\") ??\n \"Please enter the verification code(s) sent to you.\"}\n </Text>\n\n {verificationError && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{verificationError}</Text>\n </Alert>\n )}\n\n {registrationState.intent.expectEmailVerification && (\n <Flex direction=\"column\" gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerEmailCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={emailCode}\n onChange={setEmailCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Email verification code\"\n />\n </Flex>\n </Flex>\n )}\n\n {registrationState.intent.expectPhoneVerification && (\n <Flex direction=\"column\" gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerPhoneCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={phoneCode}\n onChange={setPhoneCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Phone verification code\"\n />\n </Flex>\n </Flex>\n )}\n\n <ActionButton\n color={\"blue\"}\n onClick={handleVerificationSubmit}\n loading={isSubmitting}\n disabled={!canSubmitVerification()}\n >\n {tr(\"registerVerifySubmit\")}\n </ActionButton>\n\n <ActionButton\n variant=\"subtle\"\n onClick={() =>\n setRegistrationState({ phase: \"form\", intent: undefined })\n }\n >\n {tr(\"registerVerifyBack\") ?? \"Back to registration\"}\n </ActionButton>\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n }\n\n // External login methods\n const externalMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalMethods.length > 0;\n\n const realmQuery = props.realmConfig.realmName\n ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}`\n : \"\";\n\n const formContent = (\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl || settings.displayName || settings.description) && (\n <Flex direction=\"column\" gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Flex>\n )}\n\n {!isRegistrationAllowed ? (\n <>\n <Alert variant=\"light\" color=\"yellow\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{tr(\"registerDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${realmQuery}`}\n >\n {tr(\"registerBackToSignIn\")}\n </ActionButton>\n </>\n ) : (\n <>\n {/* Credentials registration form */}\n {credentialsProvider && (\n <form {...form.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n {settings.username !== \"none\" && form.input.username && (\n <Control\n label={tr(\"registerUsername\")}\n input={form.input.username}\n icon={<IconUser />}\n text={{\n autoComplete: \"username\",\n }}\n />\n )}\n {settings.email !== \"none\" && form.input.email && (\n <Control\n label={tr(\"registerEmail\")}\n input={form.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n }}\n />\n )}\n {settings.phoneNumber !== \"none\" && form.input.phoneNumber && (\n <Control\n label={tr(\"registerPhone\")}\n input={form.input.phoneNumber}\n icon={<IconPhone />}\n text={{\n autoComplete: \"tel\",\n }}\n />\n )}\n <Control\n label={tr(\"registerPassword\")}\n input={form.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <Control\n label={tr(\"registerConfirmPassword\")}\n input={form.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={form} color={\"blue\"} variant={\"filled\"}>\n {tr(\"registerCreateAccount\")}\n </ActionButton>\n </Flex>\n </form>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Flex align=\"center\" justify=\"center\" gap={\"md\"}>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n <Text size=\"xs\" c=\"dimmed\">\n {tr(\"registerOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Flex>\n )}\n\n {/* External login methods */}\n {externalMethods.length > 0 && (\n <Flex direction=\"column\" gap={\"sm\"}>\n {externalMethods.map((method) => (\n <ActionButton\n variant={\"default\"}\n key={method.type}\n leftSection={leftSection(method.name.toLowerCase())}\n onClick={() =>\n auth.login(method.name, {\n redirect,\n realm: props.realmConfig.realmName,\n })\n }\n >\n {tr(\"registerContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Flex>\n )}\n\n {/* Sign in link */}\n <Text size=\"sm\" ta=\"center\">\n {tr(\"registerHaveAccount\")}{\" \"}\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${realmQuery}`}\n anchorProps={{ inherit: true }}\n >\n {tr(\"registerSignIn\")}\n </ActionButton>\n </Text>\n </>\n )}\n </Flex>\n );\n\n if (props.variant === \"split\") {\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Card\n withBorder\n p={0}\n w={720}\n bg={\"var(--alepha-elevated)\"}\n style={{ overflow: \"hidden\" }}\n >\n <Flex mih={480}>\n {props.image ? (\n <Flex\n flex={1}\n style={{\n backgroundImage: `url(${props.image})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n }}\n />\n ) : (\n <Flex\n flex={1}\n justify=\"center\"\n align=\"center\"\n bg=\"var(--mantine-color-gray-light)\"\n style={{\n borderRight: \"1px solid var(--mantine-color-default-border)\",\n }}\n >\n <Flex\n justify=\"center\"\n align=\"center\"\n w={120}\n h={80}\n style={{\n border: \"2px dashed var(--mantine-color-default-border)\",\n borderRadius: \"var(--mantine-radius-sm)\",\n }}\n >\n <IconPhoto size={32} style={{ opacity: 0.3 }} />\n </Flex>\n </Flex>\n )}\n <Flex\n flex={1}\n direction=\"column\"\n gap={\"md\"}\n p={\"xl\"}\n justify={\"center\"}\n >\n {formContent}\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n </Card>\n </Flex>\n );\n }\n\n // Default card variant\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n {formContent}\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default Register;\n\nconst leftSection = (name: string) => {\n if (name === \"google\") {\n return <IconGoogle />;\n }\n\n if (name === \"github\") {\n return <IconGithub />;\n }\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"Register-KKZwr_lL.js","names":[],"sources":["../../src/auth/components/Register.tsx"],"sourcesContent":["import { ActionButton, Control, capitalize } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconLock,\n IconMail,\n IconPhone,\n IconPhoto,\n IconUser,\n} from \"@tabler/icons-react\";\nimport { TypeBoxError, t } from \"alepha\";\nimport type {\n RealmConfig,\n RegistrationIntentResponse,\n UserController,\n} from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useAuth } from \"alepha/react/auth\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { useMemo, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\nimport IconGithub from \"./icons/IconGithub.tsx\";\nimport IconGoogle from \"./icons/IconGoogle.tsx\";\n\nexport interface RegisterProps {\n realmConfig: RealmConfig;\n loginPath?: string;\n variant?: \"card\" | \"split\";\n image?: string;\n}\n\ntype RegistrationPhase = \"form\" | \"verification\";\n\ninterface RegistrationState {\n phase: RegistrationPhase;\n intent?: RegistrationIntentResponse;\n credentials?: {\n identifier: string;\n password: string;\n };\n}\n\nconst Register = (props: RegisterProps) => {\n const auth = useAuth();\n const userCtrl = useClient<UserController>();\n const router = useRouter();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const redirect = router.query.r || \"/\";\n\n const [registrationState, setRegistrationState] = useState<RegistrationState>(\n {\n phase: \"form\",\n },\n );\n const [emailCode, setEmailCode] = useState(\"\");\n const [phoneCode, setPhoneCode] = useState(\"\");\n const [verificationError, setVerificationError] = useState<string | null>(\n null,\n );\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n const credentialsProvider = props.realmConfig.authenticationMethods.find(\n (it) => it.type === \"CREDENTIALS\",\n );\n\n const settings = props.realmConfig.settings || {};\n const isRegistrationAllowed = settings.registrationAllowed !== false;\n\n const registerSchema = useMemo(() => {\n const registerSchema = t.object({\n username: t.optional(\n t.text({\n trim: true,\n pattern: settings.usernameRegExp,\n }),\n ),\n email: t.optional(t.email()),\n phoneNumber: t.optional(t.e164()),\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n });\n\n const required = registerSchema.required as string[];\n\n if (settings.username === \"required\") required.push(\"username\");\n if (settings.email === \"required\") required.push(\"email\");\n if (settings.phoneNumber === \"required\") required.push(\"phoneNumber\");\n\n return registerSchema;\n }, []);\n\n const form = useForm({\n schema: registerSchema,\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new TypeBoxError({\n message: \"Passwords do not match\",\n instancePath: \"/confirmPassword\",\n keyword: \"not\",\n schemaPath: \"\",\n params: {},\n });\n }\n\n // Phase 1: Create registration intent\n const intent = await userCtrl.createRegistrationIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: {\n username: data.username,\n email: data.email,\n phoneNumber: data.phoneNumber,\n password: data.password,\n },\n });\n\n const identifier = data.username ?? data.email ?? data.phoneNumber;\n\n // Check if verification is needed\n if (\n intent.expectEmailVerification ||\n intent.expectPhoneVerification ||\n intent.expectCaptcha\n ) {\n // Move to verification phase\n setRegistrationState({\n phase: \"verification\",\n intent,\n credentials: identifier\n ? { identifier, password: data.password }\n : undefined,\n });\n return;\n }\n\n // No verification needed - complete registration immediately\n await userCtrl.createUserFromIntent({\n body: { intentId: intent.intentId },\n });\n\n // Auto-login after registration\n if (identifier && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: identifier,\n password: data.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.push(router.query.r || \"/\");\n },\n });\n\n const handleVerificationSubmit = async () => {\n if (!registrationState.intent) return;\n\n setIsSubmitting(true);\n setVerificationError(null);\n\n try {\n // Phase 2: Complete registration with verification codes\n await userCtrl.createUserFromIntent({\n body: {\n intentId: registrationState.intent.intentId,\n emailCode: registrationState.intent.expectEmailVerification\n ? emailCode\n : undefined,\n phoneCode: registrationState.intent.expectPhoneVerification\n ? phoneCode\n : undefined,\n },\n });\n\n // Auto-login after registration\n if (registrationState.credentials && credentialsProvider) {\n await auth.login(credentialsProvider.name, {\n username: registrationState.credentials.identifier,\n password: registrationState.credentials.password,\n realm: props.realmConfig.realmName,\n });\n }\n\n await router.push(router.query.r || \"/\");\n } catch (error) {\n setVerificationError(\n error instanceof Error ? error.message : \"Verification failed\",\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n const canSubmitVerification = () => {\n if (!registrationState.intent) return false;\n\n if (\n registrationState.intent.expectEmailVerification &&\n emailCode.length !== 6\n ) {\n return false;\n }\n\n if (\n registrationState.intent.expectPhoneVerification &&\n phoneCode.length !== 6\n ) {\n return false;\n }\n\n return true;\n };\n\n // Verification phase UI (always card layout)\n if (registrationState.phase === \"verification\" && registrationState.intent) {\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"registerVerifyTitle\") ?? \"Verify your account\"}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"registerVerifyDescription\") ??\n \"Please enter the verification code(s) sent to you.\"}\n </Text>\n\n {verificationError && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{verificationError}</Text>\n </Alert>\n )}\n\n {registrationState.intent.expectEmailVerification && (\n <Flex direction=\"column\" gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerEmailCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={emailCode}\n onChange={setEmailCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Email verification code\"\n />\n </Flex>\n </Flex>\n )}\n\n {registrationState.intent.expectPhoneVerification && (\n <Flex direction=\"column\" gap={\"xs\"}>\n <Text size=\"sm\" fw={500}>\n {tr(\"registerPhoneCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n value={phoneCode}\n onChange={setPhoneCode}\n type=\"number\"\n oneTimeCode\n aria-label=\"Phone verification code\"\n />\n </Flex>\n </Flex>\n )}\n\n <ActionButton\n color={\"blue\"}\n onClick={handleVerificationSubmit}\n loading={isSubmitting}\n disabled={!canSubmitVerification()}\n >\n {tr(\"registerVerifySubmit\")}\n </ActionButton>\n\n <ActionButton\n variant=\"subtle\"\n onClick={() =>\n setRegistrationState({ phase: \"form\", intent: undefined })\n }\n >\n {tr(\"registerVerifyBack\") ?? \"Back to registration\"}\n </ActionButton>\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n }\n\n // External login methods\n const externalMethods = props.realmConfig.authenticationMethods.filter(\n (method) => method.type !== \"CREDENTIALS\",\n );\n\n const showOrDivider = credentialsProvider && externalMethods.length > 0;\n\n const realmQuery = props.realmConfig.realmName\n ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}`\n : \"\";\n\n const formContent = (\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl || settings.displayName || settings.description) && (\n <Flex direction=\"column\" gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Flex>\n )}\n\n {!isRegistrationAllowed ? (\n <>\n <Alert variant=\"light\" color=\"yellow\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{tr(\"registerDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${realmQuery}`}\n >\n {tr(\"registerBackToSignIn\")}\n </ActionButton>\n </>\n ) : (\n <>\n {/* Credentials registration form */}\n {credentialsProvider && (\n <form {...form.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n {settings.username !== \"none\" && form.input.username && (\n <Control\n label={tr(\"registerUsername\")}\n input={form.input.username}\n icon={<IconUser />}\n text={{\n autoComplete: \"username\",\n }}\n />\n )}\n {settings.email !== \"none\" && form.input.email && (\n <Control\n label={tr(\"registerEmail\")}\n input={form.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n }}\n />\n )}\n {settings.phoneNumber !== \"none\" && form.input.phoneNumber && (\n <Control\n label={tr(\"registerPhone\")}\n input={form.input.phoneNumber}\n icon={<IconPhone />}\n text={{\n autoComplete: \"tel\",\n }}\n />\n )}\n <Control\n label={tr(\"registerPassword\")}\n input={form.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <Control\n label={tr(\"registerConfirmPassword\")}\n input={form.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={form} color={\"blue\"} variant={\"filled\"}>\n {tr(\"registerCreateAccount\")}\n </ActionButton>\n </Flex>\n </form>\n )}\n\n {/* OR divider - only when both credentials AND external methods exist */}\n {showOrDivider && (\n <Flex align=\"center\" justify=\"center\" gap={\"md\"}>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n <Text size=\"xs\" c=\"dimmed\">\n {tr(\"registerOr\")}\n </Text>\n <Flex flex={1} h={\"1px\"} bg={\"var(--alepha-border)\"} />\n </Flex>\n )}\n\n {/* External login methods */}\n {externalMethods.length > 0 && (\n <Flex direction=\"column\" gap={\"sm\"}>\n {externalMethods.map((method) => (\n <ActionButton\n variant={\"default\"}\n key={method.type}\n leftSection={leftSection(method.name.toLowerCase())}\n onClick={() =>\n auth.login(method.name, {\n redirect,\n realm: props.realmConfig.realmName,\n })\n }\n >\n {tr(\"registerContinueWith\", {\n args: [capitalize(method.name)],\n })}\n </ActionButton>\n ))}\n </Flex>\n )}\n\n {/* Sign in link */}\n <Text size=\"sm\" ta=\"center\">\n {tr(\"registerHaveAccount\")}{\" \"}\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${realmQuery}`}\n anchorProps={{ inherit: true }}\n >\n {tr(\"registerSignIn\")}\n </ActionButton>\n </Text>\n </>\n )}\n </Flex>\n );\n\n if (props.variant === \"split\") {\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Card\n withBorder\n p={0}\n w={720}\n bg={\"var(--alepha-elevated)\"}\n style={{ overflow: \"hidden\" }}\n >\n <Flex mih={480}>\n {props.image ? (\n <Flex\n flex={1}\n style={{\n backgroundImage: `url(${props.image})`,\n backgroundSize: \"cover\",\n backgroundPosition: \"center\",\n }}\n />\n ) : (\n <Flex\n flex={1}\n justify=\"center\"\n align=\"center\"\n bg=\"var(--mantine-color-gray-light)\"\n style={{\n borderRight: \"1px solid var(--mantine-color-default-border)\",\n }}\n >\n <Flex\n justify=\"center\"\n align=\"center\"\n w={120}\n h={80}\n style={{\n border: \"2px dashed var(--mantine-color-default-border)\",\n borderRadius: \"var(--mantine-radius-sm)\",\n }}\n >\n <IconPhoto size={32} style={{ opacity: 0.3 }} />\n </Flex>\n </Flex>\n )}\n <Flex\n flex={1}\n direction=\"column\"\n gap={\"md\"}\n p={\"xl\"}\n justify={\"center\"}\n >\n {formContent}\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n </Card>\n </Flex>\n );\n }\n\n // Default card variant\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n {formContent}\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"registerCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default Register;\n\nconst leftSection = (name: string) => {\n if (name === \"google\") {\n return <IconGoogle />;\n }\n\n if (name === \"github\") {\n return <IconGithub />;\n }\n};\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { i as ActionButton, r as Control } from "./core-D5jIAVF2.js";
1
+ import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
+ import { h as ActionButton, o as Control } from "./core-DRtQklr3.js";
3
3
  import { AlephaError, t } from "alepha";
4
4
  import { useForm } from "alepha/react/form";
5
5
  import { useI18n } from "alepha/react/i18n";
@@ -10,7 +10,6 @@ import { IconAlertCircle, IconCheck, IconInfoCircle, IconLock, IconMail } from "
10
10
  import { useRouter } from "alepha/react/router";
11
11
  import { useClient } from "alepha/react";
12
12
  import { resetPasswordRequestSchema } from "alepha/api/users";
13
-
14
13
  //#region ../../src/auth/components/ResetPassword.tsx
15
14
  var ResetPassword_exports = /* @__PURE__ */ __exportAll({ default: () => ResetPassword });
16
15
  const ResetPassword = (props) => {
@@ -280,7 +279,7 @@ const ResetPassword = (props) => {
280
279
  })
281
280
  });
282
281
  };
283
-
284
282
  //#endregion
285
283
  export { ResetPassword_exports as n, ResetPassword as t };
286
- //# sourceMappingURL=ResetPassword-DCtGcneA.js.map
284
+
285
+ //# sourceMappingURL=ResetPassword-DMrLFEtr.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ResetPassword-D8g9ha1N.js","names":[],"sources":["../../src/auth/components/ResetPassword.tsx"],"sourcesContent":["import { ActionButton, Control } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconCheck,\n IconInfoCircle,\n IconLock,\n IconMail,\n} from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type {\n PasswordResetIntentResponse,\n RealmConfig,\n UserController,\n} from \"alepha/api/users\";\nimport { resetPasswordRequestSchema } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\n\nexport interface ResetPasswordProps {\n realmConfig: RealmConfig;\n loginPath?: string;\n}\n\ntype Step = \"email\" | \"code\" | \"password\" | \"success\";\n\ninterface ResetState {\n step: Step;\n intent?: PasswordResetIntentResponse;\n email?: string;\n code?: string;\n}\n\nconst ResetPassword = (props: ResetPasswordProps) => {\n const router = useRouter();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const [resetState, setResetState] = useState<ResetState>({ step: \"email\" });\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const redirect = router.query.r || \"/\";\n\n const settings = props.realmConfig.settings;\n const isResetPasswordAllowed = settings?.resetPasswordAllowed !== false;\n\n // Phase 1: Request password reset intent\n const emailForm = useForm({\n schema: resetPasswordRequestSchema,\n handler: async (data) => {\n setError(null);\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: data.email },\n });\n\n setResetState({\n step: \"code\",\n intent,\n email: data.email,\n });\n },\n });\n\n // Phase 2: Complete password reset\n const passwordForm = useForm(\n {\n schema: t.object({\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n }),\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new AlephaError(\"Passwords do not match\");\n }\n\n if (!resetState.intent || !resetState.code) {\n throw new AlephaError(\"Invalid reset state\");\n }\n\n await userCtrl.completePasswordReset({\n body: {\n intentId: resetState.intent.intentId,\n code: resetState.code,\n newPassword: data.password,\n },\n });\n\n setResetState({ step: \"success\" });\n },\n },\n [resetState.intent, resetState.code],\n );\n\n const handleCodeComplete = (value: string) => {\n if (value.length === 6) {\n setResetState((prev) => ({\n ...prev,\n step: \"password\",\n code: value,\n }));\n }\n };\n\n const handleResendCode = async () => {\n if (!resetState.email) return;\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: resetState.email },\n });\n\n setResetState((prev) => ({\n ...prev,\n intent,\n }));\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to resend code\");\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Flex direction=\"column\" gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Flex>\n )}\n\n {error && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{error}</Text>\n </Alert>\n )}\n\n {!isResetPasswordAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"resetPasswordDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : \"\"}`}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n ) : resetState.step === \"email\" ? (\n <form {...emailForm.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterEmail\")}\n </Text>\n <Control\n label={tr(\"resetPasswordEmail\")}\n input={emailForm.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n autoFocus: true,\n disabled: !isResetPasswordAllowed,\n }}\n />\n <ActionButton\n form={emailForm}\n disabled={!isResetPasswordAllowed}\n >\n {tr(\"resetPasswordSendCode\")}\n </ActionButton>\n </Flex>\n </form>\n ) : resetState.step === \"code\" ? (\n <Flex direction=\"column\" gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"blue\" icon={<IconInfoCircle />}>\n <Text size=\"sm\">{tr(\"resetPasswordCodeSent\")}</Text>\n </Alert>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"resetPasswordEnterCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n type=\"number\"\n autoFocus\n oneTimeCode\n onComplete={handleCodeComplete}\n aria-label=\"Password reset verification code\"\n />\n </Flex>\n <ActionButton\n variant=\"subtle\"\n onClick={handleResendCode}\n loading={isSubmitting}\n >\n {tr(\"resetPasswordResendCode\")}\n </ActionButton>\n </Flex>\n ) : resetState.step === \"password\" ? (\n <form {...passwordForm.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterNewPassword\")}\n </Text>\n <Control\n label={tr(\"resetPasswordNewPassword\")}\n input={passwordForm.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n autoFocus: true,\n }}\n />\n <Control\n label={tr(\"resetPasswordConfirmPassword\")}\n input={passwordForm.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={passwordForm}>\n {tr(\"resetPasswordSetNewPassword\")}\n </ActionButton>\n </Flex>\n </form>\n ) : (\n <>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"resetPasswordSuccess\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : \"\"}`}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"resetPasswordCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default ResetPassword;\n"],"mappings":"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"}
1
+ {"version":3,"file":"ResetPassword-DMrLFEtr.js","names":[],"sources":["../../src/auth/components/ResetPassword.tsx"],"sourcesContent":["import { ActionButton, Control } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Image, PinInput, Text, Title } from \"@mantine/core\";\nimport {\n IconAlertCircle,\n IconCheck,\n IconInfoCircle,\n IconLock,\n IconMail,\n} from \"@tabler/icons-react\";\nimport { AlephaError, t } from \"alepha\";\nimport type {\n PasswordResetIntentResponse,\n RealmConfig,\n UserController,\n} from \"alepha/api/users\";\nimport { resetPasswordRequestSchema } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useForm } from \"alepha/react/form\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouter } from \"alepha/react/router\";\nimport { useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\n\nexport interface ResetPasswordProps {\n realmConfig: RealmConfig;\n loginPath?: string;\n}\n\ntype Step = \"email\" | \"code\" | \"password\" | \"success\";\n\ninterface ResetState {\n step: Step;\n intent?: PasswordResetIntentResponse;\n email?: string;\n code?: string;\n}\n\nconst ResetPassword = (props: ResetPasswordProps) => {\n const router = useRouter();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n const [resetState, setResetState] = useState<ResetState>({ step: \"email\" });\n const [error, setError] = useState<string | null>(null);\n const [isSubmitting, setIsSubmitting] = useState(false);\n const redirect = router.query.r || \"/\";\n\n const settings = props.realmConfig.settings;\n const isResetPasswordAllowed = settings?.resetPasswordAllowed !== false;\n\n // Phase 1: Request password reset intent\n const emailForm = useForm({\n schema: resetPasswordRequestSchema,\n handler: async (data) => {\n setError(null);\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: data.email },\n });\n\n setResetState({\n step: \"code\",\n intent,\n email: data.email,\n });\n },\n });\n\n // Phase 2: Complete password reset\n const passwordForm = useForm(\n {\n schema: t.object({\n password: t.string({ minLength: 8 }),\n confirmPassword: t.string({ minLength: 8 }),\n }),\n handler: async (data) => {\n if (data.password !== data.confirmPassword) {\n throw new AlephaError(\"Passwords do not match\");\n }\n\n if (!resetState.intent || !resetState.code) {\n throw new AlephaError(\"Invalid reset state\");\n }\n\n await userCtrl.completePasswordReset({\n body: {\n intentId: resetState.intent.intentId,\n code: resetState.code,\n newPassword: data.password,\n },\n });\n\n setResetState({ step: \"success\" });\n },\n },\n [resetState.intent, resetState.code],\n );\n\n const handleCodeComplete = (value: string) => {\n if (value.length === 6) {\n setResetState((prev) => ({\n ...prev,\n step: \"password\",\n code: value,\n }));\n }\n };\n\n const handleResendCode = async () => {\n if (!resetState.email) return;\n\n setIsSubmitting(true);\n setError(null);\n\n try {\n const intent = await userCtrl.createPasswordResetIntent({\n query: { userRealmName: props.realmConfig.realmName },\n body: { email: resetState.email },\n });\n\n setResetState((prev) => ({\n ...prev,\n intent,\n }));\n } catch (err) {\n setError(err instanceof Error ? err.message : \"Failed to resend code\");\n } finally {\n setIsSubmitting(false);\n }\n };\n\n return (\n <Flex flex={1} justify={\"center\"} align={\"center\"}>\n <Flex direction=\"column\" gap={\"sm\"} w={360}>\n <Card withBorder p={\"lg\"} bg={\"var(--alepha-elevated)\"}>\n <Flex direction=\"column\" gap={\"md\"}>\n {/* Realm branding */}\n {(settings.logoUrl ||\n settings.displayName ||\n settings.description) && (\n <Flex direction=\"column\" gap={\"xs\"} align=\"center\" mb=\"xs\">\n {settings.logoUrl && (\n <Image\n src={settings.logoUrl}\n alt={settings.displayName || props.realmConfig.realmName}\n h={48}\n w=\"auto\"\n fit=\"contain\"\n />\n )}\n {settings.displayName && (\n <Title order={4} ta=\"center\">\n {settings.displayName}\n </Title>\n )}\n {settings.description && (\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {settings.description}\n </Text>\n )}\n </Flex>\n )}\n\n {error && (\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">{error}</Text>\n </Alert>\n )}\n\n {!isResetPasswordAllowed ? (\n <>\n <Alert\n variant=\"light\"\n color=\"yellow\"\n icon={<IconAlertCircle />}\n >\n <Text size=\"sm\">{tr(\"resetPasswordDisabled\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : \"\"}`}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n ) : resetState.step === \"email\" ? (\n <form {...emailForm.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterEmail\")}\n </Text>\n <Control\n label={tr(\"resetPasswordEmail\")}\n input={emailForm.input.email}\n icon={<IconMail />}\n text={{\n autoComplete: \"email\",\n autoFocus: true,\n disabled: !isResetPasswordAllowed,\n }}\n />\n <ActionButton\n form={emailForm}\n disabled={!isResetPasswordAllowed}\n >\n {tr(\"resetPasswordSendCode\")}\n </ActionButton>\n </Flex>\n </form>\n ) : resetState.step === \"code\" ? (\n <Flex direction=\"column\" gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"blue\" icon={<IconInfoCircle />}>\n <Text size=\"sm\">{tr(\"resetPasswordCodeSent\")}</Text>\n </Alert>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"resetPasswordEnterCode\")}\n </Text>\n <Flex justify=\"center\">\n <PinInput\n length={6}\n type=\"number\"\n autoFocus\n oneTimeCode\n onComplete={handleCodeComplete}\n aria-label=\"Password reset verification code\"\n />\n </Flex>\n <ActionButton\n variant=\"subtle\"\n onClick={handleResendCode}\n loading={isSubmitting}\n >\n {tr(\"resetPasswordResendCode\")}\n </ActionButton>\n </Flex>\n ) : resetState.step === \"password\" ? (\n <form {...passwordForm.props}>\n <Flex direction=\"column\" flex={1} gap={\"md\"}>\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"resetPasswordTitle\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\">\n {tr(\"resetPasswordEnterNewPassword\")}\n </Text>\n <Control\n label={tr(\"resetPasswordNewPassword\")}\n input={passwordForm.input.password}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n autoFocus: true,\n }}\n />\n <Control\n label={tr(\"resetPasswordConfirmPassword\")}\n input={passwordForm.input.confirmPassword}\n icon={<IconLock />}\n password={{\n autoComplete: \"new-password\",\n }}\n />\n <ActionButton form={passwordForm}>\n {tr(\"resetPasswordSetNewPassword\")}\n </ActionButton>\n </Flex>\n </form>\n ) : (\n <>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"resetPasswordSuccess\")}</Text>\n </Alert>\n <ActionButton\n href={`${props.loginPath ?? \"/auth/login\"}${props.realmConfig.realmName ? `?realm=${encodeURIComponent(props.realmConfig.realmName)}` : \"\"}`}\n >\n {tr(\"resetPasswordBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n <ActionButton variant={\"subtle\"} href={redirect}>\n {tr(\"resetPasswordCancel\")}\n </ActionButton>\n </Flex>\n </Flex>\n );\n};\n\nexport default ResetPassword;\n"],"mappings":"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"}
@@ -1,10 +1,9 @@
1
- import { a as TypeForm, f as Flex$1, l as Text$1 } from "./core-DFgB3yU4.js";
1
+ import { a as TypeForm, f as Flex$1, l as Text$1 } from "./core-DRtQklr3.js";
2
2
  import { useForm } from "alepha/react/form";
3
3
  import { Portal, SegmentedControl, Tooltip } from "@mantine/core";
4
4
  import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { useState } from "react";
6
6
  import { IconArrowsMaximize, IconDeviceDesktop, IconDeviceMobile, IconDeviceTablet } from "@tabler/icons-react";
7
-
8
7
  //#region ../../src/demo/components/shared/MacWindow.tsx
9
8
  const DEVICE_WIDTHS = {
10
9
  phone: "375px",
@@ -150,7 +149,6 @@ const MacWindow = ({ children, title, containerProps }) => {
150
149
  children: [header, body]
151
150
  });
152
151
  };
153
-
154
152
  //#endregion
155
153
  //#region ../../src/demo/components/shared/Showcase.tsx
156
154
  /**
@@ -225,7 +223,7 @@ const Showcase = (props) => {
225
223
  })]
226
224
  });
227
225
  };
228
-
229
226
  //#endregion
230
227
  export { Showcase as t };
231
- //# sourceMappingURL=Showcase-D6Fxt4X4.js.map
228
+
229
+ //# sourceMappingURL=Showcase-D49Wud2v.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Showcase-D6Fxt4X4.js","names":["Flex","Flex","Text"],"sources":["../../src/demo/components/shared/MacWindow.tsx","../../src/demo/components/shared/Showcase.tsx"],"sourcesContent":["import { Flex } from \"@alepha/ui\";\nimport {\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\";\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 overflow direction={\"column\"} flex={1} p=\"md\" {...containerProps}>\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 col\n overflow\n h={\"100%\"}\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 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 { Flex, Text, TypeForm } from \"@alepha/ui\";\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>(props: ShowcaseProps<T>) => {\n const {\n title,\n schema,\n initialValues,\n columns = 3,\n children,\n windowProps,\n } = props;\n\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 fill p={\"md\"} pt={0} gap={\"md\"} overflow>\n <Flex fill overflow ground h={\"100%\"} justify=\"center\" align=\"flex-start\">\n <MacWindow title={title} {...windowProps}>\n {children(values as Static<T>)}\n </MacWindow>\n </Flex>\n\n <Flex h={\"100%\"} col surface bordered rounded shadowed w={300}>\n <Flex p={\"xs\"} borderedBottom>\n <Text size={\"xs\"} fw={500}>\n {title} Props\n </Text>\n </Flex>\n <Flex px={\"md\"} py={\"xs\"}>\n <TypeForm\n fill\n form={form}\n columns={{ base: 1, xs: 1, sm: 1, md: 1, lg: 1, xl: 1 }}\n skipSubmitButton\n skipFormElement\n />\n </Flex>\n </Flex>\n </Flex>\n );\n};\n\nexport default Showcase;\n"],"mappings":"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"}
1
+ {"version":3,"file":"Showcase-D49Wud2v.js","names":["Flex","Flex","Text"],"sources":["../../src/demo/components/shared/MacWindow.tsx","../../src/demo/components/shared/Showcase.tsx"],"sourcesContent":["import { Flex } from \"@alepha/ui\";\nimport {\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\";\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 overflow direction={\"column\"} flex={1} p=\"md\" {...containerProps}>\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 col\n overflow\n h={\"100%\"}\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 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 { Flex, Text, TypeForm } from \"@alepha/ui\";\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>(props: ShowcaseProps<T>) => {\n const {\n title,\n schema,\n initialValues,\n columns = 3,\n children,\n windowProps,\n } = props;\n\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 fill p={\"md\"} pt={0} gap={\"md\"} overflow>\n <Flex fill overflow ground h={\"100%\"} justify=\"center\" align=\"flex-start\">\n <MacWindow title={title} {...windowProps}>\n {children(values as Static<T>)}\n </MacWindow>\n </Flex>\n\n <Flex h={\"100%\"} col surface bordered rounded shadowed w={300}>\n <Flex p={\"xs\"} borderedBottom>\n <Text size={\"xs\"} fw={500}>\n {title} Props\n </Text>\n </Flex>\n <Flex px={\"md\"} py={\"xs\"}>\n <TypeForm\n fill\n form={form}\n columns={{ base: 1, xs: 1, sm: 1, md: 1, lg: 1, xl: 1 }}\n skipSubmitButton\n skipFormElement\n />\n </Flex>\n </Flex>\n </Flex>\n );\n};\n\nexport default Showcase;\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { t as __exportAll } from "./rolldown-runtime-CjeV3_4I.js";
2
- import { h as ActionButton } from "./core-DFgB3yU4.js";
1
+ import { t as __exportAll } from "./rolldown-runtime-CiIaOW0V.js";
2
+ import { h as ActionButton } from "./core-DRtQklr3.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";
@@ -7,7 +7,6 @@ import { useEffect, useState } from "react";
7
7
  import { IconAlertCircle, IconCheck, IconMailCheck } from "@tabler/icons-react";
8
8
  import { useRouterState } from "alepha/react/router";
9
9
  import { useClient } from "alepha/react";
10
-
11
10
  //#region ../../src/auth/components/VerifyEmail.tsx
12
11
  var VerifyEmail_exports = /* @__PURE__ */ __exportAll({ default: () => VerifyEmail });
13
12
  const VerifyEmailStateful = (props) => {
@@ -144,7 +143,7 @@ const VerifyEmail = (props) => {
144
143
  });
145
144
  return /* @__PURE__ */ jsx(VerifyEmailStateful, { ...props });
146
145
  };
147
-
148
146
  //#endregion
149
147
  export { VerifyEmail_exports as n, VerifyEmail as t };
150
- //# sourceMappingURL=VerifyEmail-BjDo0cZA.js.map
148
+
149
+ //# sourceMappingURL=VerifyEmail-BFCAFz6T.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"VerifyEmail-BjDo0cZA.js","names":[],"sources":["../../src/auth/components/VerifyEmail.tsx"],"sourcesContent":["import { ActionButton } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Loader, Text } from \"@mantine/core\";\nimport { IconAlertCircle, IconCheck, IconMailCheck } from \"@tabler/icons-react\";\nimport type { UserController } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouterState } from \"alepha/react/router\";\nimport { useEffect, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\n\nexport type VerifyEmailStep = \"verifying\" | \"success\" | \"error\";\n\nexport interface VerifyEmailProps {\n loginPath?: string;\n step?: VerifyEmailStep;\n}\n\nconst VerifyEmailStateful = (props: VerifyEmailProps) => {\n const state = useRouterState();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n\n const [step, setStep] = useState<VerifyEmailStep>(\"verifying\");\n const [error, setError] = useState<string | null>(null);\n\n const email = state.query.email as string | undefined;\n const token = state.query.token as string | undefined;\n\n useEffect(() => {\n const verify = async () => {\n if (!email || !token) {\n setError(tr(\"verifyEmailMissingParams\"));\n setStep(\"error\");\n return;\n }\n\n try {\n await userCtrl.verifyEmail({\n body: { email, token },\n });\n setStep(\"success\");\n } catch (err) {\n setError(err instanceof Error ? err.message : tr(\"verifyEmailFailed\"));\n setStep(\"error\");\n }\n };\n\n verify();\n }, [email, token]);\n\n return (\n <VerifyEmailView step={step} error={error} loginPath={props.loginPath} />\n );\n};\n\ninterface VerifyEmailViewProps {\n step: VerifyEmailStep;\n error?: string | null;\n loginPath?: string;\n}\n\nconst VerifyEmailView = (props: VerifyEmailViewProps) => {\n const { tr } = useI18n<AuthI18n, \"en\">();\n const { step } = props;\n\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Flex direction=\"column\" gap=\"sm\" w={400}>\n <Card withBorder p=\"lg\" bg=\"var(--alepha-elevated)\">\n <Flex direction=\"column\" gap=\"md\" align=\"center\">\n {step === \"verifying\" && (\n <>\n <Loader size=\"lg\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailVerifying\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"verifyEmailPleaseWait\")}\n </Text>\n </>\n )}\n\n {step === \"success\" && (\n <>\n <IconMailCheck size={48} color=\"var(--mantine-color-green-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"verifyEmailSuccess\")}</Text>\n </Alert>\n <ActionButton href={props.loginPath ?? \"/auth/login\"} fullWidth>\n {tr(\"verifyEmailSignIn\")}\n </ActionButton>\n </>\n )}\n\n {step === \"error\" && (\n <>\n <IconAlertCircle size={48} color=\"var(--mantine-color-red-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">\n {props.error || tr(\"verifyEmailFailed\")}\n </Text>\n </Alert>\n <ActionButton href={props.loginPath ?? \"/auth/login\"} fullWidth>\n {tr(\"verifyEmailBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nconst VerifyEmail = (props: VerifyEmailProps) => {\n if (props.step) {\n return <VerifyEmailView step={props.step} loginPath={props.loginPath} />;\n }\n return <VerifyEmailStateful {...props} />;\n};\n\nexport default VerifyEmail;\n"],"mappings":";;;;;;;;;;;;AAiBA,MAAM,uBAAuB,UAA4B;CACvD,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,WAAW,WAA2B;CAC5C,MAAM,EAAE,OAAO,SAAyB;CAExC,MAAM,CAAC,MAAM,WAAW,SAA0B,YAAY;CAC9D,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CAEvD,MAAM,QAAQ,MAAM,MAAM;CAC1B,MAAM,QAAQ,MAAM,MAAM;AAE1B,iBAAgB;EACd,MAAM,SAAS,YAAY;AACzB,OAAI,CAAC,SAAS,CAAC,OAAO;AACpB,aAAS,GAAG,2BAA2B,CAAC;AACxC,YAAQ,QAAQ;AAChB;;AAGF,OAAI;AACF,UAAM,SAAS,YAAY,EACzB,MAAM;KAAE;KAAO;KAAO,EACvB,CAAC;AACF,YAAQ,UAAU;YACX,KAAK;AACZ,aAAS,eAAe,QAAQ,IAAI,UAAU,GAAG,oBAAoB,CAAC;AACtE,YAAQ,QAAQ;;;AAIpB,UAAQ;IACP,CAAC,OAAO,MAAM,CAAC;AAElB,QACE,oBAAC;EAAsB;EAAa;EAAO,WAAW,MAAM;GAAa;;AAU7E,MAAM,mBAAmB,UAAgC;CACvD,MAAM,EAAE,OAAO,SAAyB;CACxC,MAAM,EAAE,SAAS;AAEjB,QACE,oBAAC;EAAK,MAAM;EAAG,SAAQ;EAAS,OAAM;YACpC,oBAAC;GAAK,WAAU;GAAS,KAAI;GAAK,GAAG;aACnC,oBAAC;IAAK;IAAW,GAAE;IAAK,IAAG;cACzB,qBAAC;KAAK,WAAU;KAAS,KAAI;KAAK,OAAM;;MACrC,SAAS,eACR;OACE,oBAAC,UAAO,MAAK,OAAO;OACpB,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,uBAAuB;SACtB;OACP,oBAAC;QAAK,MAAK;QAAK,GAAE;QAAS,IAAG;kBAC3B,GAAG,wBAAwB;SACvB;UACN;MAGJ,SAAS,aACR;OACE,oBAAC;QAAc,MAAM;QAAI,OAAM;SAAiC;OAChE,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;SAClB;OACP,oBAAC;QAAM,SAAQ;QAAQ,OAAM;QAAQ,MAAM,oBAAC,cAAY;kBACtD,oBAAC;SAAK,MAAK;mBAAM,GAAG,qBAAqB;UAAQ;SAC3C;OACR,oBAAC;QAAa,MAAM,MAAM,aAAa;QAAe;kBACnD,GAAG,oBAAoB;SACX;UACd;MAGJ,SAAS,WACR;OACE,oBAAC;QAAgB,MAAM;QAAI,OAAM;SAA+B;OAChE,oBAAC;QAAK,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;SAClB;OACP,oBAAC;QAAM,SAAQ;QAAQ,OAAM;QAAM,MAAM,oBAAC,oBAAkB;kBAC1D,oBAAC;SAAK,MAAK;mBACR,MAAM,SAAS,GAAG,oBAAoB;UAClC;SACD;OACR,oBAAC;QAAa,MAAM,MAAM,aAAa;QAAe;kBACnD,GAAG,0BAA0B;SACjB;UACd;;MAEA;KACF;IACF;GACF;;AAIX,MAAM,eAAe,UAA4B;AAC/C,KAAI,MAAM,KACR,QAAO,oBAAC;EAAgB,MAAM,MAAM;EAAM,WAAW,MAAM;GAAa;AAE1E,QAAO,oBAAC,uBAAoB,GAAI,QAAS"}
1
+ {"version":3,"file":"VerifyEmail-BFCAFz6T.js","names":[],"sources":["../../src/auth/components/VerifyEmail.tsx"],"sourcesContent":["import { ActionButton } from \"@alepha/ui\";\nimport { Alert, Card, Flex, Loader, Text } from \"@mantine/core\";\nimport { IconAlertCircle, IconCheck, IconMailCheck } from \"@tabler/icons-react\";\nimport type { UserController } from \"alepha/api/users\";\nimport { useClient } from \"alepha/react\";\nimport { useI18n } from \"alepha/react/i18n\";\nimport { useRouterState } from \"alepha/react/router\";\nimport { useEffect, useState } from \"react\";\nimport type { AuthI18n } from \"../AuthI18n.ts\";\n\nexport type VerifyEmailStep = \"verifying\" | \"success\" | \"error\";\n\nexport interface VerifyEmailProps {\n loginPath?: string;\n step?: VerifyEmailStep;\n}\n\nconst VerifyEmailStateful = (props: VerifyEmailProps) => {\n const state = useRouterState();\n const userCtrl = useClient<UserController>();\n const { tr } = useI18n<AuthI18n, \"en\">();\n\n const [step, setStep] = useState<VerifyEmailStep>(\"verifying\");\n const [error, setError] = useState<string | null>(null);\n\n const email = state.query.email as string | undefined;\n const token = state.query.token as string | undefined;\n\n useEffect(() => {\n const verify = async () => {\n if (!email || !token) {\n setError(tr(\"verifyEmailMissingParams\"));\n setStep(\"error\");\n return;\n }\n\n try {\n await userCtrl.verifyEmail({\n body: { email, token },\n });\n setStep(\"success\");\n } catch (err) {\n setError(err instanceof Error ? err.message : tr(\"verifyEmailFailed\"));\n setStep(\"error\");\n }\n };\n\n verify();\n }, [email, token]);\n\n return (\n <VerifyEmailView step={step} error={error} loginPath={props.loginPath} />\n );\n};\n\ninterface VerifyEmailViewProps {\n step: VerifyEmailStep;\n error?: string | null;\n loginPath?: string;\n}\n\nconst VerifyEmailView = (props: VerifyEmailViewProps) => {\n const { tr } = useI18n<AuthI18n, \"en\">();\n const { step } = props;\n\n return (\n <Flex flex={1} justify=\"center\" align=\"center\">\n <Flex direction=\"column\" gap=\"sm\" w={400}>\n <Card withBorder p=\"lg\" bg=\"var(--alepha-elevated)\">\n <Flex direction=\"column\" gap=\"md\" align=\"center\">\n {step === \"verifying\" && (\n <>\n <Loader size=\"lg\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailVerifying\")}\n </Text>\n <Text size=\"sm\" c=\"dimmed\" ta=\"center\">\n {tr(\"verifyEmailPleaseWait\")}\n </Text>\n </>\n )}\n\n {step === \"success\" && (\n <>\n <IconMailCheck size={48} color=\"var(--mantine-color-green-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"green\" icon={<IconCheck />}>\n <Text size=\"sm\">{tr(\"verifyEmailSuccess\")}</Text>\n </Alert>\n <ActionButton href={props.loginPath ?? \"/auth/login\"} fullWidth>\n {tr(\"verifyEmailSignIn\")}\n </ActionButton>\n </>\n )}\n\n {step === \"error\" && (\n <>\n <IconAlertCircle size={48} color=\"var(--mantine-color-red-6)\" />\n <Text size=\"lg\" fw={500} ta=\"center\">\n {tr(\"verifyEmailTitle\")}\n </Text>\n <Alert variant=\"light\" color=\"red\" icon={<IconAlertCircle />}>\n <Text size=\"sm\">\n {props.error || tr(\"verifyEmailFailed\")}\n </Text>\n </Alert>\n <ActionButton href={props.loginPath ?? \"/auth/login\"} fullWidth>\n {tr(\"verifyEmailBackToSignIn\")}\n </ActionButton>\n </>\n )}\n </Flex>\n </Card>\n </Flex>\n </Flex>\n );\n};\n\nconst VerifyEmail = (props: VerifyEmailProps) => {\n if (props.step) {\n return <VerifyEmailView step={props.step} loginPath={props.loginPath} />;\n }\n return <VerifyEmailStateful {...props} />;\n};\n\nexport default VerifyEmail;\n"],"mappings":";;;;;;;;;;;AAiBA,MAAM,uBAAuB,UAA4B;CACvD,MAAM,QAAQ,gBAAgB;CAC9B,MAAM,WAAW,WAA2B;CAC5C,MAAM,EAAE,OAAO,SAAyB;CAExC,MAAM,CAAC,MAAM,WAAW,SAA0B,YAAY;CAC9D,MAAM,CAAC,OAAO,YAAY,SAAwB,KAAK;CAEvD,MAAM,QAAQ,MAAM,MAAM;CAC1B,MAAM,QAAQ,MAAM,MAAM;AAE1B,iBAAgB;EACd,MAAM,SAAS,YAAY;AACzB,OAAI,CAAC,SAAS,CAAC,OAAO;AACpB,aAAS,GAAG,2BAA2B,CAAC;AACxC,YAAQ,QAAQ;AAChB;;AAGF,OAAI;AACF,UAAM,SAAS,YAAY,EACzB,MAAM;KAAE;KAAO;KAAO,EACvB,CAAC;AACF,YAAQ,UAAU;YACX,KAAK;AACZ,aAAS,eAAe,QAAQ,IAAI,UAAU,GAAG,oBAAoB,CAAC;AACtE,YAAQ,QAAQ;;;AAIpB,UAAQ;IACP,CAAC,OAAO,MAAM,CAAC;AAElB,QACE,oBAAC,iBAAD;EAAuB;EAAa;EAAO,WAAW,MAAM;EAAa,CAAA;;AAU7E,MAAM,mBAAmB,UAAgC;CACvD,MAAM,EAAE,OAAO,SAAyB;CACxC,MAAM,EAAE,SAAS;AAEjB,QACE,oBAAC,MAAD;EAAM,MAAM;EAAG,SAAQ;EAAS,OAAM;YACpC,oBAAC,MAAD;GAAM,WAAU;GAAS,KAAI;GAAK,GAAG;aACnC,oBAAC,MAAD;IAAM,YAAA;IAAW,GAAE;IAAK,IAAG;cACzB,qBAAC,MAAD;KAAM,WAAU;KAAS,KAAI;KAAK,OAAM;eAAxC;MACG,SAAS,eACR,qBAAA,UAAA,EAAA,UAAA;OACE,oBAAC,QAAD,EAAQ,MAAK,MAAO,CAAA;OACpB,oBAAC,MAAD;QAAM,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,uBAAuB;QACtB,CAAA;OACP,oBAAC,MAAD;QAAM,MAAK;QAAK,GAAE;QAAS,IAAG;kBAC3B,GAAG,wBAAwB;QACvB,CAAA;OACN,EAAA,CAAA;MAGJ,SAAS,aACR,qBAAA,UAAA,EAAA,UAAA;OACE,oBAAC,eAAD;QAAe,MAAM;QAAI,OAAM;QAAiC,CAAA;OAChE,oBAAC,MAAD;QAAM,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;QAClB,CAAA;OACP,oBAAC,OAAD;QAAO,SAAQ;QAAQ,OAAM;QAAQ,MAAM,oBAAC,WAAD,EAAa,CAAA;kBACtD,oBAAC,MAAD;SAAM,MAAK;mBAAM,GAAG,qBAAqB;SAAQ,CAAA;QAC3C,CAAA;OACR,oBAAC,cAAD;QAAc,MAAM,MAAM,aAAa;QAAe,WAAA;kBACnD,GAAG,oBAAoB;QACX,CAAA;OACd,EAAA,CAAA;MAGJ,SAAS,WACR,qBAAA,UAAA,EAAA,UAAA;OACE,oBAAC,iBAAD;QAAiB,MAAM;QAAI,OAAM;QAA+B,CAAA;OAChE,oBAAC,MAAD;QAAM,MAAK;QAAK,IAAI;QAAK,IAAG;kBACzB,GAAG,mBAAmB;QAClB,CAAA;OACP,oBAAC,OAAD;QAAO,SAAQ;QAAQ,OAAM;QAAM,MAAM,oBAAC,iBAAD,EAAmB,CAAA;kBAC1D,oBAAC,MAAD;SAAM,MAAK;mBACR,MAAM,SAAS,GAAG,oBAAoB;SAClC,CAAA;QACD,CAAA;OACR,oBAAC,cAAD;QAAc,MAAM,MAAM,aAAa;QAAe,WAAA;kBACnD,GAAG,0BAA0B;QACjB,CAAA;OACd,EAAA,CAAA;MAEA;;IACF,CAAA;GACF,CAAA;EACF,CAAA;;AAIX,MAAM,eAAe,UAA4B;AAC/C,KAAI,MAAM,KACR,QAAO,oBAAC,iBAAD;EAAiB,MAAM,MAAM;EAAM,WAAW,MAAM;EAAa,CAAA;AAE1E,QAAO,oBAAC,qBAAD,EAAqB,GAAI,OAAS,CAAA"}
@@ -1,14 +1,13 @@
1
- import { t as AlephaUI } from "./core-DFgB3yU4.js";
2
- import { $context, $inject, $module, AlephaError, t } from "alepha";
1
+ import { t as AlephaUI } from "./core-DRtQklr3.js";
2
+ import { $inject, $module, AlephaError, t } from "alepha";
3
3
  import { $dictionary, AlephaReactI18n } from "alepha/react/i18n";
4
- import { Avatar } from "@mantine/core";
5
- import { jsx } from "react/jsx-runtime";
6
- import { IconLogin2, IconLogout2, IconMailCheck, IconPasswordUser, IconSettings, IconUser, IconUserPlus } from "@tabler/icons-react";
7
- import { $page, Redirection, useRouter } from "alepha/react/router";
8
- import { useClient, useInject } from "alepha/react";
9
- import { AlephaReactAuth, ReactAuth, useAuth } from "alepha/react/auth";
4
+ import "@mantine/core";
5
+ import "react/jsx-runtime";
6
+ import { IconLogin2, IconLogout2, IconMailCheck, IconPasswordUser, IconUser, IconUserPlus } from "@tabler/icons-react";
7
+ import { $page, Redirection } from "alepha/react/router";
8
+ import "alepha/react";
9
+ import { AlephaReactAuth, ReactAuth } from "alepha/react/auth";
10
10
  import { $client } from "alepha/server/links";
11
-
12
11
  //#region ../../src/auth/AuthI18n.ts
13
12
  var AuthI18n = class {
14
13
  en = $dictionary({
@@ -125,7 +124,6 @@ var AuthI18n = class {
125
124
  verifyEmailBackToSignIn: "Retour à la connexion"
126
125
  } }) });
127
126
  };
128
-
129
127
  //#endregion
130
128
  //#region ../../src/auth/AuthRouter.ts
131
129
  /**
@@ -141,7 +139,7 @@ var AuthRouter = class {
141
139
  authLayout = $page({
142
140
  label: "Auth",
143
141
  path: "/auth",
144
- lazy: () => import("./AuthLayout-Brri4A-L.js"),
142
+ lazy: () => import("./AuthLayout-Dq5tSLSc.js"),
145
143
  children: () => [
146
144
  this.login,
147
145
  this.register,
@@ -156,7 +154,7 @@ var AuthRouter = class {
156
154
  description: "Sign in to your account",
157
155
  path: "/login",
158
156
  schema: { query: realmQuerySchema },
159
- lazy: () => import("./Login-C12N4oGs.js").then((n) => n.n),
157
+ lazy: () => import("./Login-CqG1iJbn.js").then((n) => n.n),
160
158
  loader: async ({ query, user }) => {
161
159
  if (user) throw new Redirection(query.r || "/");
162
160
  return { realmConfig: await this.loadRealmConfig(query.realm) };
@@ -168,7 +166,7 @@ var AuthRouter = class {
168
166
  description: "Create a new account",
169
167
  path: "/register",
170
168
  schema: { query: realmQuerySchema },
171
- lazy: () => import("./Register-B4hLBeEv.js").then((n) => n.n),
169
+ lazy: () => import("./Register-KKZwr_lL.js").then((n) => n.n),
172
170
  loader: async ({ query, user }) => {
173
171
  if (user) throw new Redirection(query.r || "/");
174
172
  return { realmConfig: await this.loadRealmConfig(query.realm) };
@@ -180,7 +178,7 @@ var AuthRouter = class {
180
178
  description: "Reset your account password",
181
179
  path: "/reset-password",
182
180
  schema: { query: realmQuerySchema },
183
- lazy: () => import("./ResetPassword-D8g9ha1N.js").then((n) => n.n),
181
+ lazy: () => import("./ResetPassword-DMrLFEtr.js").then((n) => n.n),
184
182
  loader: async ({ query, user }) => {
185
183
  if (user) throw new Redirection(query.r || "/");
186
184
  return { realmConfig: await this.loadRealmConfig(query.realm) };
@@ -195,7 +193,7 @@ var AuthRouter = class {
195
193
  email: t.optional(t.string()),
196
194
  token: t.optional(t.string())
197
195
  }) },
198
- lazy: () => import("./VerifyEmail-BjDo0cZA.js").then((n) => n.n)
196
+ lazy: () => import("./VerifyEmail-BFCAFz6T.js").then((n) => n.n)
199
197
  });
200
198
  logout = $page({
201
199
  icon: IconLogout2,
@@ -215,7 +213,7 @@ var AuthRouter = class {
215
213
  description: "View your profile",
216
214
  path: "/profile",
217
215
  can: () => !!this.auth.user,
218
- lazy: () => import("./Profile-DS5q4vOh.js")
216
+ lazy: () => import("./Profile-C0ojJCaG.js")
219
217
  });
220
218
  async loadRealmConfig(realmName) {
221
219
  try {
@@ -226,22 +224,7 @@ var AuthRouter = class {
226
224
  }
227
225
  }
228
226
  };
229
-
230
- //#endregion
231
- //#region ../../src/auth/index.ts
232
- /**
233
- * Authentication UI components.
234
- *
235
- * **Features:**
236
- * - Login page component
237
- * - Register page component
238
- * - Reset password page component
239
- * - Email verification page component
240
- * - UserButton for user menu
241
- *
242
- * @module alepha.ui.auth
243
- */
244
- const AlephaUIAuth = $module({
227
+ $module({
245
228
  name: "alepha.ui.auth",
246
229
  services: [
247
230
  AlephaUI,
@@ -251,7 +234,7 @@ const AlephaUIAuth = $module({
251
234
  AuthI18n
252
235
  ]
253
236
  });
254
-
255
237
  //#endregion
256
- export { };
257
- //# sourceMappingURL=auth-ByVTreDl.js.map
238
+ export {};
239
+
240
+ //# sourceMappingURL=auth-D9qTZzCa.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"auth-ByVTreDl.js","names":[],"sources":["../../src/auth/AuthI18n.ts","../../src/auth/AuthRouter.ts","../../src/auth/index.ts"],"sourcesContent":["import { $dictionary } from \"alepha/react/i18n\";\n\nexport class AuthI18n {\n en = $dictionary({\n name: \"alepha.ui.auth.en\",\n lazy: () => ({\n default: {\n loginSignIn: \"Sign in\",\n loginContinueWith: \"Continue with $1\",\n loginOr: \"OR\",\n loginCancel: \"Cancel\",\n loginForgotPassword: \"Forgot password?\",\n loginNoAccount: \"Don't have an account?\",\n loginSignUp: \"Sign up\",\n loginUsername: \"Username\",\n loginEmail: \"Email\",\n loginPhone: \"Phone number\",\n loginPassword: \"Password\",\n registerCreateAccount: \"Create account\",\n registerContinueWith: \"Continue with $1\",\n registerOr: \"OR\",\n registerCancel: \"Cancel\",\n registerHaveAccount: \"Already have an account?\",\n registerSignIn: \"Sign in\",\n registerUsername: \"Username\",\n registerEmail: \"Email\",\n registerPhone: \"Phone number\",\n registerPassword: \"Password\",\n registerConfirmPassword: \"Confirm password\",\n registerDisabled:\n \"Registration is not available. Please contact your administrator.\",\n registerBackToSignIn: \"Back to sign in\",\n registerVerifyTitle: \"Verify your account\",\n registerVerifyDescription:\n \"Please enter the verification code(s) sent to you.\",\n registerEmailCode: \"Email verification code\",\n registerPhoneCode: \"Phone verification code\",\n registerVerifySubmit: \"Complete Registration\",\n registerVerifyBack: \"Back to registration\",\n resetPasswordTitle: \"Reset password\",\n resetPasswordEmail: \"Email\",\n resetPasswordEnterEmail:\n \"Enter your email address to reset your password\",\n resetPasswordSendCode: \"Send verification code\",\n resetPasswordCodeSent: \"We've sent a verification code to your email.\",\n resetPasswordEnterCode: \"Enter the 6-digit code\",\n resetPasswordResendCode: \"Resend code\",\n resetPasswordEnterNewPassword: \"Create your new password\",\n resetPasswordNewPassword: \"New password\",\n resetPasswordConfirmPassword: \"Confirm password\",\n resetPasswordSetNewPassword: \"Set new password\",\n resetPasswordSuccess: \"Your password has been reset successfully.\",\n resetPasswordBackToSignIn: \"Back to sign in\",\n resetPasswordCancel: \"Cancel\",\n resetPasswordDisabled:\n \"Password reset is not available. Please contact your administrator.\",\n verifyEmailTitle: \"Email Verification\",\n verifyEmailVerifying: \"Verifying your email...\",\n verifyEmailPleaseWait:\n \"Please wait while we verify your email address.\",\n verifyEmailSuccess: \"Your email has been verified successfully.\",\n verifyEmailFailed:\n \"Failed to verify your email. The link may have expired or is invalid.\",\n verifyEmailMissingParams:\n \"Invalid verification link. Email and token are required.\",\n verifyEmailSignIn: \"Sign in to your account\",\n verifyEmailBackToSignIn: \"Back to sign in\",\n },\n }),\n });\n\n fr = $dictionary({\n lazy: () => ({\n default: {\n loginSignIn: \"Se connecter\",\n loginContinueWith: \"Continuer avec $1\",\n loginOr: \"OU\",\n loginCancel: \"Annuler\",\n loginForgotPassword: \"Mot de passe oublié ?\",\n loginNoAccount: \"Vous n'avez pas de compte ?\",\n loginSignUp: \"S'inscrire\",\n loginUsername: \"Nom d'utilisateur\",\n loginEmail: \"E-mail\",\n loginPhone: \"Numéro de téléphone\",\n loginPassword: \"Mot de passe\",\n registerCreateAccount: \"Créer un compte\",\n registerContinueWith: \"Continuer avec $1\",\n registerOr: \"OU\",\n registerCancel: \"Annuler\",\n registerHaveAccount: \"Vous avez déjà un compte ?\",\n registerSignIn: \"Se connecter\",\n registerUsername: \"Nom d'utilisateur\",\n registerEmail: \"E-mail\",\n registerPhone: \"Numéro de téléphone\",\n registerPassword: \"Mot de passe\",\n registerConfirmPassword: \"Confirmer le mot de passe\",\n registerDisabled:\n \"L'inscription n'est pas disponible. Veuillez contacter votre administrateur.\",\n registerBackToSignIn: \"Retour à la connexion\",\n registerVerifyTitle: \"Vérifiez votre compte\",\n registerVerifyDescription:\n \"Veuillez entrer le(s) code(s) de vérification qui vous ont été envoyés.\",\n registerEmailCode: \"Code de vérification par e-mail\",\n registerPhoneCode: \"Code de vérification par téléphone\",\n registerVerifySubmit: \"Terminer l'inscription\",\n registerVerifyBack: \"Retour à l'inscription\",\n resetPasswordTitle: \"Réinitialiser le mot de passe\",\n resetPasswordEmail: \"E-mail\",\n resetPasswordEnterEmail:\n \"Entrez votre adresse e-mail pour réinitialiser votre mot de passe\",\n resetPasswordSendCode: \"Envoyer le code de vérification\",\n resetPasswordCodeSent:\n \"Nous avons envoyé un code de vérification à votre e-mail.\",\n resetPasswordEnterCode: \"Entrez le code à 6 chiffres\",\n resetPasswordResendCode: \"Renvoyer le code\",\n resetPasswordEnterNewPassword: \"Créez votre nouveau mot de passe\",\n resetPasswordNewPassword: \"Nouveau mot de passe\",\n resetPasswordConfirmPassword: \"Confirmer le mot de passe\",\n resetPasswordSetNewPassword: \"Définir le nouveau mot de passe\",\n resetPasswordSuccess:\n \"Votre mot de passe a été réinitialisé avec succès.\",\n resetPasswordBackToSignIn: \"Retour à la connexion\",\n resetPasswordCancel: \"Annuler\",\n resetPasswordDisabled:\n \"La réinitialisation du mot de passe n'est pas disponible. Veuillez contacter votre administrateur.\",\n verifyEmailTitle: \"Vérification de l'e-mail\",\n verifyEmailVerifying: \"Vérification de votre e-mail...\",\n verifyEmailPleaseWait:\n \"Veuillez patienter pendant que nous vérifions votre adresse e-mail.\",\n verifyEmailSuccess: \"Votre e-mail a été vérifié avec succès.\",\n verifyEmailFailed:\n \"Échec de la vérification de votre e-mail. Le lien a peut-être expiré ou est invalide.\",\n verifyEmailMissingParams:\n \"Lien de vérification invalide. L'e-mail et le jeton sont requis.\",\n verifyEmailSignIn: \"Se connecter à votre compte\",\n verifyEmailBackToSignIn: \"Retour à la connexion\",\n },\n }),\n });\n}\n","import {\n IconLogin2,\n IconLogout2,\n IconMailCheck,\n IconPasswordUser,\n IconUser,\n IconUserPlus,\n} from \"@tabler/icons-react\";\nimport { $inject, AlephaError, t } from \"alepha\";\nimport type { RealmController } from \"alepha/api/users\";\nimport { ReactAuth } from \"alepha/react/auth\";\nimport { $page, Redirection } from \"alepha/react/router\";\nimport { $client } from \"alepha/server/links\";\n\n/**\n * Schema for realm query parameter used across auth pages.\n */\nconst realmQuerySchema = t.object({\n r: t.optional(t.string({ description: \"Redirect URL after authentication\" })),\n realm: t.optional(\n t.string({ description: \"User realm name for multi-tenant auth\" }),\n ),\n});\n\nexport class AuthRouter {\n protected readonly realmClient = $client<RealmController>();\n protected readonly auth = $inject(ReactAuth);\n\n authLayout = $page({\n label: \"Auth\",\n path: \"/auth\",\n lazy: () => import(\"./components/AuthLayout.tsx\"),\n children: () => [\n this.login,\n this.register,\n this.resetPassword,\n this.verifyEmail,\n this.profile,\n ],\n });\n\n login = $page({\n icon: IconLogin2,\n label: \"Sign In\",\n description: \"Sign in to your account\",\n path: \"/login\",\n schema: {\n query: realmQuerySchema,\n },\n lazy: () => import(\"./components/Login.tsx\"),\n loader: async ({ query, user }) => {\n if (user) {\n throw new Redirection(query.r || \"/\");\n }\n return {\n realmConfig: await this.loadRealmConfig(query.realm),\n };\n },\n });\n\n register = $page({\n icon: IconUserPlus,\n label: \"Register\",\n description: \"Create a new account\",\n path: \"/register\",\n schema: {\n query: realmQuerySchema,\n },\n lazy: () => import(\"./components/Register.tsx\"),\n loader: async ({ query, user }) => {\n if (user) {\n throw new Redirection(query.r || \"/\");\n }\n return {\n realmConfig: await this.loadRealmConfig(query.realm),\n };\n },\n });\n\n resetPassword = $page({\n icon: IconPasswordUser,\n label: \"Reset Password\",\n description: \"Reset your account password\",\n path: \"/reset-password\",\n schema: {\n query: realmQuerySchema,\n },\n lazy: () => import(\"./components/ResetPassword.tsx\"),\n loader: async ({ query, user }) => {\n if (user) {\n throw new Redirection(query.r || \"/\");\n }\n return {\n realmConfig: await this.loadRealmConfig(query.realm),\n };\n },\n });\n\n verifyEmail = $page({\n icon: IconMailCheck,\n label: \"Verify Email\",\n description: \"Verify your email address\",\n path: \"/verify-email\",\n schema: {\n query: t.object({\n email: t.optional(t.string()),\n token: t.optional(t.string()),\n }),\n },\n lazy: () => import(\"./components/VerifyEmail.tsx\"),\n });\n\n logout = $page({\n icon: IconLogout2,\n label: \"Sign Out\",\n description: \"Sign out of your account\",\n path: \"/logout\",\n component: () => null,\n loader: () => {\n this.auth.logout();\n return {};\n },\n });\n\n profile = $page({\n name: \"userProfile\",\n icon: IconUser,\n label: \"Profile\",\n description: \"View your profile\",\n path: \"/profile\",\n can: () => !!this.auth.user,\n lazy: () => import(\"./components/Profile.tsx\"),\n });\n\n protected async loadRealmConfig(realmName?: string) {\n try {\n return await this.realmClient.getRealmConfig({\n query: { realmName },\n });\n } catch (e) {\n if (e instanceof AlephaError) {\n throw new AlephaError(\n \"Missing Realm Configuration - Did you forget to add '$realm()' to your application?\",\n e,\n );\n }\n throw e;\n }\n }\n}\n","import { AlephaUI } from \"@alepha/ui\";\nimport { $module } from \"alepha\";\nimport { AlephaReactAuth } from \"alepha/react/auth\";\nimport { AlephaReactI18n } from \"alepha/react/i18n\";\nimport { AuthI18n } from \"./AuthI18n.ts\";\nimport { AuthRouter } from \"./AuthRouter.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./AuthRouter.ts\";\nexport type { UserButtonProps } from \"./components/buttons/UserButton.tsx\";\nexport { default as UserButton } from \"./components/buttons/UserButton.tsx\";\nexport { default as Login } from \"./components/Login.tsx\";\nexport { default as Register } from \"./components/Register.tsx\";\nexport { default as ResetPassword } from \"./components/ResetPassword.tsx\";\nexport type { VerifyEmailStep } from \"./components/VerifyEmail.tsx\";\nexport { default as VerifyEmail } from \"./components/VerifyEmail.tsx\";\nexport * from \"./primitives/$uiAuth.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Authentication UI components.\n *\n * **Features:**\n * - Login page component\n * - Register page component\n * - Reset password page component\n * - Email verification page component\n * - UserButton for user menu\n *\n * @module alepha.ui.auth\n */\nexport const AlephaUIAuth = $module({\n name: \"alepha.ui.auth\",\n services: [AlephaUI, AlephaReactAuth, AlephaReactI18n, AuthRouter, AuthI18n],\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"auth-D9qTZzCa.js","names":[],"sources":["../../src/auth/AuthI18n.ts","../../src/auth/AuthRouter.ts","../../src/auth/index.ts"],"sourcesContent":["import { $dictionary } from \"alepha/react/i18n\";\n\nexport class AuthI18n {\n en = $dictionary({\n name: \"alepha.ui.auth.en\",\n lazy: () => ({\n default: {\n loginSignIn: \"Sign in\",\n loginContinueWith: \"Continue with $1\",\n loginOr: \"OR\",\n loginCancel: \"Cancel\",\n loginForgotPassword: \"Forgot password?\",\n loginNoAccount: \"Don't have an account?\",\n loginSignUp: \"Sign up\",\n loginUsername: \"Username\",\n loginEmail: \"Email\",\n loginPhone: \"Phone number\",\n loginPassword: \"Password\",\n registerCreateAccount: \"Create account\",\n registerContinueWith: \"Continue with $1\",\n registerOr: \"OR\",\n registerCancel: \"Cancel\",\n registerHaveAccount: \"Already have an account?\",\n registerSignIn: \"Sign in\",\n registerUsername: \"Username\",\n registerEmail: \"Email\",\n registerPhone: \"Phone number\",\n registerPassword: \"Password\",\n registerConfirmPassword: \"Confirm password\",\n registerDisabled:\n \"Registration is not available. Please contact your administrator.\",\n registerBackToSignIn: \"Back to sign in\",\n registerVerifyTitle: \"Verify your account\",\n registerVerifyDescription:\n \"Please enter the verification code(s) sent to you.\",\n registerEmailCode: \"Email verification code\",\n registerPhoneCode: \"Phone verification code\",\n registerVerifySubmit: \"Complete Registration\",\n registerVerifyBack: \"Back to registration\",\n resetPasswordTitle: \"Reset password\",\n resetPasswordEmail: \"Email\",\n resetPasswordEnterEmail:\n \"Enter your email address to reset your password\",\n resetPasswordSendCode: \"Send verification code\",\n resetPasswordCodeSent: \"We've sent a verification code to your email.\",\n resetPasswordEnterCode: \"Enter the 6-digit code\",\n resetPasswordResendCode: \"Resend code\",\n resetPasswordEnterNewPassword: \"Create your new password\",\n resetPasswordNewPassword: \"New password\",\n resetPasswordConfirmPassword: \"Confirm password\",\n resetPasswordSetNewPassword: \"Set new password\",\n resetPasswordSuccess: \"Your password has been reset successfully.\",\n resetPasswordBackToSignIn: \"Back to sign in\",\n resetPasswordCancel: \"Cancel\",\n resetPasswordDisabled:\n \"Password reset is not available. Please contact your administrator.\",\n verifyEmailTitle: \"Email Verification\",\n verifyEmailVerifying: \"Verifying your email...\",\n verifyEmailPleaseWait:\n \"Please wait while we verify your email address.\",\n verifyEmailSuccess: \"Your email has been verified successfully.\",\n verifyEmailFailed:\n \"Failed to verify your email. The link may have expired or is invalid.\",\n verifyEmailMissingParams:\n \"Invalid verification link. Email and token are required.\",\n verifyEmailSignIn: \"Sign in to your account\",\n verifyEmailBackToSignIn: \"Back to sign in\",\n },\n }),\n });\n\n fr = $dictionary({\n lazy: () => ({\n default: {\n loginSignIn: \"Se connecter\",\n loginContinueWith: \"Continuer avec $1\",\n loginOr: \"OU\",\n loginCancel: \"Annuler\",\n loginForgotPassword: \"Mot de passe oublié ?\",\n loginNoAccount: \"Vous n'avez pas de compte ?\",\n loginSignUp: \"S'inscrire\",\n loginUsername: \"Nom d'utilisateur\",\n loginEmail: \"E-mail\",\n loginPhone: \"Numéro de téléphone\",\n loginPassword: \"Mot de passe\",\n registerCreateAccount: \"Créer un compte\",\n registerContinueWith: \"Continuer avec $1\",\n registerOr: \"OU\",\n registerCancel: \"Annuler\",\n registerHaveAccount: \"Vous avez déjà un compte ?\",\n registerSignIn: \"Se connecter\",\n registerUsername: \"Nom d'utilisateur\",\n registerEmail: \"E-mail\",\n registerPhone: \"Numéro de téléphone\",\n registerPassword: \"Mot de passe\",\n registerConfirmPassword: \"Confirmer le mot de passe\",\n registerDisabled:\n \"L'inscription n'est pas disponible. Veuillez contacter votre administrateur.\",\n registerBackToSignIn: \"Retour à la connexion\",\n registerVerifyTitle: \"Vérifiez votre compte\",\n registerVerifyDescription:\n \"Veuillez entrer le(s) code(s) de vérification qui vous ont été envoyés.\",\n registerEmailCode: \"Code de vérification par e-mail\",\n registerPhoneCode: \"Code de vérification par téléphone\",\n registerVerifySubmit: \"Terminer l'inscription\",\n registerVerifyBack: \"Retour à l'inscription\",\n resetPasswordTitle: \"Réinitialiser le mot de passe\",\n resetPasswordEmail: \"E-mail\",\n resetPasswordEnterEmail:\n \"Entrez votre adresse e-mail pour réinitialiser votre mot de passe\",\n resetPasswordSendCode: \"Envoyer le code de vérification\",\n resetPasswordCodeSent:\n \"Nous avons envoyé un code de vérification à votre e-mail.\",\n resetPasswordEnterCode: \"Entrez le code à 6 chiffres\",\n resetPasswordResendCode: \"Renvoyer le code\",\n resetPasswordEnterNewPassword: \"Créez votre nouveau mot de passe\",\n resetPasswordNewPassword: \"Nouveau mot de passe\",\n resetPasswordConfirmPassword: \"Confirmer le mot de passe\",\n resetPasswordSetNewPassword: \"Définir le nouveau mot de passe\",\n resetPasswordSuccess:\n \"Votre mot de passe a été réinitialisé avec succès.\",\n resetPasswordBackToSignIn: \"Retour à la connexion\",\n resetPasswordCancel: \"Annuler\",\n resetPasswordDisabled:\n \"La réinitialisation du mot de passe n'est pas disponible. Veuillez contacter votre administrateur.\",\n verifyEmailTitle: \"Vérification de l'e-mail\",\n verifyEmailVerifying: \"Vérification de votre e-mail...\",\n verifyEmailPleaseWait:\n \"Veuillez patienter pendant que nous vérifions votre adresse e-mail.\",\n verifyEmailSuccess: \"Votre e-mail a été vérifié avec succès.\",\n verifyEmailFailed:\n \"Échec de la vérification de votre e-mail. Le lien a peut-être expiré ou est invalide.\",\n verifyEmailMissingParams:\n \"Lien de vérification invalide. L'e-mail et le jeton sont requis.\",\n verifyEmailSignIn: \"Se connecter à votre compte\",\n verifyEmailBackToSignIn: \"Retour à la connexion\",\n },\n }),\n });\n}\n","import {\n IconLogin2,\n IconLogout2,\n IconMailCheck,\n IconPasswordUser,\n IconUser,\n IconUserPlus,\n} from \"@tabler/icons-react\";\nimport { $inject, AlephaError, t } from \"alepha\";\nimport type { RealmController } from \"alepha/api/users\";\nimport { ReactAuth } from \"alepha/react/auth\";\nimport { $page, Redirection } from \"alepha/react/router\";\nimport { $client } from \"alepha/server/links\";\n\n/**\n * Schema for realm query parameter used across auth pages.\n */\nconst realmQuerySchema = t.object({\n r: t.optional(t.string({ description: \"Redirect URL after authentication\" })),\n realm: t.optional(\n t.string({ description: \"User realm name for multi-tenant auth\" }),\n ),\n});\n\nexport class AuthRouter {\n protected readonly realmClient = $client<RealmController>();\n protected readonly auth = $inject(ReactAuth);\n\n authLayout = $page({\n label: \"Auth\",\n path: \"/auth\",\n lazy: () => import(\"./components/AuthLayout.tsx\"),\n children: () => [\n this.login,\n this.register,\n this.resetPassword,\n this.verifyEmail,\n this.profile,\n ],\n });\n\n login = $page({\n icon: IconLogin2,\n label: \"Sign In\",\n description: \"Sign in to your account\",\n path: \"/login\",\n schema: {\n query: realmQuerySchema,\n },\n lazy: () => import(\"./components/Login.tsx\"),\n loader: async ({ query, user }) => {\n if (user) {\n throw new Redirection(query.r || \"/\");\n }\n return {\n realmConfig: await this.loadRealmConfig(query.realm),\n };\n },\n });\n\n register = $page({\n icon: IconUserPlus,\n label: \"Register\",\n description: \"Create a new account\",\n path: \"/register\",\n schema: {\n query: realmQuerySchema,\n },\n lazy: () => import(\"./components/Register.tsx\"),\n loader: async ({ query, user }) => {\n if (user) {\n throw new Redirection(query.r || \"/\");\n }\n return {\n realmConfig: await this.loadRealmConfig(query.realm),\n };\n },\n });\n\n resetPassword = $page({\n icon: IconPasswordUser,\n label: \"Reset Password\",\n description: \"Reset your account password\",\n path: \"/reset-password\",\n schema: {\n query: realmQuerySchema,\n },\n lazy: () => import(\"./components/ResetPassword.tsx\"),\n loader: async ({ query, user }) => {\n if (user) {\n throw new Redirection(query.r || \"/\");\n }\n return {\n realmConfig: await this.loadRealmConfig(query.realm),\n };\n },\n });\n\n verifyEmail = $page({\n icon: IconMailCheck,\n label: \"Verify Email\",\n description: \"Verify your email address\",\n path: \"/verify-email\",\n schema: {\n query: t.object({\n email: t.optional(t.string()),\n token: t.optional(t.string()),\n }),\n },\n lazy: () => import(\"./components/VerifyEmail.tsx\"),\n });\n\n logout = $page({\n icon: IconLogout2,\n label: \"Sign Out\",\n description: \"Sign out of your account\",\n path: \"/logout\",\n component: () => null,\n loader: () => {\n this.auth.logout();\n return {};\n },\n });\n\n profile = $page({\n name: \"userProfile\",\n icon: IconUser,\n label: \"Profile\",\n description: \"View your profile\",\n path: \"/profile\",\n can: () => !!this.auth.user,\n lazy: () => import(\"./components/Profile.tsx\"),\n });\n\n protected async loadRealmConfig(realmName?: string) {\n try {\n return await this.realmClient.getRealmConfig({\n query: { realmName },\n });\n } catch (e) {\n if (e instanceof AlephaError) {\n throw new AlephaError(\n \"Missing Realm Configuration - Did you forget to add '$realm()' to your application?\",\n e,\n );\n }\n throw e;\n }\n }\n}\n","import { AlephaUI } from \"@alepha/ui\";\nimport { $module } from \"alepha\";\nimport { AlephaReactAuth } from \"alepha/react/auth\";\nimport { AlephaReactI18n } from \"alepha/react/i18n\";\nimport { AuthI18n } from \"./AuthI18n.ts\";\nimport { AuthRouter } from \"./AuthRouter.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\nexport * from \"./AuthRouter.ts\";\nexport type { UserButtonProps } from \"./components/buttons/UserButton.tsx\";\nexport { default as UserButton } from \"./components/buttons/UserButton.tsx\";\nexport { default as Login } from \"./components/Login.tsx\";\nexport { default as Register } from \"./components/Register.tsx\";\nexport { default as ResetPassword } from \"./components/ResetPassword.tsx\";\nexport type { VerifyEmailStep } from \"./components/VerifyEmail.tsx\";\nexport { default as VerifyEmail } from \"./components/VerifyEmail.tsx\";\nexport * from \"./primitives/$uiAuth.ts\";\n\n// ---------------------------------------------------------------------------------------------------------------------\n\n/**\n * Authentication UI components.\n *\n * **Features:**\n * - Login page component\n * - Register page component\n * - Reset password page component\n * - Email verification page component\n * - UserButton for user menu\n *\n * @module alepha.ui.auth\n */\nexport const AlephaUIAuth = $module({\n name: \"alepha.ui.auth\",\n services: [AlephaUI, AlephaReactAuth, AlephaReactI18n, AuthRouter, AuthI18n],\n});\n"],"mappings":";;;;;;;;;;;AAEA,IAAa,WAAb,MAAsB;CACpB,KAAK,YAAY;EACf,MAAM;EACN,aAAa,EACX,SAAS;GACP,aAAa;GACb,mBAAmB;GACnB,SAAS;GACT,aAAa;GACb,qBAAqB;GACrB,gBAAgB;GAChB,aAAa;GACb,eAAe;GACf,YAAY;GACZ,YAAY;GACZ,eAAe;GACf,uBAAuB;GACvB,sBAAsB;GACtB,YAAY;GACZ,gBAAgB;GAChB,qBAAqB;GACrB,gBAAgB;GAChB,kBAAkB;GAClB,eAAe;GACf,eAAe;GACf,kBAAkB;GAClB,yBAAyB;GACzB,kBACE;GACF,sBAAsB;GACtB,qBAAqB;GACrB,2BACE;GACF,mBAAmB;GACnB,mBAAmB;GACnB,sBAAsB;GACtB,oBAAoB;GACpB,oBAAoB;GACpB,oBAAoB;GACpB,yBACE;GACF,uBAAuB;GACvB,uBAAuB;GACvB,wBAAwB;GACxB,yBAAyB;GACzB,+BAA+B;GAC/B,0BAA0B;GAC1B,8BAA8B;GAC9B,6BAA6B;GAC7B,sBAAsB;GACtB,2BAA2B;GAC3B,qBAAqB;GACrB,uBACE;GACF,kBAAkB;GAClB,sBAAsB;GACtB,uBACE;GACF,oBAAoB;GACpB,mBACE;GACF,0BACE;GACF,mBAAmB;GACnB,yBAAyB;GAC1B,EACF;EACF,CAAC;CAEF,KAAK,YAAY,EACf,aAAa,EACX,SAAS;EACP,aAAa;EACb,mBAAmB;EACnB,SAAS;EACT,aAAa;EACb,qBAAqB;EACrB,gBAAgB;EAChB,aAAa;EACb,eAAe;EACf,YAAY;EACZ,YAAY;EACZ,eAAe;EACf,uBAAuB;EACvB,sBAAsB;EACtB,YAAY;EACZ,gBAAgB;EAChB,qBAAqB;EACrB,gBAAgB;EAChB,kBAAkB;EAClB,eAAe;EACf,eAAe;EACf,kBAAkB;EAClB,yBAAyB;EACzB,kBACE;EACF,sBAAsB;EACtB,qBAAqB;EACrB,2BACE;EACF,mBAAmB;EACnB,mBAAmB;EACnB,sBAAsB;EACtB,oBAAoB;EACpB,oBAAoB;EACpB,oBAAoB;EACpB,yBACE;EACF,uBAAuB;EACvB,uBACE;EACF,wBAAwB;EACxB,yBAAyB;EACzB,+BAA+B;EAC/B,0BAA0B;EAC1B,8BAA8B;EAC9B,6BAA6B;EAC7B,sBACE;EACF,2BAA2B;EAC3B,qBAAqB;EACrB,uBACE;EACF,kBAAkB;EAClB,sBAAsB;EACtB,uBACE;EACF,oBAAoB;EACpB,mBACE;EACF,0BACE;EACF,mBAAmB;EACnB,yBAAyB;EAC1B,EACF,GACF,CAAC;;;;;;;ACzHJ,MAAM,mBAAmB,EAAE,OAAO;CAChC,GAAG,EAAE,SAAS,EAAE,OAAO,EAAE,aAAa,qCAAqC,CAAC,CAAC;CAC7E,OAAO,EAAE,SACP,EAAE,OAAO,EAAE,aAAa,yCAAyC,CAAC,CACnE;CACF,CAAC;AAEF,IAAa,aAAb,MAAwB;CACtB,cAAiC,SAA0B;CAC3D,OAA0B,QAAQ,UAAU;CAE5C,aAAa,MAAM;EACjB,OAAO;EACP,MAAM;EACN,YAAY,OAAO;EACnB,gBAAgB;GACd,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK;GACN;EACF,CAAC;CAEF,QAAQ,MAAM;EACZ,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,QAAQ,EACN,OAAO,kBACR;EACD,YAAY,OAAO,uBAAA,MAAA,MAAA,EAAA,EAAA;EACnB,QAAQ,OAAO,EAAE,OAAO,WAAW;AACjC,OAAI,KACF,OAAM,IAAI,YAAY,MAAM,KAAK,IAAI;AAEvC,UAAO,EACL,aAAa,MAAM,KAAK,gBAAgB,MAAM,MAAM,EACrD;;EAEJ,CAAC;CAEF,WAAW,MAAM;EACf,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,QAAQ,EACN,OAAO,kBACR;EACD,YAAY,OAAO,0BAAA,MAAA,MAAA,EAAA,EAAA;EACnB,QAAQ,OAAO,EAAE,OAAO,WAAW;AACjC,OAAI,KACF,OAAM,IAAI,YAAY,MAAM,KAAK,IAAI;AAEvC,UAAO,EACL,aAAa,MAAM,KAAK,gBAAgB,MAAM,MAAM,EACrD;;EAEJ,CAAC;CAEF,gBAAgB,MAAM;EACpB,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,QAAQ,EACN,OAAO,kBACR;EACD,YAAY,OAAO,+BAAA,MAAA,MAAA,EAAA,EAAA;EACnB,QAAQ,OAAO,EAAE,OAAO,WAAW;AACjC,OAAI,KACF,OAAM,IAAI,YAAY,MAAM,KAAK,IAAI;AAEvC,UAAO,EACL,aAAa,MAAM,KAAK,gBAAgB,MAAM,MAAM,EACrD;;EAEJ,CAAC;CAEF,cAAc,MAAM;EAClB,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,QAAQ,EACN,OAAO,EAAE,OAAO;GACd,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;GAC7B,OAAO,EAAE,SAAS,EAAE,QAAQ,CAAC;GAC9B,CAAC,EACH;EACD,YAAY,OAAO,6BAAA,MAAA,MAAA,EAAA,EAAA;EACpB,CAAC;CAEF,SAAS,MAAM;EACb,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,iBAAiB;EACjB,cAAc;AACZ,QAAK,KAAK,QAAQ;AAClB,UAAO,EAAE;;EAEZ,CAAC;CAEF,UAAU,MAAM;EACd,MAAM;EACN,MAAM;EACN,OAAO;EACP,aAAa;EACb,MAAM;EACN,WAAW,CAAC,CAAC,KAAK,KAAK;EACvB,YAAY,OAAO;EACpB,CAAC;CAEF,MAAgB,gBAAgB,WAAoB;AAClD,MAAI;AACF,UAAO,MAAM,KAAK,YAAY,eAAe,EAC3C,OAAO,EAAE,WAAW,EACrB,CAAC;WACK,GAAG;AACV,OAAI,aAAa,YACf,OAAM,IAAI,YACR,uFACA,EACD;AAEH,SAAM;;;;ACjHgB,QAAQ;CAClC,MAAM;CACN,UAAU;EAAC;EAAU;EAAiB;EAAiB;EAAY;EAAS;CAC7E,CAAC"}