@better-auth-ui/heroui 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/dist/components/auth/auth-provider.d.ts +1 -1
  2. package/dist/components/auth/auth-provider.js +15 -11
  3. package/dist/components/auth/auth.d.ts +3 -3
  4. package/dist/components/auth/auth.js +36 -41
  5. package/dist/components/auth/field-separator.d.ts +1 -1
  6. package/dist/components/auth/field-separator.js +17 -4
  7. package/dist/components/auth/forgot-password.d.ts +1 -1
  8. package/dist/components/auth/forgot-password.js +69 -27
  9. package/dist/components/auth/magic-link-button.d.ts +1 -1
  10. package/dist/components/auth/magic-link-button.js +15 -18
  11. package/dist/components/auth/magic-link.d.ts +2 -2
  12. package/dist/components/auth/magic-link.js +110 -42
  13. package/dist/components/auth/passkey-button.d.ts +4 -0
  14. package/dist/components/auth/passkey-button.js +24 -0
  15. package/dist/components/auth/provider-buttons.d.ts +1 -1
  16. package/dist/components/auth/provider-buttons.js +26 -33
  17. package/dist/components/auth/reset-password.d.ts +1 -1
  18. package/dist/components/auth/reset-password.js +146 -57
  19. package/dist/components/auth/sign-in.d.ts +2 -2
  20. package/dist/components/auth/sign-in.js +163 -63
  21. package/dist/components/auth/sign-out.js +26 -32
  22. package/dist/components/auth/sign-up.d.ts +2 -2
  23. package/dist/components/auth/sign-up.js +240 -70
  24. package/dist/components/email/email-changed-email.d.ts +2 -2
  25. package/dist/components/email/email-changed-email.js +29 -22
  26. package/dist/components/email/email-verification-email.d.ts +2 -2
  27. package/dist/components/email/email-verification-email.js +29 -22
  28. package/dist/components/email/magic-link-email.d.ts +2 -2
  29. package/dist/components/email/magic-link-email.js +29 -22
  30. package/dist/components/email/new-device-email.d.ts +2 -2
  31. package/dist/components/email/new-device-email.js +29 -22
  32. package/dist/components/email/otp-email.d.ts +2 -2
  33. package/dist/components/email/otp-email.js +28 -21
  34. package/dist/components/email/password-changed-email.d.ts +2 -2
  35. package/dist/components/email/password-changed-email.js +29 -22
  36. package/dist/components/email/reset-password-email.d.ts +2 -2
  37. package/dist/components/email/reset-password-email.js +29 -22
  38. package/dist/components/settings/account/account-settings.d.ts +2 -2
  39. package/dist/components/settings/account/account-settings.js +22 -19
  40. package/dist/components/settings/account/appearance.d.ts +1 -1
  41. package/dist/components/settings/account/appearance.js +70 -27
  42. package/dist/components/settings/account/change-avatar.js +88 -55
  43. package/dist/components/settings/account/change-email.d.ts +1 -1
  44. package/dist/components/settings/account/change-email.js +56 -28
  45. package/dist/components/settings/account/manage-account.d.ts +1 -1
  46. package/dist/components/settings/account/manage-account.js +50 -31
  47. package/dist/components/settings/account/manage-accounts.d.ts +1 -1
  48. package/dist/components/settings/account/manage-accounts.js +32 -36
  49. package/dist/components/settings/account/user-profile.d.ts +3 -3
  50. package/dist/components/settings/account/user-profile.js +105 -22
  51. package/dist/components/settings/security/active-session.d.ts +1 -1
  52. package/dist/components/settings/security/active-session.js +60 -51
  53. package/dist/components/settings/security/active-sessions.d.ts +1 -1
  54. package/dist/components/settings/security/active-sessions.js +32 -26
  55. package/dist/components/settings/security/change-password.d.ts +1 -1
  56. package/dist/components/settings/security/change-password.js +189 -76
  57. package/dist/components/settings/security/danger-zone.d.ts +2 -2
  58. package/dist/components/settings/security/danger-zone.js +17 -11
  59. package/dist/components/settings/security/delete-user.d.ts +1 -1
  60. package/dist/components/settings/security/delete-user.js +96 -46
  61. package/dist/components/settings/security/linked-account.d.ts +1 -1
  62. package/dist/components/settings/security/linked-account.js +61 -47
  63. package/dist/components/settings/security/linked-accounts.d.ts +1 -1
  64. package/dist/components/settings/security/linked-accounts.js +43 -40
  65. package/dist/components/settings/security/passkey.d.ts +8 -0
  66. package/dist/components/settings/security/passkey.js +43 -0
  67. package/dist/components/settings/security/passkeys.d.ts +6 -0
  68. package/dist/components/settings/security/passkeys.js +53 -0
  69. package/dist/components/settings/security/security-settings.d.ts +2 -2
  70. package/dist/components/settings/security/security-settings.js +24 -20
  71. package/dist/components/settings/settings.d.ts +3 -3
  72. package/dist/components/settings/settings.js +44 -27
  73. package/dist/components/user/switch-account-item.d.ts +1 -1
  74. package/dist/components/user/switch-account-item.js +19 -15
  75. package/dist/components/user/switch-account-menu.js +27 -28
  76. package/dist/components/user/user-avatar.d.ts +3 -3
  77. package/dist/components/user/user-avatar.js +28 -30
  78. package/dist/components/user/user-button.d.ts +1 -1
  79. package/dist/components/user/user-button.js +90 -23
  80. package/dist/components/user/user-view.d.ts +3 -3
  81. package/dist/components/user/user-view.js +36 -23
  82. package/dist/core.d.ts +1 -1
  83. package/dist/index.d.ts +35 -33
  84. package/dist/index.js +36 -33
  85. package/dist/react-exports.d.ts +1 -1
  86. package/package.json +17 -10
  87. package/src/components/auth/auth.tsx +1 -1
  88. package/src/components/auth/magic-link.tsx +4 -0
  89. package/src/components/auth/passkey-button.tsx +36 -0
  90. package/src/components/auth/sign-in.tsx +67 -30
  91. package/src/components/auth/sign-up.tsx +97 -3
  92. package/src/components/settings/account/user-profile.tsx +121 -6
  93. package/src/components/settings/security/passkey.tsx +51 -0
  94. package/src/components/settings/security/passkeys.tsx +104 -0
  95. package/src/components/settings/security/security-settings.tsx +3 -1
  96. package/src/components/settings/settings.tsx +1 -1
  97. package/src/index.tsx +2 -0
  98. package/dist/components/account/account.d.ts +0 -18
  99. package/dist/components/account/account.js +0 -24
  100. package/dist/components/account/settings/account-settings.d.ts +0 -5
  101. package/dist/components/account/settings/account-settings.js +0 -6
  102. package/dist/components/account/settings/settings.d.ts +0 -5
  103. package/dist/components/account/settings/settings.js +0 -5
  104. package/dist/components/account/settings/user-profile.d.ts +0 -5
  105. package/dist/components/account/settings/user-profile.js +0 -20
  106. package/dist/components/settings/account/accounts.d.ts +0 -14
  107. package/dist/components/settings/account/accounts.js +0 -26
  108. package/dist/components/settings/account/theme-selector.d.ts +0 -16
  109. package/dist/components/settings/account/theme-selector.js +0 -33
  110. package/dist/components/settings/account/theme-settings.d.ts +0 -16
  111. package/dist/components/settings/account/theme-settings.js +0 -31
  112. package/dist/components/settings/account-settings.d.ts +0 -5
  113. package/dist/components/settings/account-settings.js +0 -6
  114. package/dist/components/settings/account.d.ts +0 -18
  115. package/dist/components/settings/account.js +0 -24
  116. package/dist/components/settings/security/connected-account.d.ts +0 -16
  117. package/dist/components/settings/security/connected-account.js +0 -46
  118. package/dist/components/settings/security/connected-accounts.d.ts +0 -15
  119. package/dist/components/settings/security/connected-accounts.js +0 -31
  120. package/dist/components/settings/security/sessions.d.ts +0 -14
  121. package/dist/components/settings/security/sessions.js +0 -40
  122. package/dist/components/settings/settings/account-settings.d.ts +0 -5
  123. package/dist/components/settings/settings/account-settings.js +0 -6
  124. package/dist/components/settings/settings/user-profile.d.ts +0 -5
  125. package/dist/components/settings/settings/user-profile.js +0 -20
  126. package/dist/components/settings/user-profile.d.ts +0 -5
  127. package/dist/components/settings/user-profile.js +0 -20
  128. package/dist/components/user/switch-account-popover.d.ts +0 -10
  129. package/dist/components/user/switch-account-popover.js +0 -25
  130. package/dist/components/user/switch-account-submenu.d.ts +0 -10
  131. package/dist/components/user/switch-account-submenu.js +0 -25
  132. package/dist/hooks/use-auth.d.ts +0 -2
  133. package/dist/hooks/use-auth.js +0 -8
  134. package/dist/hooks/use-redirect-to.d.ts +0 -8
  135. package/dist/hooks/use-redirect-to.js +0 -19
  136. package/dist/hooks/use-sign-in.d.ts +0 -8
  137. package/dist/hooks/use-sign-in.js +0 -53
  138. package/dist/lib/utils.d.ts +0 -2
  139. package/dist/lib/utils.js +0 -5
  140. package/dist/server.d.ts +0 -1
  141. package/dist/server.js +0 -1
  142. package/dist/src/components/auth/auth-provider.d.ts +0 -8
  143. package/dist/src/components/auth/auth-provider.js +0 -13
  144. package/dist/src/components/auth/auth.d.ts +0 -22
  145. package/dist/src/components/auth/auth.js +0 -42
  146. package/dist/src/components/auth/field-separator.d.ts +0 -4
  147. package/dist/src/components/auth/field-separator.js +0 -5
  148. package/dist/src/components/auth/forgot-password.d.ts +0 -15
  149. package/dist/src/components/auth/forgot-password.js +0 -29
  150. package/dist/src/components/auth/magic-link-button.d.ts +0 -13
  151. package/dist/src/components/auth/magic-link-button.js +0 -20
  152. package/dist/src/components/auth/magic-link.d.ts +0 -17
  153. package/dist/src/components/auth/magic-link.js +0 -37
  154. package/dist/src/components/auth/provider-buttons.d.ts +0 -19
  155. package/dist/src/components/auth/provider-buttons.js +0 -35
  156. package/dist/src/components/auth/reset-password.d.ts +0 -11
  157. package/dist/src/components/auth/reset-password.js +0 -59
  158. package/dist/src/components/auth/sign-in.d.ts +0 -14
  159. package/dist/src/components/auth/sign-in.js +0 -58
  160. package/dist/src/components/auth/sign-out.d.ts +0 -11
  161. package/dist/src/components/auth/sign-out.js +0 -34
  162. package/dist/src/components/auth/sign-up.d.ts +0 -19
  163. package/dist/src/components/auth/sign-up.js +0 -65
  164. package/dist/src/components/email/email-changed-email.d.ts +0 -3
  165. package/dist/src/components/email/email-changed-email.js +0 -23
  166. package/dist/src/components/email/email-verification-email.d.ts +0 -3
  167. package/dist/src/components/email/email-verification-email.js +0 -23
  168. package/dist/src/components/email/magic-link-email.d.ts +0 -3
  169. package/dist/src/components/email/magic-link-email.js +0 -23
  170. package/dist/src/components/email/new-device-email.d.ts +0 -3
  171. package/dist/src/components/email/new-device-email.js +0 -23
  172. package/dist/src/components/email/otp-email.d.ts +0 -3
  173. package/dist/src/components/email/otp-email.js +0 -22
  174. package/dist/src/components/email/password-changed-email.d.ts +0 -3
  175. package/dist/src/components/email/password-changed-email.js +0 -23
  176. package/dist/src/components/email/reset-password-email.d.ts +0 -3
  177. package/dist/src/components/email/reset-password-email.js +0 -23
  178. package/dist/src/components/settings/account/account-settings.d.ts +0 -13
  179. package/dist/src/components/settings/account/account-settings.js +0 -19
  180. package/dist/src/components/settings/account/appearance.d.ts +0 -16
  181. package/dist/src/components/settings/account/appearance.js +0 -28
  182. package/dist/src/components/settings/account/change-email.d.ts +0 -15
  183. package/dist/src/components/settings/account/change-email.js +0 -35
  184. package/dist/src/components/settings/account/manage-account.d.ts +0 -19
  185. package/dist/src/components/settings/account/manage-account.js +0 -27
  186. package/dist/src/components/settings/account/manage-accounts.d.ts +0 -14
  187. package/dist/src/components/settings/account/manage-accounts.js +0 -27
  188. package/dist/src/components/settings/account/user-profile.d.ts +0 -13
  189. package/dist/src/components/settings/account/user-profile.js +0 -29
  190. package/dist/src/components/settings/security/active-session.d.ts +0 -14
  191. package/dist/src/components/settings/security/active-session.js +0 -35
  192. package/dist/src/components/settings/security/active-sessions.d.ts +0 -14
  193. package/dist/src/components/settings/security/active-sessions.js +0 -29
  194. package/dist/src/components/settings/security/change-password.d.ts +0 -15
  195. package/dist/src/components/settings/security/change-password.js +0 -57
  196. package/dist/src/components/settings/security/linked-account.d.ts +0 -16
  197. package/dist/src/components/settings/security/linked-account.js +0 -46
  198. package/dist/src/components/settings/security/linked-accounts.d.ts +0 -15
  199. package/dist/src/components/settings/security/linked-accounts.js +0 -31
  200. package/dist/src/components/settings/security/security-settings.d.ts +0 -15
  201. package/dist/src/components/settings/security/security-settings.js +0 -18
  202. package/dist/src/components/settings/settings.d.ts +0 -29
  203. package/dist/src/components/settings/settings.js +0 -39
  204. package/dist/src/components/user/switch-account-item.d.ts +0 -16
  205. package/dist/src/components/user/switch-account-item.js +0 -14
  206. package/dist/src/components/user/switch-account-menu.d.ts +0 -10
  207. package/dist/src/components/user/switch-account-menu.js +0 -23
  208. package/dist/src/components/user/user-avatar.d.ts +0 -24
  209. package/dist/src/components/user/user-avatar.js +0 -31
  210. package/dist/src/components/user/user-button.d.ts +0 -21
  211. package/dist/src/components/user/user-button.js +0 -24
  212. package/dist/src/components/user/user-view.d.ts +0 -21
  213. package/dist/src/components/user/user-view.js +0 -24
  214. package/dist/src/core.d.ts +0 -1
  215. package/dist/src/core.js +0 -1
  216. package/dist/src/index.d.ts +0 -31
  217. package/dist/src/index.js +0 -32
  218. package/dist/src/lib/utils.d.ts +0 -2
  219. package/dist/src/lib/utils.js +0 -5
  220. package/dist/src/react-exports.d.ts +0 -1
  221. package/dist/src/react-exports.js +0 -1
