@better-auth-ui/heroui 1.6.1 → 1.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/auth/auth-provider.d.ts +1 -1
- package/dist/components/auth/auth-provider.js +16 -11
- package/dist/components/auth/auth.d.ts +4 -4
- package/dist/components/auth/auth.js +36 -41
- package/dist/components/auth/error-toaster.d.ts +1 -0
- package/dist/components/auth/error-toaster.js +17 -0
- package/dist/components/auth/field-separator.d.ts +1 -1
- package/dist/components/auth/field-separator.js +17 -4
- package/dist/components/auth/forgot-password.d.ts +2 -2
- package/dist/components/auth/forgot-password.js +66 -27
- package/dist/components/auth/magic-link-button.d.ts +1 -1
- package/dist/components/auth/magic-link-button.js +15 -18
- package/dist/components/auth/magic-link.d.ts +3 -3
- package/dist/components/auth/magic-link.js +98 -43
- package/dist/components/auth/passkey-button.js +20 -12
- package/dist/components/auth/provider-button.d.ts +15 -0
- package/dist/components/auth/provider-button.js +29 -0
- package/dist/components/auth/provider-buttons.d.ts +4 -10
- package/dist/components/auth/provider-buttons.js +19 -33
- package/dist/components/auth/reset-password.d.ts +2 -2
- package/dist/components/auth/reset-password.js +143 -57
- package/dist/components/auth/sign-in.d.ts +3 -3
- package/dist/components/auth/sign-in.js +151 -64
- package/dist/components/auth/sign-out.js +26 -32
- package/dist/components/auth/sign-up.d.ts +3 -3
- package/dist/components/auth/sign-up.js +231 -70
- package/dist/components/email/email-changed-email.d.ts +2 -2
- package/dist/components/email/email-changed-email.js +29 -22
- package/dist/components/email/email-verification-email.d.ts +2 -2
- package/dist/components/email/email-verification-email.js +29 -22
- package/dist/components/email/magic-link-email.d.ts +2 -2
- package/dist/components/email/magic-link-email.js +29 -22
- package/dist/components/email/new-device-email.d.ts +2 -2
- package/dist/components/email/new-device-email.js +29 -22
- package/dist/components/email/otp-email.d.ts +2 -2
- package/dist/components/email/otp-email.js +28 -21
- package/dist/components/email/password-changed-email.d.ts +2 -2
- package/dist/components/email/password-changed-email.js +29 -22
- package/dist/components/email/reset-password-email.d.ts +2 -2
- package/dist/components/email/reset-password-email.js +29 -22
- package/dist/components/settings/account/account-settings.d.ts +2 -2
- package/dist/components/settings/account/account-settings.js +22 -19
- package/dist/components/settings/account/appearance.d.ts +2 -2
- package/dist/components/settings/account/appearance.js +70 -27
- package/dist/components/settings/account/change-avatar.js +88 -55
- package/dist/components/settings/account/change-email.d.ts +2 -2
- package/dist/components/settings/account/change-email.js +53 -28
- package/dist/components/settings/account/manage-account.d.ts +1 -1
- package/dist/components/settings/account/manage-account.js +47 -31
- package/dist/components/settings/account/manage-accounts.d.ts +2 -2
- package/dist/components/settings/account/manage-accounts.js +32 -36
- package/dist/components/settings/account/user-profile.d.ts +4 -4
- package/dist/components/settings/account/user-profile.js +102 -22
- package/dist/components/settings/security/active-session.d.ts +1 -1
- package/dist/components/settings/security/active-session.js +57 -51
- package/dist/components/settings/security/active-sessions.d.ts +2 -2
- package/dist/components/settings/security/active-sessions.js +32 -26
- package/dist/components/settings/security/change-password.d.ts +2 -2
- package/dist/components/settings/security/change-password.js +186 -76
- package/dist/components/settings/security/danger-zone.d.ts +2 -2
- package/dist/components/settings/security/danger-zone.js +17 -11
- package/dist/components/settings/security/delete-user.d.ts +2 -2
- package/dist/components/settings/security/delete-user.js +91 -46
- package/dist/components/settings/security/linked-account.d.ts +1 -1
- package/dist/components/settings/security/linked-account.js +55 -47
- package/dist/components/settings/security/linked-accounts.d.ts +2 -2
- package/dist/components/settings/security/linked-accounts.js +43 -40
- package/dist/components/settings/security/passkey.js +42 -13
- package/dist/components/settings/security/passkeys.d.ts +2 -2
- package/dist/components/settings/security/passkeys.js +51 -19
- package/dist/components/settings/security/security-settings.d.ts +2 -2
- package/dist/components/settings/security/security-settings.js +24 -21
- package/dist/components/settings/settings.d.ts +3 -3
- package/dist/components/settings/settings.js +44 -27
- package/dist/components/user/switch-account-item.d.ts +1 -1
- package/dist/components/user/switch-account-item.js +19 -15
- package/dist/components/user/switch-account-menu.js +27 -28
- package/dist/components/user/user-avatar.d.ts +3 -3
- package/dist/components/user/user-avatar.js +28 -30
- package/dist/components/user/user-button.d.ts +1 -1
- package/dist/components/user/user-button.js +90 -23
- package/dist/components/user/user-view.d.ts +3 -3
- package/dist/components/user/user-view.js +36 -23
- package/dist/core.d.ts +1 -1
- package/dist/index.d.ts +36 -35
- package/dist/index.js +37 -35
- package/dist/react-exports.d.ts +1 -1
- package/package.json +15 -11
- package/src/components/auth/auth-provider.tsx +4 -0
- package/src/components/auth/auth.tsx +2 -2
- package/src/components/auth/error-toaster.tsx +25 -0
- package/src/components/auth/forgot-password.tsx +1 -2
- package/src/components/auth/magic-link.tsx +3 -23
- package/src/components/auth/passkey-button.tsx +1 -2
- package/src/components/auth/provider-button.tsx +67 -0
- package/src/components/auth/provider-buttons.tsx +26 -43
- package/src/components/auth/reset-password.tsx +1 -2
- package/src/components/auth/sign-in.tsx +63 -48
- package/src/components/auth/sign-up.tsx +99 -20
- package/src/components/settings/account/appearance.tsx +1 -1
- package/src/components/settings/account/change-avatar.tsx +1 -3
- package/src/components/settings/account/change-email.tsx +2 -3
- package/src/components/settings/account/manage-account.tsx +1 -4
- package/src/components/settings/account/manage-accounts.tsx +3 -8
- package/src/components/settings/account/user-profile.tsx +122 -8
- package/src/components/settings/security/active-session.tsx +0 -1
- package/src/components/settings/security/active-sessions.tsx +3 -8
- package/src/components/settings/security/change-password.tsx +7 -4
- package/src/components/settings/security/delete-user.tsx +1 -4
- package/src/components/settings/security/linked-account.tsx +4 -14
- package/src/components/settings/security/linked-accounts.tsx +3 -8
- package/src/components/settings/security/passkey.tsx +2 -4
- package/src/components/settings/security/passkeys.tsx +4 -12
- package/src/components/settings/settings.tsx +1 -1
- package/src/components/user/switch-account-item.tsx +2 -4
- package/src/components/user/switch-account-menu.tsx +2 -7
- package/src/index.tsx +1 -0
|
@@ -1,34 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import { useMemo } from "react";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
if (socialLayout === "auto") {
|
|
19
|
-
if (socialProviders?.length && socialProviders.length >= 4) {
|
|
20
|
-
return "horizontal";
|
|
21
|
-
}
|
|
22
|
-
return "vertical";
|
|
23
|
-
}
|
|
24
|
-
return socialLayout;
|
|
25
|
-
}, [socialLayout, socialProviders?.length]);
|
|
26
|
-
return (_jsx("div", { className: cn("gap-3", resolvedSocialLayout === "grid" && "grid grid-cols-2", resolvedSocialLayout === "vertical" && "flex flex-col", resolvedSocialLayout === "horizontal" && "flex flex-wrap"), children: socialProviders?.map((provider) => {
|
|
27
|
-
const ProviderIcon = providerIcons[provider];
|
|
28
|
-
return (_jsxs(Button, { className: cn("w-full", resolvedSocialLayout === "horizontal" && "flex-1"), variant: "tertiary", isPending: isPending, onPress: () => signInSocial({ provider, callbackURL }), children: [_jsx(ProviderIcon, {}), resolvedSocialLayout === "vertical"
|
|
29
|
-
? localization.auth.continueWith.replace("{{provider}}", getProviderName(provider))
|
|
30
|
-
: resolvedSocialLayout === "grid"
|
|
31
|
-
? getProviderName(provider)
|
|
32
|
-
: null] }, provider));
|
|
33
|
-
}) }));
|
|
1
|
+
import { ProviderButton as e } from "./provider-button.js";
|
|
2
|
+
import { useAuth as t } from "@better-auth-ui/react";
|
|
3
|
+
import { cn as n } from "@heroui/react";
|
|
4
|
+
import { jsx as r } from "react/jsx-runtime";
|
|
5
|
+
import { useMemo as i } from "react";
|
|
6
|
+
//#region src/components/auth/provider-buttons.tsx
|
|
7
|
+
function a({ isPending: a, socialLayout: o = "auto" }) {
|
|
8
|
+
let { socialProviders: s } = t(), c = i(() => o === "auto" ? s?.length && s.length >= 4 ? "horizontal" : "vertical" : o, [o, s?.length]);
|
|
9
|
+
return /* @__PURE__ */ r("div", {
|
|
10
|
+
className: n("gap-3", c === "grid" && "grid grid-cols-2", c === "vertical" && "flex flex-col", c === "horizontal" && "flex flex-wrap"),
|
|
11
|
+
children: s?.map((t) => /* @__PURE__ */ r(e, {
|
|
12
|
+
provider: t,
|
|
13
|
+
isDisabled: a,
|
|
14
|
+
label: c === "vertical" ? "continueWith" : c === "grid" ? "providerName" : "none",
|
|
15
|
+
className: n("w-full", c === "horizontal" && "flex-1")
|
|
16
|
+
}, t))
|
|
17
|
+
});
|
|
34
18
|
}
|
|
19
|
+
//#endregion
|
|
20
|
+
export { a as ProviderButtons };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CardProps } from '@heroui/react';
|
|
2
2
|
export type ResetPasswordProps = {
|
|
3
3
|
className?: string;
|
|
4
4
|
variant?: CardProps["variant"];
|
|
@@ -8,4 +8,4 @@ export type ResetPasswordProps = {
|
|
|
8
8
|
*
|
|
9
9
|
* Renders password (and optional confirm-password) inputs with visibility toggles, applies min/max length constraints from the auth configuration, shows field errors, and submits the new password to the auth client.
|
|
10
10
|
*/
|
|
11
|
-
export declare function ResetPassword({ className, variant, ...props }: ResetPasswordProps & CardProps): import("react/jsx-runtime").JSX.Element;
|
|
11
|
+
export declare function ResetPassword({ className, variant, ...props }: ResetPasswordProps & Omit<CardProps, "children">): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,58 +1,144 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
1
|
+
import { useAuth as e, useResetPassword as t } from "@better-auth-ui/react";
|
|
2
|
+
import { Button as n, Card as r, Description as i, FieldError as a, Form as o, InputGroup as s, Label as c, Link as l, Spinner as u, TextField as d, cn as f, toast as p } from "@heroui/react";
|
|
3
|
+
import { jsx as m, jsxs as h } from "react/jsx-runtime";
|
|
4
|
+
import { useEffect as g, useState as _ } from "react";
|
|
5
|
+
import { Eye as v, EyeSlash as y } from "@gravity-ui/icons";
|
|
6
|
+
//#region src/components/auth/reset-password.tsx
|
|
7
|
+
function b({ className: b, variant: x, ...S }) {
|
|
8
|
+
let { basePaths: C, emailAndPassword: w, localization: T, viewPaths: E, navigate: D } = e(), { mutate: O, isPending: k } = t({ onSuccess: () => {
|
|
9
|
+
p.success(T.auth.passwordResetSuccess), D({ to: `${C.auth}/${E.auth.signIn}` });
|
|
10
|
+
} }), [A, j] = _(!1), [M, N] = _(!1);
|
|
11
|
+
g(() => {
|
|
12
|
+
new URLSearchParams(window.location.search).get("token") || (p.danger(T.auth.invalidResetPasswordToken), D({ to: `${C.auth}/${E.auth.signIn}` }));
|
|
13
|
+
}, [
|
|
14
|
+
C.auth,
|
|
15
|
+
T.auth.invalidResetPasswordToken,
|
|
16
|
+
E.auth.signIn,
|
|
17
|
+
D
|
|
18
|
+
]);
|
|
19
|
+
function P(e) {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
let t = new URLSearchParams(window.location.search).get("token");
|
|
22
|
+
if (!t) {
|
|
23
|
+
p.danger(T.auth.invalidResetPasswordToken), D({ to: `${C.auth}/${E.auth.signIn}` });
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
let n = new FormData(e.currentTarget), r = n.get("password"), i = n.get("confirmPassword");
|
|
27
|
+
if (w?.confirmPassword && r !== i) {
|
|
28
|
+
p.danger(T.auth.passwordsDoNotMatch);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
O({
|
|
32
|
+
token: t,
|
|
33
|
+
newPassword: r
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return /* @__PURE__ */ h(r, {
|
|
37
|
+
className: f("w-full max-w-sm p-4 md:p-6", b),
|
|
38
|
+
variant: x,
|
|
39
|
+
...S,
|
|
40
|
+
children: [
|
|
41
|
+
/* @__PURE__ */ m(r.Header, { children: /* @__PURE__ */ m(r.Title, {
|
|
42
|
+
className: "text-xl font-semibold mb-1",
|
|
43
|
+
children: T.auth.resetPassword
|
|
44
|
+
}) }),
|
|
45
|
+
/* @__PURE__ */ m(r.Content, { children: /* @__PURE__ */ h(o, {
|
|
46
|
+
onSubmit: P,
|
|
47
|
+
className: "flex flex-col gap-4",
|
|
48
|
+
children: [
|
|
49
|
+
/* @__PURE__ */ h(d, {
|
|
50
|
+
minLength: w?.minPasswordLength,
|
|
51
|
+
maxLength: w?.maxPasswordLength,
|
|
52
|
+
name: "password",
|
|
53
|
+
autoComplete: "new-password",
|
|
54
|
+
isDisabled: k,
|
|
55
|
+
children: [
|
|
56
|
+
/* @__PURE__ */ m(c, { children: T.auth.password }),
|
|
57
|
+
/* @__PURE__ */ h(s, {
|
|
58
|
+
variant: x === "transparent" ? "primary" : "secondary",
|
|
59
|
+
children: [/* @__PURE__ */ m(s.Input, {
|
|
60
|
+
name: "password",
|
|
61
|
+
placeholder: T.auth.newPasswordPlaceholder,
|
|
62
|
+
type: A ? "text" : "password",
|
|
63
|
+
required: !0
|
|
64
|
+
}), /* @__PURE__ */ m(s.Suffix, {
|
|
65
|
+
className: "px-0",
|
|
66
|
+
children: /* @__PURE__ */ m(n, {
|
|
67
|
+
isIconOnly: !0,
|
|
68
|
+
"aria-label": A ? T.auth.hidePassword : T.auth.showPassword,
|
|
69
|
+
size: "sm",
|
|
70
|
+
variant: "ghost",
|
|
71
|
+
onPress: () => j(!A),
|
|
72
|
+
isDisabled: k,
|
|
73
|
+
children: m(A ? y : v, {})
|
|
74
|
+
})
|
|
75
|
+
})]
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ m(a, {})
|
|
78
|
+
]
|
|
79
|
+
}),
|
|
80
|
+
w?.confirmPassword && /* @__PURE__ */ h(d, {
|
|
81
|
+
minLength: w?.minPasswordLength,
|
|
82
|
+
maxLength: w?.maxPasswordLength,
|
|
83
|
+
name: "confirmPassword",
|
|
84
|
+
autoComplete: "new-password",
|
|
85
|
+
isDisabled: k,
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ m(c, { children: T.auth.confirmPassword }),
|
|
88
|
+
/* @__PURE__ */ h(s, {
|
|
89
|
+
variant: x === "transparent" ? "primary" : "secondary",
|
|
90
|
+
children: [/* @__PURE__ */ m(s.Input, {
|
|
91
|
+
placeholder: T.auth.confirmPasswordPlaceholder,
|
|
92
|
+
type: M ? "text" : "password",
|
|
93
|
+
required: !0,
|
|
94
|
+
name: "confirmPassword"
|
|
95
|
+
}), /* @__PURE__ */ m(s.Suffix, {
|
|
96
|
+
className: "px-0",
|
|
97
|
+
children: /* @__PURE__ */ m(n, {
|
|
98
|
+
isIconOnly: !0,
|
|
99
|
+
"aria-label": M ? T.auth.hidePassword : T.auth.showPassword,
|
|
100
|
+
size: "sm",
|
|
101
|
+
variant: "ghost",
|
|
102
|
+
onPress: () => N(!M),
|
|
103
|
+
isDisabled: k,
|
|
104
|
+
children: m(M ? y : v, {})
|
|
105
|
+
})
|
|
106
|
+
})]
|
|
107
|
+
}),
|
|
108
|
+
/* @__PURE__ */ m(a, {})
|
|
109
|
+
]
|
|
110
|
+
}),
|
|
111
|
+
/* @__PURE__ */ m("div", {
|
|
112
|
+
className: "flex flex-col gap-3",
|
|
113
|
+
children: /* @__PURE__ */ h(n, {
|
|
114
|
+
type: "submit",
|
|
115
|
+
className: "w-full",
|
|
116
|
+
isPending: k,
|
|
117
|
+
children: [k && /* @__PURE__ */ m(u, {
|
|
118
|
+
color: "current",
|
|
119
|
+
size: "sm"
|
|
120
|
+
}), T.auth.resetPassword]
|
|
121
|
+
})
|
|
122
|
+
})
|
|
123
|
+
]
|
|
124
|
+
}) }),
|
|
125
|
+
/* @__PURE__ */ m(r.Footer, {
|
|
126
|
+
className: "flex-col",
|
|
127
|
+
children: /* @__PURE__ */ h(i, {
|
|
128
|
+
className: "text-sm",
|
|
129
|
+
children: [
|
|
130
|
+
T.auth.rememberYourPassword,
|
|
131
|
+
" ",
|
|
132
|
+
/* @__PURE__ */ m(l, {
|
|
133
|
+
href: `${C.auth}/${E.auth.signIn}`,
|
|
134
|
+
className: "text-accent decoration-accent no-underline hover:underline",
|
|
135
|
+
children: T.auth.signIn
|
|
136
|
+
})
|
|
137
|
+
]
|
|
138
|
+
})
|
|
139
|
+
})
|
|
140
|
+
]
|
|
141
|
+
});
|
|
58
142
|
}
|
|
143
|
+
//#endregion
|
|
144
|
+
export { b as ResetPassword };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { CardProps } from '@heroui/react';
|
|
2
|
+
import { SocialLayout } from './provider-buttons';
|
|
3
3
|
export interface SignInProps {
|
|
4
4
|
className?: string;
|
|
5
5
|
socialLayout?: SocialLayout;
|
|
@@ -11,4 +11,4 @@ export interface SignInProps {
|
|
|
11
11
|
*
|
|
12
12
|
* @returns The sign-in JSX element containing email/password fields, optional magic-link button, and social provider buttons.
|
|
13
13
|
*/
|
|
14
|
-
export declare function SignIn({ className, socialLayout, socialPosition, variant, ...props }: SignInProps & CardProps): import("react/jsx-runtime").JSX.Element;
|
|
14
|
+
export declare function SignIn({ className, socialLayout, socialPosition, variant, ...props }: SignInProps & Omit<CardProps, "children">): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,65 +1,152 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
* @returns The sign-in JSX element containing email/password fields, optional magic-link button, and social provider buttons.
|
|
13
|
-
*/
|
|
14
|
-
export function SignIn({ className, socialLayout, socialPosition = "bottom", variant, ...props }) {
|
|
15
|
-
const { basePaths, baseURL, emailAndPassword, localization, magicLink, passkey, redirectTo, socialProviders, viewPaths, navigate } = useAuth();
|
|
16
|
-
const [password, setPassword] = useState("");
|
|
17
|
-
const { mutate: sendVerificationEmail } = useSendVerificationEmail({
|
|
18
|
-
onError: (error) => toast.danger(error.error?.message || error.message),
|
|
19
|
-
onSuccess: () => toast.success(localization.auth.verificationEmailSent)
|
|
20
|
-
});
|
|
21
|
-
const { mutate: signInEmail, isPending: signInPending } = useSignInEmail({
|
|
22
|
-
onError: (error, { email }) => {
|
|
23
|
-
setPassword("");
|
|
24
|
-
if (error.error?.code === "EMAIL_NOT_VERIFIED") {
|
|
25
|
-
toast.danger(error.error?.message || error.message, {
|
|
26
|
-
actionProps: {
|
|
27
|
-
children: localization.auth.resend,
|
|
28
|
-
onClick: () => sendVerificationEmail({
|
|
29
|
-
email,
|
|
30
|
-
callbackURL: `${baseURL}${redirectTo}`
|
|
31
|
-
})
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
toast.danger(error.error?.message || error.message);
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
onSuccess: () => navigate({ to: redirectTo })
|
|
40
|
-
});
|
|
41
|
-
const [socialRedirecting, setSocialRedirecting] = useState(false);
|
|
42
|
-
const { mutate: signInSocial, isPending: socialPending } = useSignInSocial({
|
|
43
|
-
onError: (error) => toast.danger(error.error?.message || error.message),
|
|
44
|
-
onSuccess: () => {
|
|
45
|
-
setSocialRedirecting(true);
|
|
46
|
-
setTimeout(() => {
|
|
47
|
-
setSocialRedirecting(false);
|
|
48
|
-
}, 5000);
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
const handleSubmit = (e) => {
|
|
52
|
-
e.preventDefault();
|
|
53
|
-
const formData = new FormData(e.currentTarget);
|
|
54
|
-
const email = formData.get("email");
|
|
55
|
-
const rememberMe = formData.get("rememberMe") === "on";
|
|
56
|
-
signInEmail({
|
|
57
|
-
email,
|
|
58
|
-
password,
|
|
59
|
-
...(emailAndPassword?.rememberMe ? { rememberMe } : {})
|
|
60
|
-
});
|
|
61
|
-
};
|
|
62
|
-
const isPending = signInPending || socialPending || socialRedirecting;
|
|
63
|
-
const showSeparator = emailAndPassword?.enabled && !!socialProviders?.length;
|
|
64
|
-
return (_jsxs(Card, { className: cn("w-full max-w-sm gap-4 md:p-6", className), variant: variant, ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl font-semibold mb-1", children: localization.auth.signIn }) }), _jsxs(Card.Content, { className: "gap-4", children: [socialPosition === "top" && (_jsxs(_Fragment, { children: [!!socialProviders?.length && (_jsx(ProviderButtons, { socialLayout: socialLayout, signInSocial: signInSocial, isPending: isPending })), showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or }))] })), emailAndPassword?.enabled && (_jsxs(Form, { onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs(TextField, { name: "email", type: "email", autoComplete: "email", isDisabled: isPending, children: [_jsx(Label, { children: localization.auth.email }), _jsx(Input, { placeholder: localization.auth.emailPlaceholder, variant: variant === "transparent" ? "primary" : "secondary", required: true }), _jsx(FieldError, {})] }), _jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, name: "password", type: "password", autoComplete: "current-password", isDisabled: isPending, value: password, onChange: setPassword, children: [_jsx(Label, { children: localization.auth.password }), _jsx(Input, { placeholder: localization.auth.passwordPlaceholder, variant: variant === "transparent" ? "primary" : "secondary", required: true }), _jsx(FieldError, {})] }), emailAndPassword?.rememberMe && (_jsxs(Checkbox, { name: "rememberMe", isDisabled: isPending, variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(Checkbox.Control, { children: _jsx(Checkbox.Indicator, {}) }), _jsx(Checkbox.Content, { children: _jsx(Label, { children: localization.auth.rememberMe }) })] })), _jsxs("div", { className: "flex flex-col gap-3", children: [_jsxs(Button, { type: "submit", className: "w-full", isPending: isPending, children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.auth.signIn] }), magicLink && (_jsx(MagicLinkButton, { view: "signIn", isPending: isPending })), passkey && _jsx(PasskeyButton, { isPending: isPending })] })] })), socialPosition === "bottom" && (_jsxs(_Fragment, { children: [showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or })), !!socialProviders?.length && (_jsx(ProviderButtons, { socialLayout: socialLayout, signInSocial: signInSocial, isPending: isPending }))] }))] }), _jsxs(Card.Footer, { className: "flex-col gap-3", children: [emailAndPassword?.forgotPassword && (_jsx(Link, { href: `${basePaths.auth}/${viewPaths.auth.forgotPassword}`, className: "no-underline hover:underline", children: localization.auth.forgotPasswordLink })), emailAndPassword?.enabled && (_jsxs(Description, { className: "text-sm", children: [localization.auth.needToCreateAnAccount, " ", _jsx(Link, { href: `${basePaths.auth}/${viewPaths.auth.signUp}`, className: "text-accent no-underline hover:underline decoration-accent-hover", children: localization.auth.signUp })] }))] })] }));
|
|
1
|
+
import { FieldSeparator as e } from "./field-separator.js";
|
|
2
|
+
import { MagicLinkButton as t } from "./magic-link-button.js";
|
|
3
|
+
import { PasskeyButton as n } from "./passkey-button.js";
|
|
4
|
+
import { ProviderButtons as r } from "./provider-buttons.js";
|
|
5
|
+
import { useAuth as i, useSendVerificationEmail as a, useSignInEmail as o, useSignInUsername as s } from "@better-auth-ui/react";
|
|
6
|
+
import { Button as c, Card as l, Checkbox as u, Description as d, FieldError as f, Form as p, Input as m, Label as h, Link as g, Spinner as _, TextField as v, cn as y, toast as b } from "@heroui/react";
|
|
7
|
+
import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
|
|
8
|
+
import { useState as w } from "react";
|
|
9
|
+
//#region src/components/auth/sign-in.tsx
|
|
10
|
+
function T(e) {
|
|
11
|
+
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);
|
|
65
12
|
}
|
|
13
|
+
function E({ className: E, socialLayout: D, socialPosition: O = "bottom", variant: k, ...A }) {
|
|
14
|
+
let { basePaths: j, baseURL: M, emailAndPassword: N, localization: P, magicLink: F, passkey: I, redirectTo: L, socialProviders: R, username: z, viewPaths: B, navigate: V } = i(), [H, U] = w(""), { mutate: W } = a({ onSuccess: () => b.success(P.auth.verificationEmailSent) }), { mutate: G, isPending: K } = o({
|
|
15
|
+
onError: (e, { email: t }) => {
|
|
16
|
+
U(""), e.error?.code === "EMAIL_NOT_VERIFIED" ? b.danger(e.error?.message || e.message, { actionProps: {
|
|
17
|
+
children: P.auth.resend,
|
|
18
|
+
onClick: () => W({
|
|
19
|
+
email: t,
|
|
20
|
+
callbackURL: `${M}${L}`
|
|
21
|
+
})
|
|
22
|
+
} }) : b.danger(e.error?.message || e.message);
|
|
23
|
+
},
|
|
24
|
+
onSuccess: () => V({ to: L })
|
|
25
|
+
}), { mutate: q, isPending: J } = s({
|
|
26
|
+
onError: (e) => {
|
|
27
|
+
U(""), b.danger(e.error?.message || e.message);
|
|
28
|
+
},
|
|
29
|
+
onSuccess: () => V({ to: L })
|
|
30
|
+
}), Y = (e) => {
|
|
31
|
+
e.preventDefault();
|
|
32
|
+
let t = new FormData(e.currentTarget), n = t.get("email"), r = t.get("rememberMe") === "on";
|
|
33
|
+
z?.enabled && !T(n) ? q({
|
|
34
|
+
username: n,
|
|
35
|
+
password: H
|
|
36
|
+
}) : G({
|
|
37
|
+
email: n,
|
|
38
|
+
password: H,
|
|
39
|
+
...N?.rememberMe ? { rememberMe: r } : {}
|
|
40
|
+
});
|
|
41
|
+
}, X = K || J, Z = N?.enabled && !!R?.length;
|
|
42
|
+
return /* @__PURE__ */ C(l, {
|
|
43
|
+
className: y("w-full max-w-sm gap-4 md:p-6", E),
|
|
44
|
+
variant: k,
|
|
45
|
+
...A,
|
|
46
|
+
children: [
|
|
47
|
+
/* @__PURE__ */ S(l.Header, { children: /* @__PURE__ */ S(l.Title, {
|
|
48
|
+
className: "text-xl font-semibold mb-1",
|
|
49
|
+
children: P.auth.signIn
|
|
50
|
+
}) }),
|
|
51
|
+
/* @__PURE__ */ C(l.Content, {
|
|
52
|
+
className: "gap-4",
|
|
53
|
+
children: [
|
|
54
|
+
O === "top" && /* @__PURE__ */ C(x, { children: [!!R?.length && /* @__PURE__ */ S(r, {
|
|
55
|
+
socialLayout: D,
|
|
56
|
+
isPending: X
|
|
57
|
+
}), Z && /* @__PURE__ */ S(e, { children: P.auth.or })] }),
|
|
58
|
+
N?.enabled && /* @__PURE__ */ C(p, {
|
|
59
|
+
onSubmit: Y,
|
|
60
|
+
className: "flex flex-col gap-4",
|
|
61
|
+
children: [
|
|
62
|
+
/* @__PURE__ */ C(v, {
|
|
63
|
+
name: "email",
|
|
64
|
+
type: z?.enabled ? "text" : "email",
|
|
65
|
+
autoComplete: z?.enabled ? "username" : "email",
|
|
66
|
+
isDisabled: X,
|
|
67
|
+
children: [
|
|
68
|
+
/* @__PURE__ */ S(h, { children: z?.enabled ? P.auth.username : P.auth.email }),
|
|
69
|
+
/* @__PURE__ */ S(m, {
|
|
70
|
+
placeholder: z?.enabled ? P.auth.usernameOrEmailPlaceholder : P.auth.emailPlaceholder,
|
|
71
|
+
variant: k === "transparent" ? "primary" : "secondary",
|
|
72
|
+
required: !0
|
|
73
|
+
}),
|
|
74
|
+
/* @__PURE__ */ S(f, {})
|
|
75
|
+
]
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ C(v, {
|
|
78
|
+
minLength: N?.minPasswordLength,
|
|
79
|
+
maxLength: N?.maxPasswordLength,
|
|
80
|
+
name: "password",
|
|
81
|
+
type: "password",
|
|
82
|
+
autoComplete: "current-password",
|
|
83
|
+
isDisabled: X,
|
|
84
|
+
value: H,
|
|
85
|
+
onChange: U,
|
|
86
|
+
children: [
|
|
87
|
+
/* @__PURE__ */ S(h, { children: P.auth.password }),
|
|
88
|
+
/* @__PURE__ */ S(m, {
|
|
89
|
+
placeholder: P.auth.passwordPlaceholder,
|
|
90
|
+
variant: k === "transparent" ? "primary" : "secondary",
|
|
91
|
+
required: !0
|
|
92
|
+
}),
|
|
93
|
+
/* @__PURE__ */ S(f, {})
|
|
94
|
+
]
|
|
95
|
+
}),
|
|
96
|
+
N?.rememberMe && /* @__PURE__ */ C(u, {
|
|
97
|
+
name: "rememberMe",
|
|
98
|
+
isDisabled: X,
|
|
99
|
+
variant: k === "transparent" ? "primary" : "secondary",
|
|
100
|
+
children: [/* @__PURE__ */ S(u.Control, { children: /* @__PURE__ */ S(u.Indicator, {}) }), /* @__PURE__ */ S(u.Content, { children: /* @__PURE__ */ S(h, { children: P.auth.rememberMe }) })]
|
|
101
|
+
}),
|
|
102
|
+
/* @__PURE__ */ C("div", {
|
|
103
|
+
className: "flex flex-col gap-3",
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ C(c, {
|
|
106
|
+
type: "submit",
|
|
107
|
+
className: "w-full",
|
|
108
|
+
isPending: X,
|
|
109
|
+
children: [X && /* @__PURE__ */ S(_, {
|
|
110
|
+
color: "current",
|
|
111
|
+
size: "sm"
|
|
112
|
+
}), P.auth.signIn]
|
|
113
|
+
}),
|
|
114
|
+
F && /* @__PURE__ */ S(t, {
|
|
115
|
+
view: "signIn",
|
|
116
|
+
isPending: X
|
|
117
|
+
}),
|
|
118
|
+
I && /* @__PURE__ */ S(n, { isPending: X })
|
|
119
|
+
]
|
|
120
|
+
})
|
|
121
|
+
]
|
|
122
|
+
}),
|
|
123
|
+
O === "bottom" && /* @__PURE__ */ C(x, { children: [Z && /* @__PURE__ */ S(e, { children: P.auth.or }), !!R?.length && /* @__PURE__ */ S(r, {
|
|
124
|
+
socialLayout: D,
|
|
125
|
+
isPending: X
|
|
126
|
+
})] })
|
|
127
|
+
]
|
|
128
|
+
}),
|
|
129
|
+
/* @__PURE__ */ C(l.Footer, {
|
|
130
|
+
className: "flex-col gap-3",
|
|
131
|
+
children: [N?.forgotPassword && /* @__PURE__ */ S(g, {
|
|
132
|
+
href: `${j.auth}/${B.auth.forgotPassword}`,
|
|
133
|
+
className: "no-underline hover:underline",
|
|
134
|
+
children: P.auth.forgotPasswordLink
|
|
135
|
+
}), N?.enabled && /* @__PURE__ */ C(d, {
|
|
136
|
+
className: "text-sm",
|
|
137
|
+
children: [
|
|
138
|
+
P.auth.needToCreateAnAccount,
|
|
139
|
+
" ",
|
|
140
|
+
/* @__PURE__ */ S(g, {
|
|
141
|
+
href: `${j.auth}/${B.auth.signUp}`,
|
|
142
|
+
className: "text-accent no-underline hover:underline decoration-accent-hover",
|
|
143
|
+
children: P.auth.signUp
|
|
144
|
+
})
|
|
145
|
+
]
|
|
146
|
+
})]
|
|
147
|
+
})
|
|
148
|
+
]
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
152
|
+
export { E as SignIn };
|
|
@@ -1,33 +1,27 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { useEffect, useRef } from "react";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const hasSignedOut = useRef(false);
|
|
26
|
-
useEffect(() => {
|
|
27
|
-
if (hasSignedOut.current)
|
|
28
|
-
return;
|
|
29
|
-
hasSignedOut.current = true;
|
|
30
|
-
signOut();
|
|
31
|
-
}, [signOut]);
|
|
32
|
-
return (_jsx(Spinner, { className: cn("mx-auto my-auto", className), color: "current" }));
|
|
1
|
+
import { useAuth as e, useSignOut as t } from "@better-auth-ui/react";
|
|
2
|
+
import { Spinner as n, cn as r, toast as i } from "@heroui/react";
|
|
3
|
+
import { jsx as a } from "react/jsx-runtime";
|
|
4
|
+
import { useEffect as o, useRef as s } from "react";
|
|
5
|
+
//#region src/components/auth/sign-out.tsx
|
|
6
|
+
function c({ className: c }) {
|
|
7
|
+
let { basePaths: l, navigate: u, viewPaths: d } = e(), { mutate: f } = t({
|
|
8
|
+
onError: (e) => {
|
|
9
|
+
i.danger(e.error?.message || e.message), u({
|
|
10
|
+
to: `${l.auth}/${d.auth.signIn}`,
|
|
11
|
+
replace: !0
|
|
12
|
+
});
|
|
13
|
+
},
|
|
14
|
+
onSuccess: () => u({
|
|
15
|
+
to: `${l.auth}/${d.auth.signIn}`,
|
|
16
|
+
replace: !0
|
|
17
|
+
})
|
|
18
|
+
}), p = s(!1);
|
|
19
|
+
return o(() => {
|
|
20
|
+
p.current || (p.current = !0, f());
|
|
21
|
+
}, [f]), /* @__PURE__ */ a(n, {
|
|
22
|
+
className: r("mx-auto my-auto", c),
|
|
23
|
+
color: "current"
|
|
24
|
+
});
|
|
33
25
|
}
|
|
26
|
+
//#endregion
|
|
27
|
+
export { c as SignOut };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { CardProps } from '@heroui/react';
|
|
2
|
+
import { SocialLayout } from './provider-buttons';
|
|
3
3
|
export type SignUpProps = {
|
|
4
4
|
className?: string;
|
|
5
5
|
socialLayout?: SocialLayout;
|
|
@@ -16,4 +16,4 @@ export type SignUpProps = {
|
|
|
16
16
|
* @param socialPosition - Position of social provider buttons relative to the form; `"top"` or `"bottom"` (default `"bottom"`)
|
|
17
17
|
* @returns The sign-up form React element
|
|
18
18
|
*/
|
|
19
|
-
export declare function SignUp({ className, socialLayout, socialPosition, variant, ...props }: SignUpProps & CardProps): import("react/jsx-runtime").JSX.Element;
|
|
19
|
+
export declare function SignUp({ className, socialLayout, socialPosition, variant, ...props }: SignUpProps & Omit<CardProps, "children">): import("react/jsx-runtime").JSX.Element;
|