@better-auth-ui/heroui 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/account/account.d.ts +18 -0
- package/dist/components/account/account.js +24 -0
- package/dist/components/account/settings/account-settings.d.ts +5 -0
- package/dist/components/account/settings/account-settings.js +6 -0
- package/dist/components/account/settings/settings.d.ts +5 -0
- package/dist/components/account/settings/settings.js +5 -0
- package/dist/components/account/settings/user-profile.d.ts +5 -0
- package/dist/components/account/settings/user-profile.js +20 -0
- package/dist/components/auth/auth-provider.d.ts +9 -0
- package/dist/components/auth/auth-provider.js +12 -0
- package/dist/components/auth/auth.d.ts +23 -0
- package/dist/components/auth/auth.js +42 -0
- package/dist/components/auth/field-separator.d.ts +4 -0
- package/dist/components/auth/field-separator.js +5 -0
- package/dist/components/auth/forgot-password.d.ts +15 -0
- package/dist/components/auth/forgot-password.js +28 -0
- package/dist/components/auth/magic-link-button.d.ts +13 -0
- package/dist/components/auth/magic-link-button.js +19 -0
- package/dist/components/auth/magic-link.d.ts +17 -0
- package/dist/components/auth/magic-link.js +43 -0
- package/dist/components/auth/provider-buttons.d.ts +19 -0
- package/dist/components/auth/provider-buttons.js +34 -0
- package/dist/components/auth/reset-password.d.ts +11 -0
- package/dist/components/auth/reset-password.js +58 -0
- package/dist/components/auth/sign-in.d.ts +14 -0
- package/dist/components/auth/sign-in.js +64 -0
- package/dist/components/auth/sign-out.d.ts +9 -0
- package/dist/components/auth/sign-out.js +33 -0
- package/dist/components/auth/sign-up.d.ts +19 -0
- package/dist/components/auth/sign-up.js +71 -0
- package/dist/components/email/email-changed-email.d.ts +3 -0
- package/dist/components/email/email-changed-email.js +23 -0
- package/dist/components/email/email-verification-email.d.ts +3 -0
- package/dist/components/email/email-verification-email.js +23 -0
- package/dist/components/email/magic-link-email.d.ts +3 -0
- package/dist/components/email/magic-link-email.js +23 -0
- package/dist/components/email/new-device-email.d.ts +3 -0
- package/dist/components/email/new-device-email.js +23 -0
- package/dist/components/email/otp-email.d.ts +3 -0
- package/dist/components/email/otp-email.js +22 -0
- package/dist/components/email/password-changed-email.d.ts +3 -0
- package/dist/components/email/password-changed-email.js +23 -0
- package/dist/components/email/reset-password-email.d.ts +3 -0
- package/dist/components/email/reset-password-email.js +23 -0
- package/dist/components/settings/account/account-settings.d.ts +16 -0
- package/dist/components/settings/account/account-settings.js +20 -0
- package/dist/components/settings/account/accounts.d.ts +14 -0
- package/dist/components/settings/account/accounts.js +26 -0
- package/dist/components/settings/account/appearance.d.ts +16 -0
- package/dist/components/settings/account/appearance.js +28 -0
- package/dist/components/settings/account/change-avatar.d.ts +4 -0
- package/dist/components/settings/account/change-avatar.js +56 -0
- package/dist/components/settings/account/change-email.d.ts +15 -0
- package/dist/components/settings/account/change-email.js +29 -0
- package/dist/components/settings/account/manage-account.d.ts +19 -0
- package/dist/components/settings/account/manage-account.js +32 -0
- package/dist/components/settings/account/manage-accounts.d.ts +14 -0
- package/dist/components/settings/account/manage-accounts.js +37 -0
- package/dist/components/settings/account/theme-selector.d.ts +16 -0
- package/dist/components/settings/account/theme-selector.js +33 -0
- package/dist/components/settings/account/theme-settings.d.ts +16 -0
- package/dist/components/settings/account/theme-settings.js +31 -0
- package/dist/components/settings/account/user-profile.d.ts +11 -0
- package/dist/components/settings/account/user-profile.js +23 -0
- package/dist/components/settings/account-settings.d.ts +5 -0
- package/dist/components/settings/account-settings.js +6 -0
- package/dist/components/settings/account.d.ts +18 -0
- package/dist/components/settings/account.js +24 -0
- package/dist/components/settings/security/active-session.d.ts +14 -0
- package/dist/components/settings/security/active-session.js +53 -0
- package/dist/components/settings/security/active-sessions.d.ts +14 -0
- package/dist/components/settings/security/active-sessions.js +28 -0
- package/dist/components/settings/security/change-password.d.ts +15 -0
- package/dist/components/settings/security/change-password.js +79 -0
- package/dist/components/settings/security/connected-account.d.ts +16 -0
- package/dist/components/settings/security/connected-account.js +46 -0
- package/dist/components/settings/security/connected-accounts.d.ts +15 -0
- package/dist/components/settings/security/connected-accounts.js +31 -0
- package/dist/components/settings/security/danger-zone.d.ts +11 -0
- package/dist/components/settings/security/danger-zone.js +12 -0
- package/dist/components/settings/security/delete-user.d.ts +9 -0
- package/dist/components/settings/security/delete-user.js +47 -0
- package/dist/components/settings/security/linked-account.d.ts +16 -0
- package/dist/components/settings/security/linked-account.js +48 -0
- package/dist/components/settings/security/linked-accounts.d.ts +15 -0
- package/dist/components/settings/security/linked-accounts.js +42 -0
- package/dist/components/settings/security/security-settings.d.ts +17 -0
- package/dist/components/settings/security/security-settings.js +21 -0
- package/dist/components/settings/security/sessions.d.ts +14 -0
- package/dist/components/settings/security/sessions.js +40 -0
- package/dist/components/settings/settings/account-settings.d.ts +5 -0
- package/dist/components/settings/settings/account-settings.js +6 -0
- package/dist/components/settings/settings/user-profile.d.ts +5 -0
- package/dist/components/settings/settings/user-profile.js +20 -0
- package/dist/components/settings/settings.d.ts +24 -0
- package/dist/components/settings/settings.js +28 -0
- package/dist/components/settings/user-profile.d.ts +5 -0
- package/dist/components/settings/user-profile.js +20 -0
- package/dist/components/user/switch-account-item.d.ts +16 -0
- package/dist/components/user/switch-account-item.js +16 -0
- package/dist/components/user/switch-account-menu.d.ts +10 -0
- package/dist/components/user/switch-account-menu.js +29 -0
- package/dist/components/user/switch-account-popover.d.ts +10 -0
- package/dist/components/user/switch-account-popover.js +25 -0
- package/dist/components/user/switch-account-submenu.d.ts +10 -0
- package/dist/components/user/switch-account-submenu.js +25 -0
- package/dist/components/user/user-avatar.d.ts +25 -0
- package/dist/components/user/user-avatar.js +31 -0
- package/dist/components/user/user-button.d.ts +25 -0
- package/dist/components/user/user-button.js +24 -0
- package/dist/components/user/user-view.d.ts +22 -0
- package/dist/components/user/user-view.js +24 -0
- package/dist/core.d.ts +1 -0
- package/dist/core.js +1 -0
- package/dist/hooks/use-auth.d.ts +2 -0
- package/dist/hooks/use-auth.js +8 -0
- package/dist/hooks/use-redirect-to.d.ts +8 -0
- package/dist/hooks/use-redirect-to.js +19 -0
- package/dist/hooks/use-sign-in.d.ts +8 -0
- package/dist/hooks/use-sign-in.js +53 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +34 -0
- package/dist/lib/utils.d.ts +2 -0
- package/dist/lib/utils.js +5 -0
- package/dist/react-exports.d.ts +1 -0
- package/dist/react-exports.js +1 -0
- package/dist/server.d.ts +1 -0
- package/dist/server.js +1 -0
- package/dist/src/components/auth/auth-provider.d.ts +8 -0
- package/dist/src/components/auth/auth-provider.js +13 -0
- package/dist/src/components/auth/auth.d.ts +22 -0
- package/dist/src/components/auth/auth.js +42 -0
- package/dist/src/components/auth/field-separator.d.ts +4 -0
- package/dist/src/components/auth/field-separator.js +5 -0
- package/dist/src/components/auth/forgot-password.d.ts +15 -0
- package/dist/src/components/auth/forgot-password.js +29 -0
- package/dist/src/components/auth/magic-link-button.d.ts +13 -0
- package/dist/src/components/auth/magic-link-button.js +20 -0
- package/dist/src/components/auth/magic-link.d.ts +17 -0
- package/dist/src/components/auth/magic-link.js +37 -0
- package/dist/src/components/auth/provider-buttons.d.ts +19 -0
- package/dist/src/components/auth/provider-buttons.js +35 -0
- package/dist/src/components/auth/reset-password.d.ts +11 -0
- package/dist/src/components/auth/reset-password.js +59 -0
- package/dist/src/components/auth/sign-in.d.ts +14 -0
- package/dist/src/components/auth/sign-in.js +58 -0
- package/dist/src/components/auth/sign-out.d.ts +11 -0
- package/dist/src/components/auth/sign-out.js +34 -0
- package/dist/src/components/auth/sign-up.d.ts +19 -0
- package/dist/src/components/auth/sign-up.js +65 -0
- package/dist/src/components/email/email-changed-email.d.ts +3 -0
- package/dist/src/components/email/email-changed-email.js +23 -0
- package/dist/src/components/email/email-verification-email.d.ts +3 -0
- package/dist/src/components/email/email-verification-email.js +23 -0
- package/dist/src/components/email/magic-link-email.d.ts +3 -0
- package/dist/src/components/email/magic-link-email.js +23 -0
- package/dist/src/components/email/new-device-email.d.ts +3 -0
- package/dist/src/components/email/new-device-email.js +23 -0
- package/dist/src/components/email/otp-email.d.ts +3 -0
- package/dist/src/components/email/otp-email.js +22 -0
- package/dist/src/components/email/password-changed-email.d.ts +3 -0
- package/dist/src/components/email/password-changed-email.js +23 -0
- package/dist/src/components/email/reset-password-email.d.ts +3 -0
- package/dist/src/components/email/reset-password-email.js +23 -0
- package/dist/src/components/settings/account/account-settings.d.ts +13 -0
- package/dist/src/components/settings/account/account-settings.js +19 -0
- package/dist/src/components/settings/account/appearance.d.ts +16 -0
- package/dist/src/components/settings/account/appearance.js +28 -0
- package/dist/src/components/settings/account/change-email.d.ts +15 -0
- package/dist/src/components/settings/account/change-email.js +35 -0
- package/dist/src/components/settings/account/manage-account.d.ts +19 -0
- package/dist/src/components/settings/account/manage-account.js +27 -0
- package/dist/src/components/settings/account/manage-accounts.d.ts +14 -0
- package/dist/src/components/settings/account/manage-accounts.js +27 -0
- package/dist/src/components/settings/account/user-profile.d.ts +13 -0
- package/dist/src/components/settings/account/user-profile.js +29 -0
- package/dist/src/components/settings/security/active-session.d.ts +14 -0
- package/dist/src/components/settings/security/active-session.js +35 -0
- package/dist/src/components/settings/security/active-sessions.d.ts +14 -0
- package/dist/src/components/settings/security/active-sessions.js +29 -0
- package/dist/src/components/settings/security/change-password.d.ts +15 -0
- package/dist/src/components/settings/security/change-password.js +57 -0
- package/dist/src/components/settings/security/linked-account.d.ts +16 -0
- package/dist/src/components/settings/security/linked-account.js +46 -0
- package/dist/src/components/settings/security/linked-accounts.d.ts +15 -0
- package/dist/src/components/settings/security/linked-accounts.js +31 -0
- package/dist/src/components/settings/security/security-settings.d.ts +15 -0
- package/dist/src/components/settings/security/security-settings.js +18 -0
- package/dist/src/components/settings/settings.d.ts +29 -0
- package/dist/src/components/settings/settings.js +39 -0
- package/dist/src/components/user/switch-account-item.d.ts +16 -0
- package/dist/src/components/user/switch-account-item.js +14 -0
- package/dist/src/components/user/switch-account-menu.d.ts +10 -0
- package/dist/src/components/user/switch-account-menu.js +23 -0
- package/dist/src/components/user/user-avatar.d.ts +24 -0
- package/dist/src/components/user/user-avatar.js +31 -0
- package/dist/src/components/user/user-button.d.ts +21 -0
- package/dist/src/components/user/user-button.js +24 -0
- package/dist/src/components/user/user-view.d.ts +21 -0
- package/dist/src/components/user/user-view.js +24 -0
- package/dist/src/core.d.ts +1 -0
- package/dist/src/core.js +1 -0
- package/dist/src/index.d.ts +31 -0
- package/dist/src/index.js +32 -0
- package/dist/src/lib/utils.d.ts +2 -0
- package/dist/src/lib/utils.js +5 -0
- package/dist/src/react-exports.d.ts +1 -0
- package/dist/src/react-exports.js +1 -0
- package/dist/styles.css +1 -0
- package/package.json +63 -0
- package/src/components/auth/auth-provider.tsx +27 -0
- package/src/components/auth/auth.tsx +87 -0
- package/src/components/auth/field-separator.tsx +14 -0
- package/src/components/auth/forgot-password.tsx +107 -0
- package/src/components/auth/magic-link-button.tsx +43 -0
- package/src/components/auth/magic-link.tsx +181 -0
- package/src/components/auth/provider-buttons.tsx +85 -0
- package/src/components/auth/reset-password.tsx +210 -0
- package/src/components/auth/sign-in.tsx +260 -0
- package/src/components/auth/sign-out.tsx +44 -0
- package/src/components/auth/sign-up.tsx +314 -0
- package/src/components/email/email-changed-email.tsx +38 -0
- package/src/components/email/email-verification-email.tsx +38 -0
- package/src/components/email/magic-link-email.tsx +38 -0
- package/src/components/email/new-device-email.tsx +38 -0
- package/src/components/email/otp-email.tsx +33 -0
- package/src/components/email/password-changed-email.tsx +38 -0
- package/src/components/email/reset-password-email.tsx +38 -0
- package/src/components/settings/account/account-settings.tsx +48 -0
- package/src/components/settings/account/appearance.tsx +157 -0
- package/src/components/settings/account/change-avatar.tsx +142 -0
- package/src/components/settings/account/change-email.tsx +111 -0
- package/src/components/settings/account/manage-account.tsx +123 -0
- package/src/components/settings/account/manage-accounts.tsx +78 -0
- package/src/components/settings/account/user-profile.tsx +103 -0
- package/src/components/settings/security/active-session.tsx +123 -0
- package/src/components/settings/security/active-sessions.tsx +77 -0
- package/src/components/settings/security/change-password.tsx +335 -0
- package/src/components/settings/security/danger-zone.tsx +32 -0
- package/src/components/settings/security/delete-user.tsx +187 -0
- package/src/components/settings/security/linked-account.tsx +136 -0
- package/src/components/settings/security/linked-accounts.tsx +98 -0
- package/src/components/settings/security/security-settings.tsx +43 -0
- package/src/components/settings/settings.tsx +96 -0
- package/src/components/user/switch-account-item.tsx +39 -0
- package/src/components/user/switch-account-menu.tsx +64 -0
- package/src/components/user/user-avatar.tsx +88 -0
- package/src/components/user/user-button.tsx +221 -0
- package/src/components/user/user-view.tsx +74 -0
- package/src/core.ts +1 -0
- package/src/index.tsx +35 -0
- package/src/react-exports.ts +1 -0
- package/src/styles.css +1 -0
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth, useSignInMagicLink, useSignInSocial } from "@better-auth-ui/react";
|
|
3
|
+
import { Button, Card, Description, FieldError, Fieldset, Form, Input, Label, Link, Spinner, TextField, toast } from "@heroui/react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
import { FieldSeparator } from "./field-separator";
|
|
7
|
+
import { MagicLinkButton } from "./magic-link-button";
|
|
8
|
+
import { ProviderButtons } from "./provider-buttons";
|
|
9
|
+
/**
|
|
10
|
+
* Render a card-based sign-in form that sends an email magic link and optionally shows social provider buttons.
|
|
11
|
+
*
|
|
12
|
+
* @param className - Additional CSS class names applied to the card container
|
|
13
|
+
* @param socialLayout - Layout style for social provider buttons
|
|
14
|
+
* @param socialPosition - Position of social provider buttons; `"top"` or `"bottom"`. Defaults to `"bottom"`.
|
|
15
|
+
* @returns The magic-link sign-in UI as a JSX element
|
|
16
|
+
*/
|
|
17
|
+
export function MagicLink({ className, socialLayout, socialPosition = "bottom", variant, ...props }) {
|
|
18
|
+
const { basePaths, baseURL, localization, redirectTo, socialProviders, viewPaths } = useAuth();
|
|
19
|
+
const [email, setEmail] = useState("");
|
|
20
|
+
const { mutate: signInMagicLink, isPending: magicLinkPending } = useSignInMagicLink({
|
|
21
|
+
onError: (error) => toast.danger(error.error?.message || error.message),
|
|
22
|
+
onSuccess: () => {
|
|
23
|
+
setEmail("");
|
|
24
|
+
toast.success(localization.auth.magicLinkSent);
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const { mutate: signInSocial, isPending: socialPending } = useSignInSocial({
|
|
28
|
+
onError: (error) => toast.danger(error.error?.message || error.message)
|
|
29
|
+
});
|
|
30
|
+
const isPending = magicLinkPending || socialPending;
|
|
31
|
+
const handleSubmit = (e) => {
|
|
32
|
+
e.preventDefault();
|
|
33
|
+
signInMagicLink({ email, callbackURL: `${baseURL}${redirectTo}` });
|
|
34
|
+
};
|
|
35
|
+
const showSeparator = socialProviders && socialProviders.length > 0;
|
|
36
|
+
return (_jsx(Card, { className: cn("w-full max-w-sm p-4 md:p-6", className), variant: variant, ...props, children: _jsx(Card.Content, { children: _jsxs(Fieldset, { className: "gap-4", children: [_jsx(Label, { className: "text-xl", children: localization.auth.signIn }), socialPosition === "top" && (_jsxs(_Fragment, { children: [socialProviders && socialProviders.length > 0 && (_jsx(ProviderButtons, { socialLayout: socialLayout, signInSocial: signInSocial, isPending: isPending })), showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or }))] })), _jsxs(Form, { onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsx(Fieldset.Group, { children: _jsxs(TextField, { name: "email", type: "email", autoComplete: "email", isDisabled: isPending, value: email, onChange: setEmail, children: [_jsx(Label, { children: localization.auth.email }), _jsx(Input, { placeholder: localization.auth.emailPlaceholder, required: true, variant: variant === "transparent" ? "primary" : "secondary" }), _jsx(FieldError, { className: "text-wrap" })] }) }), _jsxs(Fieldset.Actions, { className: "flex-col gap-3", children: [_jsxs(Button, { type: "submit", className: "w-full", isPending: isPending, children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.auth.sendMagicLink] }), _jsx(MagicLinkButton, { view: "magicLink", isPending: isPending })] })] }), socialPosition === "bottom" && (_jsxs(_Fragment, { children: [showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or })), socialProviders && socialProviders.length > 0 && (_jsx(ProviderButtons, { socialLayout: socialLayout, signInSocial: signInSocial, isPending: isPending }))] })), _jsxs(Description, { className: "text-center text-sm", children: [localization.auth.needToCreateAnAccount, " ", _jsx(Link, { href: `${basePaths.auth}/${viewPaths.auth.signUp}`, className: "text-accent decoration-accent no-underline hover:underline", children: localization.auth.signUp })] })] }) }) }));
|
|
37
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { SocialProvider } from "better-auth/social-providers";
|
|
2
|
+
export type ProviderButtonsProps = {
|
|
3
|
+
isPending: boolean;
|
|
4
|
+
socialLayout?: SocialLayout;
|
|
5
|
+
signInSocial: (params: {
|
|
6
|
+
provider: SocialProvider;
|
|
7
|
+
callbackURL: string;
|
|
8
|
+
}) => void;
|
|
9
|
+
};
|
|
10
|
+
export type SocialLayout = "auto" | "horizontal" | "vertical" | "grid";
|
|
11
|
+
/**
|
|
12
|
+
* Render social provider sign-in buttons and handle initiation and pending state.
|
|
13
|
+
*
|
|
14
|
+
* @param isPending - Disables all provider buttons when true.
|
|
15
|
+
* @param socialLayout - Preferred layout for the buttons; `"auto"` picks `"horizontal"` when there are four or more providers, otherwise `"vertical"`.
|
|
16
|
+
* @param signInSocial - Callback invoked with the provider and callbackURL when a button is clicked.
|
|
17
|
+
* @returns The JSX element that renders the configured social provider buttons.
|
|
18
|
+
*/
|
|
19
|
+
export declare function ProviderButtons({ isPending, socialLayout, signInSocial }: ProviderButtonsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { getProviderName } from "@better-auth-ui/core";
|
|
3
|
+
import { providerIcons, useAuth } from "@better-auth-ui/react";
|
|
4
|
+
import { Button } from "@heroui/react";
|
|
5
|
+
import { useMemo } from "react";
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
/**
|
|
8
|
+
* Render social provider sign-in buttons and handle initiation and pending state.
|
|
9
|
+
*
|
|
10
|
+
* @param isPending - Disables all provider buttons when true.
|
|
11
|
+
* @param socialLayout - Preferred layout for the buttons; `"auto"` picks `"horizontal"` when there are four or more providers, otherwise `"vertical"`.
|
|
12
|
+
* @param signInSocial - Callback invoked with the provider and callbackURL when a button is clicked.
|
|
13
|
+
* @returns The JSX element that renders the configured social provider buttons.
|
|
14
|
+
*/
|
|
15
|
+
export function ProviderButtons({ isPending, socialLayout = "auto", signInSocial }) {
|
|
16
|
+
const { baseURL, localization, redirectTo, socialProviders } = useAuth();
|
|
17
|
+
const callbackURL = `${baseURL}${redirectTo}`;
|
|
18
|
+
const resolvedSocialLayout = useMemo(() => {
|
|
19
|
+
if (socialLayout === "auto") {
|
|
20
|
+
if (socialProviders?.length && socialProviders.length >= 4) {
|
|
21
|
+
return "horizontal";
|
|
22
|
+
}
|
|
23
|
+
return "vertical";
|
|
24
|
+
}
|
|
25
|
+
return socialLayout;
|
|
26
|
+
}, [socialLayout, socialProviders?.length]);
|
|
27
|
+
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) => {
|
|
28
|
+
const ProviderIcon = providerIcons[provider];
|
|
29
|
+
return (_jsxs(Button, { className: cn("w-full", resolvedSocialLayout === "horizontal" && "flex-1"), variant: "tertiary", isPending: isPending, onPress: () => signInSocial({ provider, callbackURL }), children: [_jsx(ProviderIcon, {}), resolvedSocialLayout === "vertical"
|
|
30
|
+
? localization.auth.continueWith.replace("{{provider}}", getProviderName(provider))
|
|
31
|
+
: resolvedSocialLayout === "grid"
|
|
32
|
+
? getProviderName(provider)
|
|
33
|
+
: null] }, provider));
|
|
34
|
+
}) }));
|
|
35
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type CardProps } from "@heroui/react";
|
|
2
|
+
export type ResetPasswordProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
variant?: CardProps["variant"];
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Renders a reset password form that verifies a "token" URL parameter on mount and redirects to sign-in if absent.
|
|
8
|
+
*
|
|
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
|
+
*/
|
|
11
|
+
export declare function ResetPassword({ className, variant, ...props }: ResetPasswordProps & CardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth, useResetPassword } from "@better-auth-ui/react";
|
|
3
|
+
import { Eye, EyeSlash } from "@gravity-ui/icons";
|
|
4
|
+
import { Button, Card, Description, FieldError, Fieldset, Form, InputGroup, Label, Link, Spinner, TextField, toast } from "@heroui/react";
|
|
5
|
+
import { useEffect, useState } from "react";
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
/**
|
|
8
|
+
* Renders a reset password form that verifies a "token" URL parameter on mount and redirects to sign-in if absent.
|
|
9
|
+
*
|
|
10
|
+
* 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.
|
|
11
|
+
*/
|
|
12
|
+
export function ResetPassword({ className, variant, ...props }) {
|
|
13
|
+
const { basePaths, emailAndPassword, localization, viewPaths, navigate } = useAuth();
|
|
14
|
+
const { mutate: resetPassword, isPending } = useResetPassword({
|
|
15
|
+
onError: (error) => toast.danger(error.error?.message || error.message),
|
|
16
|
+
onSuccess: () => {
|
|
17
|
+
toast.success(localization.auth.passwordResetSuccess);
|
|
18
|
+
navigate({ to: `${basePaths.auth}/${viewPaths.auth.signIn}` });
|
|
19
|
+
}
|
|
20
|
+
});
|
|
21
|
+
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
|
22
|
+
const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] = useState(false);
|
|
23
|
+
useEffect(() => {
|
|
24
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
25
|
+
const token = searchParams.get("token");
|
|
26
|
+
if (!token) {
|
|
27
|
+
toast.danger(localization.auth.invalidResetPasswordToken);
|
|
28
|
+
navigate({ to: `${basePaths.auth}/${viewPaths.auth.signIn}` });
|
|
29
|
+
}
|
|
30
|
+
}, [
|
|
31
|
+
basePaths.auth,
|
|
32
|
+
localization.auth.invalidResetPasswordToken,
|
|
33
|
+
viewPaths.auth.signIn,
|
|
34
|
+
navigate
|
|
35
|
+
]);
|
|
36
|
+
function handleSubmit(e) {
|
|
37
|
+
e.preventDefault();
|
|
38
|
+
const searchParams = new URLSearchParams(window.location.search);
|
|
39
|
+
const token = searchParams.get("token");
|
|
40
|
+
if (!token) {
|
|
41
|
+
toast.danger(localization.auth.invalidResetPasswordToken);
|
|
42
|
+
navigate({ to: `${basePaths.auth}/${viewPaths.auth.signIn}` });
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const formData = new FormData(e.currentTarget);
|
|
46
|
+
const password = formData.get("password");
|
|
47
|
+
const confirmPassword = formData.get("confirmPassword");
|
|
48
|
+
if (emailAndPassword?.confirmPassword && password !== confirmPassword) {
|
|
49
|
+
toast.danger(localization.auth.passwordsDoNotMatch);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
resetPassword({ token, newPassword: password });
|
|
53
|
+
}
|
|
54
|
+
return (_jsx(Card, { className: cn("w-full max-w-sm p-4 md:p-6", className), variant: variant, ...props, children: _jsx(Card.Content, { children: _jsx(Form, { onSubmit: handleSubmit, children: _jsxs(Fieldset, { className: "gap-4", children: [_jsx(Label, { className: "text-xl", children: localization.auth.resetPassword }), _jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, name: "password", autoComplete: "new-password", isDisabled: isPending, children: [_jsx(Label, { children: localization.auth.password }), _jsxs(InputGroup, { variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(InputGroup.Input, { name: "password", placeholder: localization.auth.newPasswordPlaceholder, type: isPasswordVisible ? "text" : "password", required: true }), _jsx(InputGroup.Suffix, { className: "px-0", children: _jsx(Button, { isIconOnly: true, "aria-label": isPasswordVisible
|
|
55
|
+
? localization.auth.hidePassword
|
|
56
|
+
: localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsPasswordVisible(!isPasswordVisible), isDisabled: isPending, children: isPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] }), _jsx(FieldError, { className: "text-wrap" })] }), emailAndPassword?.confirmPassword && (_jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, name: "confirmPassword", autoComplete: "new-password", isDisabled: isPending, children: [_jsx(Label, { children: localization.auth.confirmPassword }), _jsxs(InputGroup, { variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(InputGroup.Input, { placeholder: localization.auth.confirmPasswordPlaceholder, type: isConfirmPasswordVisible ? "text" : "password", required: true, name: "confirmPassword" }), _jsx(InputGroup.Suffix, { className: "px-0", children: _jsx(Button, { isIconOnly: true, "aria-label": isConfirmPasswordVisible
|
|
57
|
+
? localization.auth.hidePassword
|
|
58
|
+
: localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsConfirmPasswordVisible(!isConfirmPasswordVisible), isDisabled: isPending, children: isConfirmPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] }), _jsx(FieldError, { className: "text-wrap" })] })), _jsx(Fieldset.Actions, { children: _jsxs(Button, { type: "submit", className: "w-full", isPending: isPending, children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.auth.resetPassword] }) }), _jsxs(Description, { className: "text-center text-sm", children: [localization.auth.rememberYourPassword, " ", _jsx(Link, { href: `${basePaths.auth}/${viewPaths.auth.signIn}`, className: "text-accent decoration-accent no-underline hover:underline", children: localization.auth.signIn })] })] }) }) }) }));
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CardProps } from "@heroui/react";
|
|
2
|
+
import { type SocialLayout } from "./provider-buttons";
|
|
3
|
+
export interface SignInProps {
|
|
4
|
+
className?: string;
|
|
5
|
+
socialLayout?: SocialLayout;
|
|
6
|
+
socialPosition?: "top" | "bottom";
|
|
7
|
+
variant?: CardProps["variant"];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Render the sign-in UI using auth context for configuration and localization.
|
|
11
|
+
*
|
|
12
|
+
* @returns The sign-in JSX element containing email/password fields, optional magic-link button, and social provider buttons.
|
|
13
|
+
*/
|
|
14
|
+
export declare function SignIn({ className, socialLayout, socialPosition, variant, ...props }: SignInProps & CardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth, useSendVerificationEmail, useSignInEmail, useSignInSocial } from "@better-auth-ui/react";
|
|
3
|
+
import { Button, Card, Checkbox, Description, FieldError, Form, Input, Label, Link, Spinner, TextField, toast } from "@heroui/react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
import { FieldSeparator } from "./field-separator";
|
|
7
|
+
import { MagicLinkButton } from "./magic-link-button";
|
|
8
|
+
import { ProviderButtons } from "./provider-buttons";
|
|
9
|
+
/**
|
|
10
|
+
* Render the sign-in UI using auth context for configuration and localization.
|
|
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, navigate, redirectTo, socialProviders, viewPaths } = 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 { mutate: signInSocial, isPending: socialPending } = useSignInSocial({
|
|
42
|
+
onError: (error) => toast.danger(error.error?.message || error.message)
|
|
43
|
+
});
|
|
44
|
+
const handleSubmit = (e) => {
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
const formData = new FormData(e.currentTarget);
|
|
47
|
+
const email = formData.get("email");
|
|
48
|
+
const rememberMe = formData.get("rememberMe") === "on";
|
|
49
|
+
signInEmail({
|
|
50
|
+
email,
|
|
51
|
+
password,
|
|
52
|
+
...(emailAndPassword?.rememberMe ? { rememberMe } : {})
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
const isPending = signInPending || socialPending;
|
|
56
|
+
const showSeparator = emailAndPassword?.enabled && socialProviders && socialProviders.length > 0;
|
|
57
|
+
return (_jsxs(Card, { className: cn("w-full max-w-sm p-4 md:p-6 gap-4", className), variant: variant, ...props, children: [_jsx(Card.Header, { children: _jsx(Card.Title, { className: "text-xl", children: localization.auth.signIn }) }), _jsxs(Card.Content, { className: "gap-4", children: [socialPosition === "top" && (_jsxs(_Fragment, { children: [socialProviders && socialProviders.length > 0 && (_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, { className: "text-wrap" })] }), _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, { className: "text-wrap" })] }), 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 }))] })] })), socialPosition === "bottom" && (_jsxs(_Fragment, { children: [showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or })), socialProviders && socialProviders.length > 0 && (_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 self-center", children: localization.auth.forgotPasswordLink })), emailAndPassword?.enabled && (_jsxs(Description, { className: "justify-center 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 })] }))] })] }));
|
|
58
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type CardProps } from "@heroui/react";
|
|
2
|
+
export type SignOutProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
variant?: CardProps["variant"];
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Initiates sign-out on mount and renders a loading card while sign-out proceeds.
|
|
8
|
+
*
|
|
9
|
+
* @returns A Card containing a centered Spinner shown during the sign-out process
|
|
10
|
+
*/
|
|
11
|
+
export declare function SignOut({ className, ...props }: SignOutProps & CardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth, useSignOut } from "@better-auth-ui/react";
|
|
3
|
+
import { Card, Spinner, toast } from "@heroui/react";
|
|
4
|
+
import { useEffect, useRef } from "react";
|
|
5
|
+
import { cn } from "../../lib/utils";
|
|
6
|
+
/**
|
|
7
|
+
* Initiates sign-out on mount and renders a loading card while sign-out proceeds.
|
|
8
|
+
*
|
|
9
|
+
* @returns A Card containing a centered Spinner shown during the sign-out process
|
|
10
|
+
*/
|
|
11
|
+
export function SignOut({ className, ...props }) {
|
|
12
|
+
const { basePaths, navigate, viewPaths } = useAuth();
|
|
13
|
+
const { mutate: signOut } = useSignOut({
|
|
14
|
+
onError: (error) => {
|
|
15
|
+
toast.danger(error.error?.message || error.message);
|
|
16
|
+
navigate({
|
|
17
|
+
to: `${basePaths.auth}/${viewPaths.auth.signIn}`,
|
|
18
|
+
replace: true
|
|
19
|
+
});
|
|
20
|
+
},
|
|
21
|
+
onSuccess: () => navigate({
|
|
22
|
+
to: `${basePaths.auth}/${viewPaths.auth.signIn}`,
|
|
23
|
+
replace: true
|
|
24
|
+
})
|
|
25
|
+
});
|
|
26
|
+
const hasSignedOut = useRef(false);
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
if (hasSignedOut.current)
|
|
29
|
+
return;
|
|
30
|
+
hasSignedOut.current = true;
|
|
31
|
+
signOut();
|
|
32
|
+
}, [signOut]);
|
|
33
|
+
return (_jsx(Card, { variant: "transparent", className: cn("w-full max-w-sm", className), ...props, children: _jsx(Spinner, { className: "mx-auto my-auto", color: "current" }) }));
|
|
34
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type CardProps } from "@heroui/react";
|
|
2
|
+
import { type SocialLayout } from "./provider-buttons";
|
|
3
|
+
export type SignUpProps = {
|
|
4
|
+
className?: string;
|
|
5
|
+
socialLayout?: SocialLayout;
|
|
6
|
+
socialPosition?: "top" | "bottom";
|
|
7
|
+
variant?: CardProps["variant"];
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Render a sign-up form with name, email, password (and optional confirm password) fields, optional social provider buttons, and password visibility controls.
|
|
11
|
+
*
|
|
12
|
+
* The component reflects request state by disabling inputs and showing a pending indicator during sign-up or social sign-in.
|
|
13
|
+
*
|
|
14
|
+
* @param className - Additional CSS classes applied to the outer card container
|
|
15
|
+
* @param socialLayout - Social layout to apply to the provider buttons component
|
|
16
|
+
* @param socialPosition - Position of social provider buttons relative to the form; `"top"` or `"bottom"` (default `"bottom"`)
|
|
17
|
+
* @returns The sign-up form React element
|
|
18
|
+
*/
|
|
19
|
+
export declare function SignUp({ className, socialLayout, socialPosition, variant, ...props }: SignUpProps & CardProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useAuth, useSignInSocial, useSignUpEmail } from "@better-auth-ui/react";
|
|
3
|
+
import { Eye, EyeSlash } from "@gravity-ui/icons";
|
|
4
|
+
import { Button, Card, Description, FieldError, Fieldset, Form, Input, InputGroup, Label, Link, Spinner, TextField, toast } from "@heroui/react";
|
|
5
|
+
import { useState } from "react";
|
|
6
|
+
import { cn } from "../../lib/utils";
|
|
7
|
+
import { FieldSeparator } from "./field-separator";
|
|
8
|
+
import { MagicLinkButton } from "./magic-link-button";
|
|
9
|
+
import { ProviderButtons } from "./provider-buttons";
|
|
10
|
+
/**
|
|
11
|
+
* Render a sign-up form with name, email, password (and optional confirm password) fields, optional social provider buttons, and password visibility controls.
|
|
12
|
+
*
|
|
13
|
+
* The component reflects request state by disabling inputs and showing a pending indicator during sign-up or social sign-in.
|
|
14
|
+
*
|
|
15
|
+
* @param className - Additional CSS classes applied to the outer card container
|
|
16
|
+
* @param socialLayout - Social layout to apply to the provider buttons component
|
|
17
|
+
* @param socialPosition - Position of social provider buttons relative to the form; `"top"` or `"bottom"` (default `"bottom"`)
|
|
18
|
+
* @returns The sign-up form React element
|
|
19
|
+
*/
|
|
20
|
+
export function SignUp({ className, socialLayout, socialPosition = "bottom", variant, ...props }) {
|
|
21
|
+
const { basePaths, emailAndPassword, localization, magicLink, navigate, redirectTo, socialProviders, viewPaths } = useAuth();
|
|
22
|
+
const [password, setPassword] = useState("");
|
|
23
|
+
const [confirmPassword, setConfirmPassword] = useState("");
|
|
24
|
+
const { mutate: signUpEmail, isPending: signUpPending } = useSignUpEmail({
|
|
25
|
+
onError: (error) => {
|
|
26
|
+
setPassword("");
|
|
27
|
+
setConfirmPassword("");
|
|
28
|
+
toast.danger(error.error?.message || error.message);
|
|
29
|
+
},
|
|
30
|
+
onSuccess: () => {
|
|
31
|
+
if (emailAndPassword?.requireEmailVerification) {
|
|
32
|
+
toast.success(localization.auth.verifyYourEmail);
|
|
33
|
+
navigate({ to: `${basePaths.auth}/${viewPaths.auth.signIn}` });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
navigate({ to: redirectTo });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
const { mutate: signInSocial, isPending: socialPending } = useSignInSocial({
|
|
41
|
+
onError: (error) => toast.danger(error.error?.message || error.message)
|
|
42
|
+
});
|
|
43
|
+
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
|
44
|
+
const [isConfirmPasswordVisible, setIsConfirmPasswordVisible] = useState(false);
|
|
45
|
+
const isPending = signUpPending || socialPending;
|
|
46
|
+
const handleSubmit = (e) => {
|
|
47
|
+
e.preventDefault();
|
|
48
|
+
const formData = new FormData(e.currentTarget);
|
|
49
|
+
const name = formData.get("name");
|
|
50
|
+
const email = formData.get("email");
|
|
51
|
+
if (emailAndPassword?.confirmPassword && password !== confirmPassword) {
|
|
52
|
+
toast.danger(localization.auth.passwordsDoNotMatch);
|
|
53
|
+
setPassword("");
|
|
54
|
+
setConfirmPassword("");
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
signUpEmail({ name, email, password });
|
|
58
|
+
};
|
|
59
|
+
const showSeparator = emailAndPassword?.enabled && socialProviders && socialProviders.length > 0;
|
|
60
|
+
return (_jsx(Card, { className: cn("w-full max-w-sm p-4 md:p-6", className), variant: variant, ...props, children: _jsx(Card.Content, { children: _jsxs(Fieldset, { className: "gap-4", children: [_jsx(Label, { className: "text-xl", children: localization.auth.signUp }), socialPosition === "top" && (_jsxs(_Fragment, { children: [socialProviders && socialProviders.length > 0 && (_jsx(ProviderButtons, { isPending: isPending, socialLayout: socialLayout, signInSocial: signInSocial })), showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or }))] })), emailAndPassword?.enabled && (_jsxs(Form, { onSubmit: handleSubmit, className: "flex flex-col gap-4", children: [_jsxs(Fieldset.Group, { children: [_jsxs(TextField, { name: "name", type: "text", autoComplete: "name", isDisabled: isPending, children: [_jsx(Label, { children: localization.auth.name }), _jsx(Input, { placeholder: localization.auth.namePlaceholder, required: true, variant: variant === "transparent" ? "primary" : "secondary" }), _jsx(FieldError, { className: "text-wrap" })] }), _jsxs(TextField, { name: "email", type: "email", autoComplete: "email", isDisabled: isPending, children: [_jsx(Label, { children: localization.auth.email }), _jsx(Input, { placeholder: localization.auth.emailPlaceholder, required: true, variant: variant === "transparent" ? "primary" : "secondary" }), _jsx(FieldError, { className: "text-wrap" })] }), _jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, name: "password", autoComplete: "new-password", isDisabled: isPending, value: password, onChange: setPassword, children: [_jsx(Label, { children: localization.auth.password }), _jsxs(InputGroup, { variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(InputGroup.Input, { placeholder: localization.auth.passwordPlaceholder, type: isPasswordVisible ? "text" : "password", name: "password", required: true }), _jsx(InputGroup.Suffix, { className: "px-0", children: _jsx(Button, { isIconOnly: true, "aria-label": isPasswordVisible
|
|
61
|
+
? localization.auth.hidePassword
|
|
62
|
+
: localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsPasswordVisible(!isPasswordVisible), isDisabled: isPending, children: isPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] }), _jsx(FieldError, { className: "text-wrap" })] }), emailAndPassword?.confirmPassword && (_jsxs(TextField, { minLength: emailAndPassword?.minPasswordLength, maxLength: emailAndPassword?.maxPasswordLength, name: "confirmPassword", autoComplete: "new-password", isDisabled: isPending, value: confirmPassword, onChange: setConfirmPassword, children: [_jsx(Label, { children: localization.auth.confirmPassword }), _jsxs(InputGroup, { variant: variant === "transparent" ? "primary" : "secondary", children: [_jsx(InputGroup.Input, { name: "confirmPassword", placeholder: localization.auth.confirmPasswordPlaceholder, type: isConfirmPasswordVisible ? "text" : "password", required: true }), _jsx(InputGroup.Suffix, { className: "px-0", children: _jsx(Button, { isIconOnly: true, "aria-label": isConfirmPasswordVisible
|
|
63
|
+
? localization.auth.hidePassword
|
|
64
|
+
: localization.auth.showPassword, size: "sm", variant: "ghost", onPress: () => setIsConfirmPasswordVisible(!isConfirmPasswordVisible), isDisabled: isPending, children: isConfirmPasswordVisible ? _jsx(EyeSlash, {}) : _jsx(Eye, {}) }) })] }), _jsx(FieldError, { className: "text-wrap" })] }))] }), _jsxs(Fieldset.Actions, { className: "flex-col gap-3", children: [_jsxs(Button, { type: "submit", className: "w-full", isPending: isPending, children: [isPending && _jsx(Spinner, { color: "current", size: "sm" }), localization.auth.signUp] }), magicLink && (_jsx(MagicLinkButton, { view: "signUp", isPending: isPending }))] })] })), socialPosition === "bottom" && (_jsxs(_Fragment, { children: [showSeparator && (_jsx(FieldSeparator, { children: localization.auth.or })), socialProviders && socialProviders.length > 0 && (_jsx(ProviderButtons, { socialLayout: socialLayout, signInSocial: signInSocial, isPending: isPending }))] })), emailAndPassword?.enabled && (_jsxs(Description, { className: "text-center text-sm", children: [localization.auth.alreadyHaveAnAccount, " ", _jsx(Link, { href: `${basePaths.auth}/${viewPaths.auth.signIn}`, className: "text-accent decoration-accent no-underline hover:underline", children: localization.auth.signIn })] }))] }) }) }));
|
|
65
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type EmailChangedEmailProps } from "@better-auth-ui/react";
|
|
2
|
+
export type { EmailChangedEmailProps } from "@better-auth-ui/react";
|
|
3
|
+
export declare function EmailChangedEmail({ colors, classNames, ...props }: EmailChangedEmailProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { EmailChangedEmail as EmailChangedEmailPrimitive } from "@better-auth-ui/react";
|
|
3
|
+
import { cn } from "@heroui/react";
|
|
4
|
+
export function EmailChangedEmail({ colors, classNames, ...props }) {
|
|
5
|
+
return (_jsx(EmailChangedEmailPrimitive, { colors: {
|
|
6
|
+
light: {
|
|
7
|
+
background: "#F5F5F5",
|
|
8
|
+
primary: "#0285F7",
|
|
9
|
+
primaryForeground: "#FCFCFC",
|
|
10
|
+
...colors?.light
|
|
11
|
+
},
|
|
12
|
+
dark: {
|
|
13
|
+
background: "#060607",
|
|
14
|
+
primary: "#0584F6",
|
|
15
|
+
primaryForeground: "#FCFCFC",
|
|
16
|
+
...colors?.dark
|
|
17
|
+
}
|
|
18
|
+
}, classNames: {
|
|
19
|
+
...classNames,
|
|
20
|
+
card: cn("border-none rounded-3xl", classNames?.card),
|
|
21
|
+
button: cn("rounded-full", classNames?.button)
|
|
22
|
+
}, ...props }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type EmailVerificationEmailProps } from "@better-auth-ui/react";
|
|
2
|
+
export type { EmailVerificationEmailProps } from "@better-auth-ui/react";
|
|
3
|
+
export declare function EmailVerificationEmail({ colors, classNames, ...props }: EmailVerificationEmailProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { EmailVerificationEmail as EmailVerificationEmailPrimitive } from "@better-auth-ui/react";
|
|
3
|
+
import { cn } from "@heroui/react";
|
|
4
|
+
export function EmailVerificationEmail({ colors, classNames, ...props }) {
|
|
5
|
+
return (_jsx(EmailVerificationEmailPrimitive, { colors: {
|
|
6
|
+
light: {
|
|
7
|
+
background: "#F5F5F5",
|
|
8
|
+
primary: "#0285F7",
|
|
9
|
+
primaryForeground: "#FCFCFC",
|
|
10
|
+
...colors?.light
|
|
11
|
+
},
|
|
12
|
+
dark: {
|
|
13
|
+
background: "#060607",
|
|
14
|
+
primary: "#0584F6",
|
|
15
|
+
primaryForeground: "#FCFCFC",
|
|
16
|
+
...colors?.dark
|
|
17
|
+
}
|
|
18
|
+
}, classNames: {
|
|
19
|
+
...classNames,
|
|
20
|
+
card: cn("border-none rounded-3xl", classNames?.card),
|
|
21
|
+
button: cn("rounded-full", classNames?.button)
|
|
22
|
+
}, ...props }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { MagicLinkEmail as MagicLinkEmailPrimitive } from "@better-auth-ui/react";
|
|
3
|
+
import { cn } from "@heroui/react";
|
|
4
|
+
export function MagicLinkEmail({ colors, classNames, ...props }) {
|
|
5
|
+
return (_jsx(MagicLinkEmailPrimitive, { colors: {
|
|
6
|
+
light: {
|
|
7
|
+
background: "#F5F5F5",
|
|
8
|
+
primary: "#0285F7",
|
|
9
|
+
primaryForeground: "#FCFCFC",
|
|
10
|
+
...colors?.light
|
|
11
|
+
},
|
|
12
|
+
dark: {
|
|
13
|
+
background: "#060607",
|
|
14
|
+
primary: "#0584F6",
|
|
15
|
+
primaryForeground: "#FCFCFC",
|
|
16
|
+
...colors?.dark
|
|
17
|
+
}
|
|
18
|
+
}, classNames: {
|
|
19
|
+
...classNames,
|
|
20
|
+
card: cn("border-none rounded-3xl", classNames?.card),
|
|
21
|
+
button: cn("rounded-full", classNames?.button)
|
|
22
|
+
}, ...props }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { NewDeviceEmail as NewDeviceEmailPrimitive } from "@better-auth-ui/react";
|
|
3
|
+
import { cn } from "@heroui/react";
|
|
4
|
+
export function NewDeviceEmail({ colors, classNames, ...props }) {
|
|
5
|
+
return (_jsx(NewDeviceEmailPrimitive, { colors: {
|
|
6
|
+
light: {
|
|
7
|
+
background: "#F5F5F5",
|
|
8
|
+
primary: "#0285F7",
|
|
9
|
+
primaryForeground: "#FCFCFC",
|
|
10
|
+
...colors?.light
|
|
11
|
+
},
|
|
12
|
+
dark: {
|
|
13
|
+
background: "#060607",
|
|
14
|
+
primary: "#0584F6",
|
|
15
|
+
primaryForeground: "#FCFCFC",
|
|
16
|
+
...colors?.dark
|
|
17
|
+
}
|
|
18
|
+
}, classNames: {
|
|
19
|
+
...classNames,
|
|
20
|
+
card: cn("border-none rounded-3xl", classNames?.card),
|
|
21
|
+
button: cn("rounded-full", classNames?.button)
|
|
22
|
+
}, ...props }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { OtpEmail as OtpEmailPrimitive } from "@better-auth-ui/react";
|
|
3
|
+
import { cn } from "@heroui/react";
|
|
4
|
+
export function OtpEmail({ colors, classNames, ...props }) {
|
|
5
|
+
return (_jsx(OtpEmailPrimitive, { colors: {
|
|
6
|
+
light: {
|
|
7
|
+
background: "#F5F5F5",
|
|
8
|
+
primary: "#0285F7",
|
|
9
|
+
primaryForeground: "#FCFCFC",
|
|
10
|
+
...colors?.light
|
|
11
|
+
},
|
|
12
|
+
dark: {
|
|
13
|
+
background: "#060607",
|
|
14
|
+
primary: "#0584F6",
|
|
15
|
+
primaryForeground: "#FCFCFC",
|
|
16
|
+
...colors?.dark
|
|
17
|
+
}
|
|
18
|
+
}, classNames: {
|
|
19
|
+
...classNames,
|
|
20
|
+
card: cn("border-none rounded-3xl", classNames?.card)
|
|
21
|
+
}, ...props }));
|
|
22
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type PasswordChangedEmailProps } from "@better-auth-ui/react";
|
|
2
|
+
export type { PasswordChangedEmailProps } from "@better-auth-ui/react";
|
|
3
|
+
export declare function PasswordChangedEmail({ colors, classNames, ...props }: PasswordChangedEmailProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { PasswordChangedEmail as PasswordChangedEmailPrimitive } from "@better-auth-ui/react";
|
|
3
|
+
import { cn } from "@heroui/react";
|
|
4
|
+
export function PasswordChangedEmail({ colors, classNames, ...props }) {
|
|
5
|
+
return (_jsx(PasswordChangedEmailPrimitive, { colors: {
|
|
6
|
+
light: {
|
|
7
|
+
background: "#F5F5F5",
|
|
8
|
+
primary: "#0285F7",
|
|
9
|
+
primaryForeground: "#FCFCFC",
|
|
10
|
+
...colors?.light
|
|
11
|
+
},
|
|
12
|
+
dark: {
|
|
13
|
+
background: "#060607",
|
|
14
|
+
primary: "#0584F6",
|
|
15
|
+
primaryForeground: "#FCFCFC",
|
|
16
|
+
...colors?.dark
|
|
17
|
+
}
|
|
18
|
+
}, classNames: {
|
|
19
|
+
...classNames,
|
|
20
|
+
card: cn("border-none rounded-3xl", classNames?.card),
|
|
21
|
+
button: cn("rounded-full", classNames?.button)
|
|
22
|
+
}, ...props }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { type ResetPasswordEmailProps } from "@better-auth-ui/react";
|
|
2
|
+
export type { ResetPasswordEmailProps } from "@better-auth-ui/react";
|
|
3
|
+
export declare function ResetPasswordEmail({ colors, classNames, ...props }: ResetPasswordEmailProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { ResetPasswordEmail as ResetPasswordEmailPrimitive } from "@better-auth-ui/react";
|
|
3
|
+
import { cn } from "@heroui/react";
|
|
4
|
+
export function ResetPasswordEmail({ colors, classNames, ...props }) {
|
|
5
|
+
return (_jsx(ResetPasswordEmailPrimitive, { colors: {
|
|
6
|
+
light: {
|
|
7
|
+
background: "#F5F5F5",
|
|
8
|
+
primary: "#0285F7",
|
|
9
|
+
primaryForeground: "#FCFCFC",
|
|
10
|
+
...colors?.light
|
|
11
|
+
},
|
|
12
|
+
dark: {
|
|
13
|
+
background: "#060607",
|
|
14
|
+
primary: "#0584F6",
|
|
15
|
+
primaryForeground: "#FCFCFC",
|
|
16
|
+
...colors?.dark
|
|
17
|
+
}
|
|
18
|
+
}, classNames: {
|
|
19
|
+
...classNames,
|
|
20
|
+
card: cn("border-none rounded-3xl", classNames?.card),
|
|
21
|
+
button: cn("rounded-full", classNames?.button)
|
|
22
|
+
}, ...props }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ComponentProps } from "react";
|
|
2
|
+
export type AccountSettingsProps = {
|
|
3
|
+
className?: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Renders the account settings layout including user profile, change email, appearance, and accounts management.
|
|
7
|
+
*
|
|
8
|
+
* UserProfile, ChangeEmail, and Appearance are always rendered; Accounts is rendered when `multiSession` is enabled.
|
|
9
|
+
*
|
|
10
|
+
* @param className - Optional additional CSS class names for the outer container.
|
|
11
|
+
* @returns The account settings container as a JSX element.
|
|
12
|
+
*/
|
|
13
|
+
export declare function AccountSettings({ className, ...props }: AccountSettingsProps & ComponentProps<"div">): import("react/jsx-runtime").JSX.Element;
|