@@ -1,32 +1,51 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useRevokeMultiSession, useSetActiveSession, useUser } from "@better-auth-ui/react";
3
- import { ArrowRightArrowLeft, ArrowRightFromSquare, Ellipsis } from "@gravity-ui/icons";
4
- import { Button, Dropdown, Spinner, toast } from "@heroui/react";
5
- import { UserView } from "../../user/user-view";
6
- /**
7
- * Render a single account row with user info and a dropdown for switch/sign-out actions.
8
- *
9
- * Shows the user's avatar and info. A three-dot menu provides options to
10
- * switch account (for non-active sessions) and sign out.
11
- *
12
- * @param deviceSession - The device session object containing session and user data
13
- * @returns A JSX element containing the account row
14
- */
15
- export function ManageAccount({ deviceSession, isPending }) {
16
- const { localization } = useAuth();
17
- const { data: user } = useUser();
18
- const { mutate: setActiveSession, isPending: isSwitching } = useSetActiveSession({
19
- onError: (error) => toast.danger(error.error?.message || error.message)
20
- });
21
- const { mutate: revokeSession, isPending: isRevoking } = useRevokeMultiSession({
22
- onError: (error) => toast.danger(error.error?.message || error.message),
23
- onSuccess: () => toast.success(localization.settings.revokeSessionSuccess)
24
- });
25
- const isActive = deviceSession?.session.userId === user?.id;
26
- const isBusy = isSwitching || isRevoking;
27
- return (_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx(UserView, { user: deviceSession?.user, isPending: isPending, size: "md" }), deviceSession && isActive && (_jsxs(Button, { className: "shrink-0", variant: "outline", size: "sm", onPress: () => revokeSession({ sessionToken: deviceSession.session.token }), isDisabled: isBusy, children: [isRevoking ? (_jsx(Spinner, { color: "current", size: "sm" })) : (_jsx(ArrowRightFromSquare, {})), localization.auth.signOut] })), deviceSession && !isActive && (_jsxs(Dropdown, { children: [_jsx(Button, { isIconOnly: true, variant: "ghost", className: "shrink-0", size: "sm", isDisabled: isBusy, children: _jsx(Ellipsis, {}) }), _jsx(Dropdown.Popover, { children: _jsxs(Dropdown.Menu, { children: [_jsxs(Dropdown.Item, { textValue: localization.auth.switchAccount, onAction: () => setActiveSession({
28
- sessionToken: deviceSession.session.token
29
- }), children: [_jsx(ArrowRightArrowLeft, { className: "text-muted" }), localization.auth.switchAccount] }), _jsxs(Dropdown.Item, { textValue: localization.auth.signOut, onAction: () => revokeSession({
30
- sessionToken: deviceSession.session.token
31
- }), children: [_jsx(ArrowRightFromSquare, { className: "text-muted" }), localization.auth.signOut] })] }) })] }))] }));
1
+ import { UserView as e } from "../../user/user-view.js";
2
+ import { useAuth as t, useRevokeMultiSession as n, useSetActiveSession as r, useUser as i } from "@better-auth-ui/react";
3
+ import { Button as a, Dropdown as o, Spinner as s, toast as c } from "@heroui/react";
4
+ import { jsx as l, jsxs as u } from "react/jsx-runtime";
5
+ import { ArrowRightArrowLeft as d, ArrowRightFromSquare as f, Ellipsis as p } from "@gravity-ui/icons";
6
+ //#region src/components/settings/account/manage-account.tsx
7
+ function m({ deviceSession: m, isPending: h }) {
8
+ let { localization: g } = t(), { data: _ } = i(), { mutate: v, isPending: y } = r({ onError: (e) => c.danger(e.error?.message || e.message) }), { mutate: b, isPending: x } = n({
9
+ onError: (e) => c.danger(e.error?.message || e.message),
10
+ onSuccess: () => c.success(g.settings.revokeSessionSuccess)
11
+ }), S = m?.session.userId === _?.id, C = y || x;
12
+ return /* @__PURE__ */ u("div", {
13
+ className: "flex items-center justify-between gap-3",
14
+ children: [
15
+ /* @__PURE__ */ l(e, {
16
+ user: m?.user,
17
+ isPending: h,
18
+ size: "md"
19
+ }),
20
+ m && S && /* @__PURE__ */ u(a, {
21
+ className: "shrink-0",
22
+ variant: "outline",
23
+ size: "sm",
24
+ onPress: () => b({ sessionToken: m.session.token }),
25
+ isDisabled: C,
26
+ children: [x ? /* @__PURE__ */ l(s, {
27
+ color: "current",
28
+ size: "sm"
29
+ }) : /* @__PURE__ */ l(f, {}), g.auth.signOut]
30
+ }),
31
+ m && !S && /* @__PURE__ */ u(o, { children: [/* @__PURE__ */ l(a, {
32
+ isIconOnly: !0,
33
+ variant: "ghost",
34
+ className: "shrink-0",
35
+ size: "sm",
36
+ isDisabled: C,
37
+ children: /* @__PURE__ */ l(p, {})
38
+ }), /* @__PURE__ */ l(o.Popover, { children: /* @__PURE__ */ u(o.Menu, { children: [/* @__PURE__ */ u(o.Item, {
39
+ textValue: g.auth.switchAccount,
40
+ onAction: () => v({ sessionToken: m.session.token }),
41
+ children: [/* @__PURE__ */ l(d, { className: "text-muted" }), g.auth.switchAccount]
42
+ }), /* @__PURE__ */ u(o.Item, {
43
+ textValue: g.auth.signOut,
44
+ onAction: () => b({ sessionToken: m.session.token }),
45
+ children: [/* @__PURE__ */ l(f, { className: "text-muted" }), g.auth.signOut]
46
+ })] }) })] })
47
+ ]
48
+ });
32
49
  }
