@better-auth-ui/heroui 1.6.4 → 1.6.6
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/delete-user/danger-zone.d.ts +3 -2
- package/dist/components/auth/delete-user/danger-zone.js +1 -1
- package/dist/components/auth/delete-user/delete-user.js +53 -53
- package/dist/components/auth/forgot-password.js +67 -48
- package/dist/components/auth/sign-in.js +72 -67
- package/dist/components/auth/sign-up.js +82 -77
- package/dist/components/auth/theme/theme-toggle-item.js +50 -46
- package/dist/components/auth/user/user-button.d.ts +27 -2
- package/dist/components/auth/user/user-button.js +48 -29
- package/dist/components/auth/username/sign-in-username.js +80 -74
- package/dist/components/auth/username/username-field.js +4 -2
- package/package.json +12 -12
- package/src/components/auth/delete-user/danger-zone.tsx +10 -3
- package/src/components/auth/delete-user/delete-user.tsx +2 -7
- package/src/components/auth/forgot-password.tsx +29 -7
- package/src/components/auth/sign-in.tsx +13 -1
- package/src/components/auth/sign-up.tsx +12 -2
- package/src/components/auth/theme/theme-toggle-item.tsx +2 -1
- package/src/components/auth/user/user-button.tsx +80 -13
- package/src/components/auth/username/sign-in-username.tsx +40 -24
- package/src/components/auth/username/username-field.tsx +4 -2
|
@@ -2,135 +2,141 @@ import { FieldSeparator as e } from "../field-separator.js";
|
|
|
2
2
|
import { ProviderButtons as t } from "../provider-buttons.js";
|
|
3
3
|
import { usernamePlugin as n } from "../../../lib/auth/username-plugin.js";
|
|
4
4
|
import { authMutationKeys as r } from "@better-auth-ui/core";
|
|
5
|
-
import { useAuth as i, useAuthPlugin as a,
|
|
6
|
-
import { Button as
|
|
7
|
-
import { useState as
|
|
8
|
-
import { Fragment as
|
|
9
|
-
import { useIsMutating as
|
|
5
|
+
import { useAuth as i, useAuthPlugin as a, useFetchOptions as o, useSendVerificationEmail as s, useSignInEmail as c, useSignInUsername as l } from "@better-auth-ui/react";
|
|
6
|
+
import { Button as ee, Card as u, Checkbox as d, Description as f, FieldError as p, Form as te, Input as m, Label as h, Link as g, Spinner as ne, TextField as _, cn as v, toast as y } from "@heroui/react";
|
|
7
|
+
import { useState as re } from "react";
|
|
8
|
+
import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
|
|
9
|
+
import { useIsMutating as C } from "@tanstack/react-query";
|
|
10
10
|
//#region src/components/auth/username/sign-in-username.tsx
|
|
11
|
-
function
|
|
12
|
-
let { authClient:
|
|
13
|
-
function
|
|
11
|
+
function w({ className: w, socialLayout: T, socialPosition: E = "bottom", variant: D, ...O }) {
|
|
12
|
+
let { authClient: k, basePaths: A, baseURL: j, emailAndPassword: M, localization: N, plugins: P, redirectTo: F, socialProviders: I, viewPaths: L, navigate: R } = i(), { fetchOptions: z, resetFetchOptions: B } = o(), { localization: V } = a(n), [H, U] = re(""), { mutate: W } = s(k, { onSuccess: () => y.success(N.auth.verificationEmailSent) });
|
|
13
|
+
function G(e) {
|
|
14
14
|
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e);
|
|
15
15
|
}
|
|
16
|
-
let { mutate: q } =
|
|
16
|
+
let { mutate: K, isPending: q } = c(k, {
|
|
17
17
|
onError: (e, { email: t }) => {
|
|
18
|
-
|
|
19
|
-
children:
|
|
20
|
-
onClick: () =>
|
|
18
|
+
U(""), e.error?.code === "EMAIL_NOT_VERIFIED" ? y.danger(e.error?.message || e.message, { actionProps: {
|
|
19
|
+
children: N.auth.resend,
|
|
20
|
+
onClick: () => W({
|
|
21
21
|
email: t,
|
|
22
|
-
callbackURL: `${
|
|
22
|
+
callbackURL: `${j}${F}`
|
|
23
23
|
})
|
|
24
|
-
} }) :
|
|
24
|
+
} }) : y.danger(e.error?.message || e.message), B();
|
|
25
25
|
},
|
|
26
|
-
onSuccess: () =>
|
|
27
|
-
}), { mutate: J, isPending: Y } =
|
|
26
|
+
onSuccess: () => R({ to: F })
|
|
27
|
+
}), { mutate: J, isPending: Y } = l(k, {
|
|
28
28
|
onError: (e) => {
|
|
29
|
-
|
|
29
|
+
U(""), y.danger(e.error?.message || e.message), B();
|
|
30
30
|
},
|
|
31
|
-
onSuccess: () =>
|
|
32
|
-
}),
|
|
31
|
+
onSuccess: () => R({ to: F })
|
|
32
|
+
}), ie = (e) => {
|
|
33
33
|
e.preventDefault();
|
|
34
34
|
let t = new FormData(e.currentTarget), n = t.get("email"), r = t.get("rememberMe") === "on";
|
|
35
|
-
|
|
35
|
+
G(n) ? K({
|
|
36
36
|
email: n,
|
|
37
|
-
password:
|
|
38
|
-
...
|
|
37
|
+
password: H,
|
|
38
|
+
...M?.rememberMe ? { rememberMe: r } : {},
|
|
39
|
+
fetchOptions: z
|
|
39
40
|
}) : J({
|
|
40
41
|
username: n,
|
|
41
|
-
password:
|
|
42
|
-
...
|
|
42
|
+
password: H,
|
|
43
|
+
...M?.rememberMe ? { rememberMe: r } : {},
|
|
44
|
+
fetchOptions: z
|
|
43
45
|
});
|
|
44
|
-
},
|
|
45
|
-
return /* @__PURE__ */
|
|
46
|
-
className:
|
|
47
|
-
variant:
|
|
48
|
-
...
|
|
46
|
+
}, X = C({ mutationKey: r.signIn.all }) + C({ mutationKey: r.signUp.all }) > 0, Z = q || Y, Q = P.find((e) => e.captchaComponent)?.captchaComponent, $ = M?.enabled && !!I?.length;
|
|
47
|
+
return /* @__PURE__ */ S(u, {
|
|
48
|
+
className: v("w-full max-w-sm gap-4 md:p-6", w),
|
|
49
|
+
variant: D,
|
|
50
|
+
...O,
|
|
49
51
|
children: [
|
|
50
|
-
/* @__PURE__ */
|
|
52
|
+
/* @__PURE__ */ x(u.Header, { children: /* @__PURE__ */ x(u.Title, {
|
|
51
53
|
className: "text-xl font-semibold mb-1",
|
|
52
|
-
children:
|
|
54
|
+
children: N.auth.signIn
|
|
53
55
|
}) }),
|
|
54
|
-
/* @__PURE__ */
|
|
56
|
+
/* @__PURE__ */ S(u.Content, {
|
|
55
57
|
className: "gap-4",
|
|
56
58
|
children: [
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
onSubmit:
|
|
59
|
+
E === "top" && /* @__PURE__ */ S(b, { children: [!!I?.length && /* @__PURE__ */ x(t, { socialLayout: T }), $ && /* @__PURE__ */ x(e, { children: N.auth.or })] }),
|
|
60
|
+
M?.enabled && /* @__PURE__ */ S(te, {
|
|
61
|
+
onSubmit: ie,
|
|
60
62
|
className: "flex flex-col gap-4",
|
|
61
63
|
children: [
|
|
62
|
-
/* @__PURE__ */
|
|
64
|
+
/* @__PURE__ */ S(_, {
|
|
63
65
|
name: "email",
|
|
64
66
|
type: "text",
|
|
65
67
|
autoComplete: "username email",
|
|
66
|
-
isDisabled:
|
|
68
|
+
isDisabled: X,
|
|
67
69
|
children: [
|
|
68
|
-
/* @__PURE__ */
|
|
69
|
-
/* @__PURE__ */
|
|
70
|
-
placeholder:
|
|
71
|
-
variant:
|
|
70
|
+
/* @__PURE__ */ x(h, { children: V.username }),
|
|
71
|
+
/* @__PURE__ */ x(m, {
|
|
72
|
+
placeholder: V.usernameOrEmailPlaceholder,
|
|
73
|
+
variant: D === "transparent" ? "primary" : "secondary",
|
|
72
74
|
required: !0
|
|
73
75
|
}),
|
|
74
|
-
/* @__PURE__ */
|
|
76
|
+
/* @__PURE__ */ x(p, {})
|
|
75
77
|
]
|
|
76
78
|
}),
|
|
77
|
-
/* @__PURE__ */
|
|
78
|
-
minLength:
|
|
79
|
-
maxLength:
|
|
79
|
+
/* @__PURE__ */ S(_, {
|
|
80
|
+
minLength: M?.minPasswordLength,
|
|
81
|
+
maxLength: M?.maxPasswordLength,
|
|
80
82
|
name: "password",
|
|
81
83
|
type: "password",
|
|
82
84
|
autoComplete: "current-password",
|
|
83
|
-
isDisabled:
|
|
84
|
-
value:
|
|
85
|
-
onChange:
|
|
85
|
+
isDisabled: X,
|
|
86
|
+
value: H,
|
|
87
|
+
onChange: U,
|
|
86
88
|
children: [
|
|
87
|
-
/* @__PURE__ */
|
|
88
|
-
/* @__PURE__ */
|
|
89
|
-
placeholder:
|
|
90
|
-
variant:
|
|
89
|
+
/* @__PURE__ */ x(h, { children: N.auth.password }),
|
|
90
|
+
/* @__PURE__ */ x(m, {
|
|
91
|
+
placeholder: N.auth.passwordPlaceholder,
|
|
92
|
+
variant: D === "transparent" ? "primary" : "secondary",
|
|
91
93
|
required: !0
|
|
92
94
|
}),
|
|
93
|
-
/* @__PURE__ */
|
|
95
|
+
/* @__PURE__ */ x(p, {})
|
|
94
96
|
]
|
|
95
97
|
}),
|
|
96
|
-
|
|
98
|
+
M?.rememberMe && /* @__PURE__ */ S(d, {
|
|
97
99
|
name: "rememberMe",
|
|
98
|
-
isDisabled:
|
|
99
|
-
variant:
|
|
100
|
-
children: [/* @__PURE__ */
|
|
100
|
+
isDisabled: X,
|
|
101
|
+
variant: D === "transparent" ? "primary" : "secondary",
|
|
102
|
+
children: [/* @__PURE__ */ x(d.Control, { children: /* @__PURE__ */ x(d.Indicator, {}) }), /* @__PURE__ */ x(d.Content, { children: /* @__PURE__ */ x(h, { children: N.auth.rememberMe }) })]
|
|
101
103
|
}),
|
|
102
|
-
/* @__PURE__ */
|
|
104
|
+
Q && /* @__PURE__ */ x("div", {
|
|
105
|
+
className: "flex justify-center",
|
|
106
|
+
children: Q
|
|
107
|
+
}),
|
|
108
|
+
/* @__PURE__ */ S("div", {
|
|
103
109
|
className: "flex flex-col gap-3",
|
|
104
|
-
children: [/* @__PURE__ */
|
|
110
|
+
children: [/* @__PURE__ */ S(ee, {
|
|
105
111
|
type: "submit",
|
|
106
112
|
className: "w-full",
|
|
107
|
-
isPending:
|
|
108
|
-
children: [
|
|
113
|
+
isPending: Z || X,
|
|
114
|
+
children: [Z && /* @__PURE__ */ x(ne, {
|
|
109
115
|
color: "current",
|
|
110
116
|
size: "sm"
|
|
111
|
-
}),
|
|
112
|
-
}),
|
|
117
|
+
}), N.auth.signIn]
|
|
118
|
+
}), P.flatMap((e) => e.authButtons?.map((t, n) => /* @__PURE__ */ x(t, { view: "signIn" }, `${e.id}-${n.toString()}`)))]
|
|
113
119
|
})
|
|
114
120
|
]
|
|
115
121
|
}),
|
|
116
|
-
|
|
122
|
+
E === "bottom" && /* @__PURE__ */ S(b, { children: [$ && /* @__PURE__ */ x(e, { children: N.auth.or }), !!I?.length && /* @__PURE__ */ x(t, { socialLayout: T })] })
|
|
117
123
|
]
|
|
118
124
|
}),
|
|
119
|
-
/* @__PURE__ */
|
|
125
|
+
/* @__PURE__ */ S(u.Footer, {
|
|
120
126
|
className: "flex-col gap-3",
|
|
121
|
-
children: [
|
|
122
|
-
href: `${
|
|
127
|
+
children: [M?.forgotPassword && /* @__PURE__ */ x(g, {
|
|
128
|
+
href: `${A.auth}/${L.auth.forgotPassword}`,
|
|
123
129
|
className: "no-underline hover:underline",
|
|
124
|
-
children:
|
|
125
|
-
}),
|
|
130
|
+
children: N.auth.forgotPasswordLink
|
|
131
|
+
}), M?.enabled && /* @__PURE__ */ S(f, {
|
|
126
132
|
className: "text-sm",
|
|
127
133
|
children: [
|
|
128
|
-
|
|
134
|
+
N.auth.needToCreateAnAccount,
|
|
129
135
|
" ",
|
|
130
|
-
/* @__PURE__ */
|
|
131
|
-
href: `${
|
|
136
|
+
/* @__PURE__ */ x(g, {
|
|
137
|
+
href: `${A.auth}/${L.auth.signUp}`,
|
|
132
138
|
className: "text-accent no-underline hover:underline decoration-accent-hover",
|
|
133
|
-
children:
|
|
139
|
+
children: N.auth.signUp
|
|
134
140
|
})
|
|
135
141
|
]
|
|
136
142
|
})]
|
|
@@ -139,4 +145,4 @@ function D({ className: D, socialLayout: O, socialPosition: k = "bottom", varian
|
|
|
139
145
|
});
|
|
140
146
|
}
|
|
141
147
|
//#endregion
|
|
142
|
-
export {
|
|
148
|
+
export { w as SignInUsername };
|
|
@@ -26,7 +26,6 @@ function h({ name: h, field: g, isPending: _, variant: v }) {
|
|
|
26
26
|
minLength: x,
|
|
27
27
|
maxLength: S,
|
|
28
28
|
isDisabled: _,
|
|
29
|
-
isRequired: g.required,
|
|
30
29
|
isReadOnly: g.readOnly,
|
|
31
30
|
value: T,
|
|
32
31
|
onChange: M,
|
|
@@ -34,7 +33,10 @@ function h({ name: h, field: g, isPending: _, variant: v }) {
|
|
|
34
33
|
/* @__PURE__ */ f(c, { children: g.label }),
|
|
35
34
|
/* @__PURE__ */ p(s, {
|
|
36
35
|
variant: v === "transparent" ? "primary" : "secondary",
|
|
37
|
-
children: [/* @__PURE__ */ f(s.Input, {
|
|
36
|
+
children: [/* @__PURE__ */ f(s.Input, {
|
|
37
|
+
placeholder: g.placeholder,
|
|
38
|
+
required: g.required
|
|
39
|
+
}), N && /* @__PURE__ */ f(s.Suffix, {
|
|
38
40
|
"aria-label": O?.available ? b.usernameAvailable : O?.available === !1 ? b.usernameTaken : void 0,
|
|
39
41
|
className: "px-2",
|
|
40
42
|
children: O?.available ? /* @__PURE__ */ f(i, { className: "text-success" }) : k || O?.available === !1 ? /* @__PURE__ */ f(a, { className: "text-danger" }) : /* @__PURE__ */ f(l, {
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@better-auth-ui/heroui",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"build": "vite build",
|
|
7
|
-
"dev": "
|
|
7
|
+
"dev": "tsc --watch",
|
|
8
8
|
"test": "vitest"
|
|
9
9
|
},
|
|
10
10
|
"files": [
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
},
|
|
29
29
|
"devDependencies": {
|
|
30
30
|
"@gravity-ui/icons": "^2.18.0",
|
|
31
|
-
"@heroui/react": "^3.0.
|
|
32
|
-
"@heroui/styles": "^3.0.
|
|
31
|
+
"@heroui/react": "^3.0.4",
|
|
32
|
+
"@heroui/styles": "^3.0.4",
|
|
33
33
|
"@internationalized/date": "^3.12.1",
|
|
34
34
|
"@tanstack/react-pacer": "^0.22.0",
|
|
35
|
-
"@tanstack/react-query": "^5.100.
|
|
35
|
+
"@tanstack/react-query": "^5.100.9",
|
|
36
36
|
"@testing-library/react": "^16.3.2",
|
|
37
37
|
"@testing-library/user-event": "^14.5.2",
|
|
38
38
|
"@types/react": "^19.2.14",
|
|
@@ -41,22 +41,22 @@
|
|
|
41
41
|
"better-auth": "^1.6.9",
|
|
42
42
|
"bowser": "^2.11.0",
|
|
43
43
|
"playwright": "^1.59.1",
|
|
44
|
-
"react": "^19.2.
|
|
45
|
-
"react-dom": "^19.2.
|
|
44
|
+
"react": "^19.2.6",
|
|
45
|
+
"react-dom": "^19.2.6",
|
|
46
46
|
"vitest": "^4.1.5"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
49
49
|
"@better-auth-ui/core": "*",
|
|
50
50
|
"@better-auth-ui/react": "*",
|
|
51
51
|
"@gravity-ui/icons": ">=2.18.0",
|
|
52
|
-
"@heroui/react": ">=3.0.
|
|
53
|
-
"@heroui/styles": ">=3.0.
|
|
52
|
+
"@heroui/react": ">=3.0.4",
|
|
53
|
+
"@heroui/styles": ">=3.0.4",
|
|
54
54
|
"@internationalized/date": ">=3.12.1",
|
|
55
55
|
"@tanstack/react-pacer": ">=0.22.0",
|
|
56
|
-
"@tanstack/react-query": ">=5.100.
|
|
56
|
+
"@tanstack/react-query": ">=5.100.9",
|
|
57
57
|
"better-auth": ">=1.6.9",
|
|
58
|
-
"react": ">=19.2.
|
|
59
|
-
"react-dom": ">=19.2.
|
|
58
|
+
"react": ">=19.2.6",
|
|
59
|
+
"react-dom": ">=19.2.6",
|
|
60
60
|
"bowser": ">=2.11.0"
|
|
61
61
|
},
|
|
62
62
|
"repository": {
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { useAuth } from "@better-auth-ui/react"
|
|
2
2
|
import { type CardProps, cn } from "@heroui/react"
|
|
3
3
|
import type { ComponentProps } from "react"
|
|
4
|
+
|
|
4
5
|
import { DeleteUser } from "./delete-user"
|
|
5
|
-
|
|
6
|
+
|
|
7
|
+
export type DangerZoneProps = {
|
|
8
|
+
className?: string
|
|
6
9
|
variant?: CardProps["variant"]
|
|
7
10
|
}
|
|
8
11
|
|
|
@@ -10,12 +13,16 @@ export type DangerZoneProps = Omit<ComponentProps<"div">, "children"> & {
|
|
|
10
13
|
* Renders the danger zone heading and {@link DeleteUser}.
|
|
11
14
|
* Registered as a `securityCard` by `deleteUserPlugin()`; gate by registering the plugin.
|
|
12
15
|
*/
|
|
13
|
-
export function DangerZone({
|
|
16
|
+
export function DangerZone({
|
|
17
|
+
className,
|
|
18
|
+
variant,
|
|
19
|
+
...props
|
|
20
|
+
}: DangerZoneProps & ComponentProps<"div">) {
|
|
14
21
|
const { localization } = useAuth()
|
|
15
22
|
|
|
16
23
|
return (
|
|
17
24
|
<div className={cn("flex w-full flex-col", className)} {...props}>
|
|
18
|
-
<h2 className={cn("text-sm font-semibold mb-3")}>
|
|
25
|
+
<h2 className={cn("text-sm font-semibold mb-3 text-danger")}>
|
|
19
26
|
{localization.settings.dangerZone}
|
|
20
27
|
</h2>
|
|
21
28
|
|
|
@@ -11,7 +11,6 @@ import {
|
|
|
11
11
|
Button,
|
|
12
12
|
Card,
|
|
13
13
|
type CardProps,
|
|
14
|
-
cn,
|
|
15
14
|
FieldError,
|
|
16
15
|
Form,
|
|
17
16
|
Input,
|
|
@@ -91,11 +90,7 @@ export function DeleteUser({
|
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
return (
|
|
94
|
-
<Card
|
|
95
|
-
className={cn("border border-danger", className)}
|
|
96
|
-
variant={variant}
|
|
97
|
-
{...props}
|
|
98
|
-
>
|
|
93
|
+
<Card className={className} variant={variant} {...props}>
|
|
99
94
|
<Card.Content className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
|
|
100
95
|
<div>
|
|
101
96
|
<p className="text-sm font-medium leading-tight">
|
|
@@ -111,7 +106,7 @@ export function DeleteUser({
|
|
|
111
106
|
<Button
|
|
112
107
|
isDisabled={!accounts}
|
|
113
108
|
size="sm"
|
|
114
|
-
variant="danger"
|
|
109
|
+
variant="danger-soft"
|
|
115
110
|
onPress={() => setConfirmOpen(true)}
|
|
116
111
|
>
|
|
117
112
|
{deleteUserLocalization.deleteUser}
|
|
@@ -1,4 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
useAuth,
|
|
3
|
+
useFetchOptions,
|
|
4
|
+
useRequestPasswordReset
|
|
5
|
+
} from "@better-auth-ui/react"
|
|
2
6
|
import {
|
|
3
7
|
Button,
|
|
4
8
|
Card,
|
|
@@ -35,11 +39,18 @@ export function ForgotPassword({
|
|
|
35
39
|
variant,
|
|
36
40
|
...props
|
|
37
41
|
}: ForgotPasswordProps & Omit<CardProps, "children">) {
|
|
38
|
-
const { authClient, basePaths, localization, viewPaths, navigate } =
|
|
42
|
+
const { authClient, basePaths, localization, viewPaths, navigate, plugins } =
|
|
43
|
+
useAuth()
|
|
44
|
+
|
|
45
|
+
const { fetchOptions, resetFetchOptions } = useFetchOptions()
|
|
39
46
|
|
|
40
47
|
const { mutate: requestPasswordReset, isPending } = useRequestPasswordReset(
|
|
41
48
|
authClient,
|
|
42
49
|
{
|
|
50
|
+
onError: (error) => {
|
|
51
|
+
toast.danger(error.error?.message || error.message)
|
|
52
|
+
resetFetchOptions()
|
|
53
|
+
},
|
|
43
54
|
onSuccess: () => {
|
|
44
55
|
toast.success(localization.auth.passwordResetEmailSent)
|
|
45
56
|
navigate({ to: `${basePaths.auth}/${viewPaths.auth.signIn}` })
|
|
@@ -51,9 +62,16 @@ export function ForgotPassword({
|
|
|
51
62
|
e.preventDefault()
|
|
52
63
|
|
|
53
64
|
const formData = new FormData(e.currentTarget)
|
|
54
|
-
requestPasswordReset({
|
|
65
|
+
requestPasswordReset({
|
|
66
|
+
email: formData.get("email") as string,
|
|
67
|
+
fetchOptions
|
|
68
|
+
})
|
|
55
69
|
}
|
|
56
70
|
|
|
71
|
+
const Captcha = plugins.find(
|
|
72
|
+
(plugin) => plugin.captchaComponent
|
|
73
|
+
)?.captchaComponent
|
|
74
|
+
|
|
57
75
|
return (
|
|
58
76
|
<Card
|
|
59
77
|
className={cn("w-full max-w-sm gap-4 md:p-6", className)}
|
|
@@ -85,11 +103,15 @@ export function ForgotPassword({
|
|
|
85
103
|
<FieldError />
|
|
86
104
|
</TextField>
|
|
87
105
|
|
|
88
|
-
<
|
|
89
|
-
|
|
106
|
+
{Captcha && <div className="flex justify-center">{Captcha}</div>}
|
|
107
|
+
|
|
108
|
+
<div className="flex flex-col gap-3">
|
|
109
|
+
<Button type="submit" className="w-full" isPending={isPending}>
|
|
110
|
+
{isPending && <Spinner color="current" size="sm" />}
|
|
90
111
|
|
|
91
|
-
|
|
92
|
-
|
|
112
|
+
{localization.auth.sendResetLink}
|
|
113
|
+
</Button>
|
|
114
|
+
</div>
|
|
93
115
|
</Form>
|
|
94
116
|
</Card.Content>
|
|
95
117
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { authMutationKeys } from "@better-auth-ui/core"
|
|
2
2
|
import {
|
|
3
3
|
useAuth,
|
|
4
|
+
useFetchOptions,
|
|
4
5
|
useSendVerificationEmail,
|
|
5
6
|
useSignInEmail
|
|
6
7
|
} from "@better-auth-ui/react"
|
|
@@ -58,6 +59,8 @@ export function SignIn({
|
|
|
58
59
|
navigate
|
|
59
60
|
} = useAuth()
|
|
60
61
|
|
|
62
|
+
const { fetchOptions, resetFetchOptions } = useFetchOptions()
|
|
63
|
+
|
|
61
64
|
const [password, setPassword] = useState("")
|
|
62
65
|
|
|
63
66
|
const { mutate: sendVerificationEmail } = useSendVerificationEmail(
|
|
@@ -87,6 +90,8 @@ export function SignIn({
|
|
|
87
90
|
} else {
|
|
88
91
|
toast.danger(error.error?.message || error.message)
|
|
89
92
|
}
|
|
93
|
+
|
|
94
|
+
resetFetchOptions()
|
|
90
95
|
},
|
|
91
96
|
onSuccess: () => navigate({ to: redirectTo })
|
|
92
97
|
}
|
|
@@ -102,7 +107,8 @@ export function SignIn({
|
|
|
102
107
|
signInEmail({
|
|
103
108
|
email,
|
|
104
109
|
password,
|
|
105
|
-
...(emailAndPassword?.rememberMe ? { rememberMe } : {})
|
|
110
|
+
...(emailAndPassword?.rememberMe ? { rememberMe } : {}),
|
|
111
|
+
fetchOptions
|
|
106
112
|
})
|
|
107
113
|
}
|
|
108
114
|
|
|
@@ -114,6 +120,10 @@ export function SignIn({
|
|
|
114
120
|
})
|
|
115
121
|
const isPending = signInMutating + signUpMutating > 0
|
|
116
122
|
|
|
123
|
+
const Captcha = plugins.find(
|
|
124
|
+
(plugin) => plugin.captchaComponent
|
|
125
|
+
)?.captchaComponent
|
|
126
|
+
|
|
117
127
|
const showSeparator = emailAndPassword?.enabled && !!socialProviders?.length
|
|
118
128
|
|
|
119
129
|
return (
|
|
@@ -197,6 +207,8 @@ export function SignIn({
|
|
|
197
207
|
</Checkbox>
|
|
198
208
|
)}
|
|
199
209
|
|
|
210
|
+
{Captcha && <div className="flex justify-center">{Captcha}</div>}
|
|
211
|
+
|
|
200
212
|
<div className="flex flex-col gap-3">
|
|
201
213
|
<Button type="submit" className="w-full" isPending={isPending}>
|
|
202
214
|
{signInEmailPending && <Spinner color="current" size="sm" />}
|
|
@@ -2,7 +2,7 @@ import {
|
|
|
2
2
|
authMutationKeys,
|
|
3
3
|
parseAdditionalFieldValue
|
|
4
4
|
} from "@better-auth-ui/core"
|
|
5
|
-
import { useAuth, useSignUpEmail } from "@better-auth-ui/react"
|
|
5
|
+
import { useAuth, useFetchOptions, useSignUpEmail } from "@better-auth-ui/react"
|
|
6
6
|
import { Eye, EyeSlash } from "@gravity-ui/icons"
|
|
7
7
|
import {
|
|
8
8
|
Button,
|
|
@@ -63,6 +63,8 @@ export function SignUp({
|
|
|
63
63
|
navigate
|
|
64
64
|
} = useAuth()
|
|
65
65
|
|
|
66
|
+
const { fetchOptions, resetFetchOptions } = useFetchOptions()
|
|
67
|
+
|
|
66
68
|
const [password, setPassword] = useState("")
|
|
67
69
|
const [confirmPassword, setConfirmPassword] = useState("")
|
|
68
70
|
|
|
@@ -73,6 +75,7 @@ export function SignUp({
|
|
|
73
75
|
setPassword("")
|
|
74
76
|
setConfirmPassword("")
|
|
75
77
|
toast.danger(error.error?.message || error.message)
|
|
78
|
+
resetFetchOptions()
|
|
76
79
|
},
|
|
77
80
|
onSuccess: () => {
|
|
78
81
|
if (emailAndPassword?.requireEmailVerification) {
|
|
@@ -97,6 +100,10 @@ export function SignUp({
|
|
|
97
100
|
})
|
|
98
101
|
const isPending = signInMutating + signUpMutating > 0
|
|
99
102
|
|
|
103
|
+
const Captcha = plugins.find(
|
|
104
|
+
(plugin) => plugin.captchaComponent
|
|
105
|
+
)?.captchaComponent
|
|
106
|
+
|
|
100
107
|
const handleSubmit = async (e: SyntheticEvent<HTMLFormElement>) => {
|
|
101
108
|
e.preventDefault()
|
|
102
109
|
|
|
@@ -139,7 +146,8 @@ export function SignUp({
|
|
|
139
146
|
name,
|
|
140
147
|
email,
|
|
141
148
|
password,
|
|
142
|
-
...additionalFieldValues
|
|
149
|
+
...additionalFieldValues,
|
|
150
|
+
fetchOptions
|
|
143
151
|
})
|
|
144
152
|
}
|
|
145
153
|
|
|
@@ -323,6 +331,8 @@ export function SignUp({
|
|
|
323
331
|
)
|
|
324
332
|
)}
|
|
325
333
|
|
|
334
|
+
{Captcha && <div className="flex justify-center">{Captcha}</div>}
|
|
335
|
+
|
|
326
336
|
<div className="flex flex-col gap-3">
|
|
327
337
|
<Button type="submit" className="w-full" isPending={isPending}>
|
|
328
338
|
{signUpEmailPending && <Spinner color="current" size="sm" />}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useAuthPlugin } from "@better-auth-ui/react"
|
|
2
|
-
import { Display, Moon, Sun } from "@gravity-ui/icons"
|
|
2
|
+
import { Display, Moon, Palette, Sun } from "@gravity-ui/icons"
|
|
3
3
|
import { Dropdown, Label, Tabs } from "@heroui/react"
|
|
4
4
|
|
|
5
5
|
import { themePlugin } from "../../../lib/auth/theme-plugin"
|
|
@@ -67,6 +67,7 @@ export function ThemeToggleItem() {
|
|
|
67
67
|
// menu-item activation.
|
|
68
68
|
shouldCloseOnSelect={false}
|
|
69
69
|
>
|
|
70
|
+
<Palette className="text-muted" />
|
|
70
71
|
<Label>{localization.theme}</Label>
|
|
71
72
|
|
|
72
73
|
<Tabs
|