50
+ //#endregion
51
+ export { m as ManageAccount };
@@ -1,4 +1,4 @@
1
- import { type CardProps } from "@heroui/react";
1
+ import { CardProps } from '@heroui/react';
2
2
  export type ManageAccountsProps = {
3
3
  className?: string;
4
4
  variant?: CardProps["variant"];
@@ -1,37 +1,33 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useListDeviceSessions, useSession } from "@better-auth-ui/react";
3
- import { Card, cn, toast } from "@heroui/react";
4
- import { ManageAccount } from "./manage-account";
5
- /**
6
- * Render a card that lists and manages all device sessions for the current user.
7
- *
8
- * Shows each session with user information and actions to switch to or revoke a session.
9
- * When device session data is loading, a pending placeholder row is displayed.
10
- *
11
- * @returns A JSX element containing the accounts management card
12
- */
13
- export function ManageAccounts({ className, variant, ...props }) {
14
- const { localization } = useAuth();
15
- const { data: session } = useSession();
16
- const { data: deviceSessions, isPending } = useListDeviceSessions({
17
- throwOnError: (error) => {
18
- if (error.error)
19
- toast.danger(error.error.message);
20
- return false;
21
- }
22
- });
23
- const otherSessions = deviceSessions?.filter((deviceSession) => deviceSession.session.id !== session?.session.id);
24
- const allRows = [
25
- {
26
- key: "current",
27
- deviceSession: !isPending ? session : null,
28
- isPending
29
- },
30
- ...(otherSessions?.map((deviceSession) => ({
31
- key: deviceSession.session.id,
32
- deviceSession,
33
- isPending: false
34
- })) ?? [])
35
- ];
36
- return (_jsxs("div", { children: [_jsx("h2", { className: cn("text-sm font-semibold mb-3"), children: localization.settings.manageAccounts }), _jsx(Card, { className: cn(className), variant: variant, ...props, children: _jsx(Card.Content, { className: "gap-0", children: allRows.map((row, index) => (_jsxs("div", { children: [index > 0 && (_jsx("div", { className: "border-b border-dashed -mx-4 md:-mx-6 my-4" })), _jsx(ManageAccount, { deviceSession: row.deviceSession, isPending: row.isPending })] }, row.key))) }) })] }));
1
+ import { ManageAccount as e } from "./manage-account.js";
2
+ import { useAuth as t, useListDeviceSessions as n, useSession as r } from "@better-auth-ui/react";
3
+ import { Card as i, cn as a, toast as o } from "@heroui/react";
4
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
5
+ //#region src/components/settings/account/manage-accounts.tsx
6
+ function l({ className: l, variant: u, ...d }) {
7
+ let { localization: f } = t(), { data: p } = r(), { data: m, isPending: h } = n({ throwOnError: (e) => (e.error && o.danger(e.error.message), !1) }), g = m?.filter((e) => e.session.id !== p?.session.id), _ = [{
8
+ key: "current",
9
+ deviceSession: h ? null : p,
10
+ isPending: h
11
+ }, ...g?.map((e) => ({
12
+ key: e.session.id,
13
+ deviceSession: e,
14
+ isPending: !1
15
+ })) ?? []];
16
+ return /* @__PURE__ */ c("div", { children: [/* @__PURE__ */ s("h2", {
17
+ className: a("text-sm font-semibold mb-3"),
18
+ children: f.settings.manageAccounts
19
+ }), /* @__PURE__ */ s(i, {
20
+ className: a(l),
21
+ variant: u,
22
+ ...d,
23
+ children: /* @__PURE__ */ s(i.Content, {
24
+ className: "gap-0",
25
+ children: _.map((t, n) => /* @__PURE__ */ c("div", { children: [n > 0 && /* @__PURE__ */ s("div", { className: "border-b border-dashed -mx-4 md:-mx-6 my-4" }), /* @__PURE__ */ s(e, {
26
+ deviceSession: t.deviceSession,
27
+ isPending: t.isPending
28
+ })] }, t.key))
29
+ })
30
+ })] });
37
31
  }
32
+ //#endregion
33
+ export { l as ManageAccounts };
@@ -1,11 +1,11 @@
1
- import { type CardProps } from "@heroui/react";
1
+ import { CardProps } from '@heroui/react';
2
2
  export type UserProfileProps = {
3
3
  className?: string;
4
4
  variant?: CardProps["variant"];
5
5
  };
6
6
  /**
7
- * Render a profile card that lets the authenticated user view and update their display name and avatar.
7
+ * Render a profile card that lets the authenticated user view and update their display name, username, and avatar.
8
8
  *
9
- * @returns A JSX element containing the user profile card with avatar upload and an editable name form
9
+ * @returns A JSX element containing the user profile card with avatar upload and editable form fields
10
10
  */
11
11
  export declare function UserProfile({ className, variant, ...props }: UserProfileProps & CardProps): import("react/jsx-runtime").JSX.Element;
@@ -1,23 +1,106 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useSession, useUpdateUser } from "@better-auth-ui/react";
3
- import { Button, Card, cn, FieldError, Fieldset, Form, Input, Label, Skeleton, Spinner, TextField, toast } from "@heroui/react";
4
- import { ChangeAvatar } from "./change-avatar";
5
- /**
6
- * Render a profile card that lets the authenticated user view and update their display name and avatar.
7
- *
8
- * @returns A JSX element containing the user profile card with avatar upload and an editable name form
9
- */
10
- export function UserProfile({ className, variant, ...props }) {
11
- const { localization } = useAuth();
12
- const { data: session } = useSession();
13
- const { mutate: updateUser, isPending } = useUpdateUser({
14
- onError: (error) => toast.danger(error.error?.message || error.message),
15
- onSuccess: () => toast.success(localization.settings.profileUpdatedSuccess)
16
- });
17
- function handleSubmit(e) {
18
- e.preventDefault();
19
- const formData = new FormData(e.currentTarget);
20
- updateUser({ name: formData.get("name") });
21
- }
22
- return (_jsxs("div", { children: [_jsx("h2", { className: cn("text-sm font-semibold mb-3"), children: localization.settings.profile }), _jsx(Card, { className: cn("p-4 gap-4", className), variant: variant, ...props, children: _jsx(Card.Content, { children: _jsx(Form, { onSubmit: handleSubmit, children: _jsxs(Fieldset, { className: "w-full gap-4", children: [_jsx(ChangeAvatar, {}), _jsx(Fieldset.Group, { children: _jsxs(TextField, { name: "name", defaultValue: session?.user.name, isDisabled: isPending || !session, children: [_jsx(Label, { children: localization.auth.name }), session ? (_jsx(Input, { autoComplete: "name", placeholder: localization.auth.name, variant: variant === "transparent" ? "primary" : "secondary" })) : (_jsx(Skeleton, { className: "h-10 md:h-9 w-full rounded-xl" })), _jsx(FieldError, {})] }, session?.user?.name) }), _jsx(Fieldset.Actions, { children: _jsxs(Button, { type: "submit", isPending: isPending, isDisabled: !session, size: "sm", children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.settings.saveChanges] }) })] }) }) }) })] }));
1
+ import { ChangeAvatar as e } from "./change-avatar.js";
2
+ import { useAuth as t, useIsUsernameAvailable as n, useSession as r, useUpdateUser as i } from "@better-auth-ui/react";
3
+ import { Button as a, Card as o, FieldError as s, Fieldset as c, Form as l, Input as u, InputGroup as d, Label as f, Skeleton as p, Spinner as m, TextField as h, cn as g, toast as _ } from "@heroui/react";
4
+ import { jsx as v, jsxs as y } from "react/jsx-runtime";
5
+ import { useEffect as b, useState as x } from "react";
6
+ import { Check as S, Xmark as C } from "@gravity-ui/icons";
7
+ import { useDebouncer as w } from "@tanstack/react-pacer";
8
+ //#region src/components/settings/account/user-profile.tsx
9
+ function T({ className: T, variant: E, ...D }) {
10
+ let { localization: O, username: k } = t(), { data: A } = r(), j = (k?.displayUsername ? A?.user?.displayUsername : A?.user?.username) || "", [M, N] = x(j);
11
+ b(() => {
12
+ N(j);
13
+ }, [j]);
14
+ let { mutate: P, data: F, error: I, reset: L } = n(), R = w((e) => {
15
+ if (!e.trim() || e.trim() === j) {
16
+ L();
17
+ return;
18
+ }
19
+ P({ username: e.trim() });
20
+ }, { wait: 500 });
21
+ function z(e) {
22
+ N(e), L(), k?.isUsernameAvailable && R.maybeExecute(e);
23
+ }
24
+ let { mutate: B, isPending: V } = i({
25
+ onError: (e) => _.danger(e.error?.message || e.message),
26
+ onSuccess: () => _.success(O.settings.profileUpdatedSuccess)
27
+ });
28
+ function H(e) {
29
+ e.preventDefault(), B({
30
+ name: new FormData(e.currentTarget).get("name"),
31
+ ...k?.enabled ? {
32
+ username: M.trim(),
33
+ ...k.displayUsername ? { displayUsername: M.trim() } : {}
34
+ } : {}
35
+ });
36
+ }
37
+ return /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h2", {
38
+ className: g("text-sm font-semibold mb-3"),
39
+ children: O.settings.profile
40
+ }), /* @__PURE__ */ v(o, {
41
+ className: g("p-4 gap-4", T),
42
+ variant: E,
43
+ ...D,
44
+ children: /* @__PURE__ */ v(o.Content, { children: /* @__PURE__ */ v(l, {
45
+ onSubmit: H,
46
+ children: /* @__PURE__ */ y(c, {
47
+ className: "w-full gap-4",
48
+ children: [
49
+ /* @__PURE__ */ v(e, {}),
50
+ /* @__PURE__ */ y(c.Group, { children: [k?.enabled && /* @__PURE__ */ y(h, {
51
+ type: "text",
52
+ autoComplete: "username",
53
+ minLength: k.minUsernameLength,
54
+ maxLength: k.maxUsernameLength,
55
+ isDisabled: V || !A,
56
+ value: M,
57
+ onChange: z,
58
+ isInvalid: !!I || F && !F.available,
59
+ children: [
60
+ /* @__PURE__ */ v(f, { children: O.auth.username }),
61
+ A ? /* @__PURE__ */ y(d, {
62
+ variant: E === "transparent" ? "primary" : "secondary",
63
+ children: [/* @__PURE__ */ v(d.Input, {
64
+ placeholder: O.auth.usernamePlaceholder,
65
+ name: "username"
66
+ }), k.isUsernameAvailable && M.trim() && M.trim() !== j && /* @__PURE__ */ v(d.Suffix, {
67
+ className: "px-2",
68
+ children: F?.available ? /* @__PURE__ */ v(S, { className: "text-success" }) : I || F?.available === !1 ? /* @__PURE__ */ v(C, { className: "text-danger" }) : /* @__PURE__ */ v(m, {
69
+ size: "sm",
70
+ color: "current"
71
+ })
72
+ })]
73
+ }) : /* @__PURE__ */ v(p, { className: "h-10 md:h-9 w-full rounded-xl" }),
74
+ /* @__PURE__ */ v(s, { children: I?.error?.message || I?.message || F?.available === !1 && O.auth.usernameTaken })
75
+ ]
76
+ }), /* @__PURE__ */ y(h, {
77
+ name: "name",
78
+ defaultValue: A?.user.name,
79
+ isDisabled: V || !A,
80
+ children: [
81
+ /* @__PURE__ */ v(f, { children: O.auth.name }),
82
+ A ? /* @__PURE__ */ v(u, {
83
+ autoComplete: "name",
84
+ placeholder: O.auth.name,
85
+ variant: E === "transparent" ? "primary" : "secondary"
86
+ }) : /* @__PURE__ */ v(p, { className: "h-10 md:h-9 w-full rounded-xl" }),
87
+ /* @__PURE__ */ v(s, {})
88
+ ]
89
+ }, A?.user?.name)] }),
90
+ /* @__PURE__ */ v(c.Actions, { children: /* @__PURE__ */ y(a, {
91
+ type: "submit",
92
+ isPending: V,
93
+ isDisabled: !A,
94
+ size: "sm",
95
+ children: [V && /* @__PURE__ */ v(m, {
96
+ color: "current",
97
+ size: "sm"
98
+ }), O.settings.saveChanges]
99
+ }) })
100
+ ]
101
+ })
102
+ }) })
103
+ })] });
23
104
  }
105
+ //#endregion
106
+ export { T as UserProfile };
@@ -1,4 +1,4 @@
1
- import type { Session } from "better-auth";
1
+ import { Session } from 'better-auth';
2
2
  export type ActiveSessionProps = {
3
3
  activeSession: Session;
4
4
  };
@@ -1,53 +1,62 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useRevokeSession, useSession } from "@better-auth-ui/react";
3
- import { ArrowRightFromSquare, Display, Smartphone, Xmark } from "@gravity-ui/icons";
4
- import { Button, Chip, Spinner, toast } from "@heroui/react";
5
- import Bowser from "bowser";
6
- function timeAgo(date) {
7
- const seconds = Math.floor((Date.now() - date.getTime()) / 1000);
8
- const rtf = new Intl.RelativeTimeFormat(undefined, { numeric: "auto" });
9
- const UNITS = [
10
- ["year", 31536000],
11
- ["month", 2592000],
12
- ["week", 604800],
13
- ["day", 86400],
14
- ["hour", 3600],
15
- ["minute", 60],
16
- ["second", 1]
17
- ];
18
- for (const [unit, threshold] of UNITS) {
19
- if (seconds >= threshold) {
20
- return rtf.format(-Math.floor(seconds / threshold), unit);
21
- }
22
- }
23
- return rtf.format(0, "second");
1
+ import { useAuth as e, useRevokeSession as t, useSession as n } from "@better-auth-ui/react";
2
+ import { Button as r, Chip as i, Spinner as a, toast as o } from "@heroui/react";
3
+ import { jsx as s, jsxs as c } from "react/jsx-runtime";
4
+ import { ArrowRightFromSquare as l, Display as u, Smartphone as d, Xmark as f } from "@gravity-ui/icons";
5
+ import p from "bowser";
6
+ //#region src/components/settings/security/active-session.tsx
7
+ function m(e) {
8
+ let t = Math.floor((Date.now() - e.getTime()) / 1e3), n = new Intl.RelativeTimeFormat(void 0, { numeric: "auto" });
9
+ for (let [e, r] of [
10
+ ["year", 31536e3],
11
+ ["month", 2592e3],
12
+ ["week", 604800],
13
+ ["day", 86400],
14
+ ["hour", 3600],
15
+ ["minute", 60],
16
+ ["second", 1]
17
+ ]) if (t >= r) return n.format(-Math.floor(t / r), e);
18
+ return n.format(0, "second");
24
19
  }
25
- /**
26
- * Render a single active session row with device info and revoke control.
27
- *
28
- * Shows the session's browser, OS, IP address, and creation time. The current session is marked
29
- * and navigates to sign-out on click, while other sessions can be revoked individually.
30
- *
31
- * @param session - The session object containing id, token, userAgent, ipAddress, and createdAt
32
- * @returns A JSX element containing the active session row
33
- */
34
- export function ActiveSession({ activeSession }) {
35
- const { basePaths, localization, viewPaths, navigate } = useAuth();
36
- const { data: session } = useSession({ refetchOnMount: false });
37
- const { mutate: revokeSession, isPending: isRevoking } = useRevokeSession({
38
- onError: (error) => toast.danger(error.error?.message || error.message),
39
- onSuccess: () => toast.success(localization.settings.revokeSessionSuccess)
40
- });
41
- const isCurrentSession = activeSession.token === session?.session.token;
42
- const ua = Bowser.parse(activeSession.userAgent || "");
43
- const isMobile = ua.platform.type === "mobile" || ua.platform.type === "tablet";
44
- return (_jsxs("div", { className: "flex items-center gap-3", children: [_jsx("div", { className: "flex size-10 shrink-0 items-center justify-center rounded-xl bg-surface-secondary", children: isMobile ? (_jsx(Smartphone, { className: "size-4.5" })) : (_jsx(Display, { className: "size-4.5" })) }), _jsxs("div", { className: "flex flex-col min-w-0", children: [_jsxs("span", { className: "text-sm font-medium truncate", children: [ua.browser.name || "Unknown Browser", ua.os.name ? `, ${ua.os.name}` : ""] }), isCurrentSession ? (_jsx(Chip, { color: "accent", size: "sm", children: localization.settings.currentSession })) : (activeSession.createdAt && (_jsx("span", { className: "text-xs text-muted capitalize", children: timeAgo(activeSession.createdAt) })))] }), _jsxs(Button, { className: "ml-auto shrink-0", variant: "outline", size: "sm", onPress: () => isCurrentSession
45
- ? navigate({
46
- to: `${basePaths.auth}/${viewPaths.auth.signOut}`
47
- })
48
- : revokeSession(activeSession), isPending: isRevoking, "aria-label": isCurrentSession
49
- ? localization.auth.signOut
50
- : localization.settings.revokeSession, children: [isRevoking ? (_jsx(Spinner, { color: "current", size: "sm" })) : isCurrentSession ? (_jsx(ArrowRightFromSquare, {})) : (_jsx(Xmark, {})), isCurrentSession
51
- ? localization.auth.signOut
52
- : localization.settings.revoke] })] }));
20
+ function h({ activeSession: h }) {
21
+ let { basePaths: g, localization: _, viewPaths: v, navigate: y } = e(), { data: b } = n({ refetchOnMount: !1 }), { mutate: x, isPending: S } = t({
22
+ onError: (e) => o.danger(e.error?.message || e.message),
23
+ onSuccess: () => o.success(_.settings.revokeSessionSuccess)
24
+ }), C = h.token === b?.session.token, w = p.parse(h.userAgent || "");
25
+ return /* @__PURE__ */ c("div", {
26
+ className: "flex items-center gap-3",
27
+ children: [
28
+ /* @__PURE__ */ s("div", {
29
+ className: "flex size-10 shrink-0 items-center justify-center rounded-xl bg-surface-secondary",
30
+ children: w.platform.type === "mobile" || w.platform.type === "tablet" ? /* @__PURE__ */ s(d, { className: "size-4.5" }) : /* @__PURE__ */ s(u, { className: "size-4.5" })
31
+ }),
32
+ /* @__PURE__ */ c("div", {
33
+ className: "flex flex-col min-w-0",
34
+ children: [/* @__PURE__ */ c("span", {
35
+ className: "text-sm font-medium truncate",
36
+ children: [w.browser.name || "Unknown Browser", w.os.name ? `, ${w.os.name}` : ""]
37
+ }), C ? /* @__PURE__ */ s(i, {
38
+ color: "accent",
39
+ size: "sm",
40
+ children: _.settings.currentSession
41
+ }) : h.createdAt && /* @__PURE__ */ s("span", {
42
+ className: "text-xs text-muted capitalize",
43
+ children: m(h.createdAt)
44
+ })]
45
+ }),
46
+ /* @__PURE__ */ c(r, {
47
+ className: "ml-auto shrink-0",
48
+ variant: "outline",
49
+ size: "sm",
50
+ onPress: () => C ? y({ to: `${g.auth}/${v.auth.signOut}` }) : x(h),
51
+ isPending: S,
52
+ "aria-label": C ? _.auth.signOut : _.settings.revokeSession,
53
+ children: [S ? /* @__PURE__ */ s(a, {
54
+ color: "current",
55
+ size: "sm"
56
+ }) : s(C ? l : f, {}), C ? _.auth.signOut : _.settings.revoke]
57
+ })
58
+ ]
59
+ });
53
60
  }
61
+ //#endregion
62
+ export { h as ActiveSession };
@@ -1,4 +1,4 @@
1
- import { type CardProps } from "@heroui/react";
1
+ import { CardProps } from '@heroui/react';
2
2
  export type ActiveSessionsProps = {
3
3
  className?: string;
4
4
  variant?: CardProps["variant"];
@@ -1,28 +1,34 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { useAuth, useListSessions, useSession } from "@better-auth-ui/react";
3
- import { Card, cn, Skeleton, toast } from "@heroui/react";
4
- import { ActiveSession } from "./active-session";
5
- /**
6
- * Render a card listing all active sessions for the current user with revoke controls.
7
- *
8
- * Shows each session's browser, OS, IP address, and creation time. The current session is marked
9
- * and navigates to sign-out on click, while other sessions can be revoked individually.
10
- *
11
- * @returns A JSX element containing the sessions card
12
- */
13
- export function ActiveSessions({ className, variant, ...props }) {
14
- const { localization } = useAuth();
15
- const { data: session } = useSession();
16
- const { data: sessions, isPending } = useListSessions({
17
- throwOnError: (error) => {
18
- if (error.error)
19
- toast.danger(error.error.message);
20
- return false;
21
- }
22
- });
23
- const activeSessions = sessions?.toSorted((activeSession) => activeSession.id === session?.session.id ? -1 : 1);
24
- return (_jsxs("div", { children: [_jsx("h2", { className: cn("text-sm font-semibold mb-3"), children: localization.settings.activeSessions }), _jsx(Card, { className: cn(className), variant: variant, ...props, children: _jsx(Card.Content, { className: "gap-0", children: isPending ? (_jsx(SessionRowSkeleton, {})) : (activeSessions?.map((activeSession, index) => (_jsxs("div", { children: [index > 0 && (_jsx("div", { className: "border-b border-dashed -mx-4 md:-mx-6 my-4" })), _jsx(ActiveSession, { activeSession: activeSession })] }, activeSession.id)))) }) })] }));
1
+ import { ActiveSession as e } from "./active-session.js";
2
+ import { useAuth as t, useListSessions as n, useSession as r } from "@better-auth-ui/react";
3
+ import { Card as i, Skeleton as a, cn as o, toast as s } from "@heroui/react";
4
+ import { jsx as c, jsxs as l } from "react/jsx-runtime";
5
+ //#region src/components/settings/security/active-sessions.tsx
6
+ function u({ className: a, variant: u, ...f }) {
7
+ let { localization: p } = t(), { data: m } = r(), { data: h, isPending: g } = n({ throwOnError: (e) => (e.error && s.danger(e.error.message), !1) }), _ = h?.toSorted((e) => e.id === m?.session.id ? -1 : 1);
8
+ return /* @__PURE__ */ l("div", { children: [/* @__PURE__ */ c("h2", {
9
+ className: o("text-sm font-semibold mb-3"),
10
+ children: p.settings.activeSessions
11
+ }), /* @__PURE__ */ c(i, {
12
+ className: o(a),
13
+ variant: u,
14
+ ...f,
15
+ children: /* @__PURE__ */ c(i.Content, {
16
+ className: "gap-0",
17
+ children: g ? /* @__PURE__ */ c(d, {}) : _?.map((t, n) => /* @__PURE__ */ l("div", { children: [n > 0 && /* @__PURE__ */ c("div", { className: "border-b border-dashed -mx-4 md:-mx-6 my-4" }), /* @__PURE__ */ c(e, { activeSession: t })] }, t.id))
18
+ })
19
+ })] });
25
20
  }
26
- function SessionRowSkeleton() {
27
- return (_jsx("div", { className: "flex items-center justify-between", children: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Skeleton, { className: "size-10 rounded-xl" }), _jsxs("div", { className: "flex flex-col gap-1", children: [_jsx(Skeleton, { className: "h-4 w-32 rounded-lg" }), _jsx(Skeleton, { className: "h-3 w-24 rounded-lg" })] })] }) }));
21
+ function d() {
22
+ return /* @__PURE__ */ c("div", {
23
+ className: "flex items-center justify-between",
24
+ children: /* @__PURE__ */ l("div", {
25
+ className: "flex items-center gap-3",
26
+ children: [/* @__PURE__ */ c(a, { className: "size-10 rounded-xl" }), /* @__PURE__ */ l("div", {
27
+ className: "flex flex-col gap-1",
28
+ children: [/* @__PURE__ */ c(a, { className: "h-4 w-32 rounded-lg" }), /* @__PURE__ */ c(a, { className: "h-3 w-24 rounded-lg" })]
29
+ })]
30
+ })
31
+ });
28
32
  }
33
+ //#endregion
34
+ export { u as ActiveSessions };
@@ -1,4 +1,4 @@
1
- import { type CardProps } from "@heroui/react";
1
+ import { CardProps } from '@heroui/react';
2
2
  export type ChangePasswordProps = {
3
3
  className?: string;
4
4
  variant?: CardProps["variant"];