@main12/auth-login 0.1.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/README.md +218 -0
- package/dist/auth/application/hooks/useForgotPasswordFlow.d.ts +10 -0
- package/dist/auth/application/hooks/useForgotPasswordFlow.js +45 -0
- package/dist/auth/application/hooks/useLoginFlow.d.ts +30 -0
- package/dist/auth/application/hooks/useLoginFlow.js +105 -0
- package/dist/auth/application/hooks/useSetPasswordFlow.d.ts +18 -0
- package/dist/auth/application/hooks/useSetPasswordFlow.js +59 -0
- package/dist/auth/application/hooks/useVerifyOtpFlow.d.ts +18 -0
- package/dist/auth/application/hooks/useVerifyOtpFlow.js +84 -0
- package/dist/auth/application/services/authService.d.ts +26 -0
- package/dist/auth/application/services/authService.js +90 -0
- package/dist/auth/domain/otp.d.ts +25 -0
- package/dist/auth/domain/otp.js +41 -0
- package/dist/auth/domain/passwordRules.d.ts +12 -0
- package/dist/auth/domain/passwordRules.js +34 -0
- package/dist/auth/domain/types.d.ts +35 -0
- package/dist/auth/domain/types.js +2 -0
- package/dist/components/AuthLayout.d.ts +20 -0
- package/dist/components/AuthLayout.js +49 -0
- package/dist/components/PoweredBy.d.ts +10 -0
- package/dist/components/PoweredBy.js +50 -0
- package/dist/components/email/baseTemplate.d.ts +13 -0
- package/dist/components/email/baseTemplate.js +69 -0
- package/dist/components/email/constants.d.ts +26 -0
- package/dist/components/email/constants.js +30 -0
- package/dist/components/email/index.d.ts +7 -0
- package/dist/components/email/index.js +7 -0
- package/dist/components/email/templates/otp.d.ts +16 -0
- package/dist/components/email/templates/otp.js +38 -0
- package/dist/components/email/templates/passwordChanged.d.ts +15 -0
- package/dist/components/email/templates/passwordChanged.js +33 -0
- package/dist/components/email/templates/passwordReset.d.ts +15 -0
- package/dist/components/email/templates/passwordReset.js +36 -0
- package/dist/components/email/templates/welcome.d.ts +16 -0
- package/dist/components/email/templates/welcome.js +38 -0
- package/dist/components/email/translations.d.ts +45 -0
- package/dist/components/email/translations.js +88 -0
- package/dist/components/pages/ForgotPasswordPage.d.ts +5 -0
- package/dist/components/pages/ForgotPasswordPage.js +45 -0
- package/dist/components/pages/LoginPage.d.ts +11 -0
- package/dist/components/pages/LoginPage.js +222 -0
- package/dist/components/pages/SetPasswordPage.d.ts +5 -0
- package/dist/components/pages/SetPasswordPage.js +74 -0
- package/dist/components/pages/SignupPage.d.ts +10 -0
- package/dist/components/pages/SignupPage.js +129 -0
- package/dist/components/pages/VerifyOtpPage.d.ts +5 -0
- package/dist/components/pages/VerifyOtpPage.js +87 -0
- package/dist/components/ui/index.d.ts +57 -0
- package/dist/components/ui/index.js +121 -0
- package/dist/css.d.js +0 -0
- package/dist/endpoints/authEndpoints.d.ts +22 -0
- package/dist/endpoints/authEndpoints.js +422 -0
- package/dist/exports/client.d.ts +24 -0
- package/dist/exports/client.js +22 -0
- package/dist/exports/rsc.d.ts +6 -0
- package/dist/exports/rsc.js +5 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +16 -0
- package/package.json +115 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { Button, Input, Divider } from '../ui/index.js';
|
|
5
|
+
import { AuthLayout } from '../AuthLayout.js';
|
|
6
|
+
export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass }) {
|
|
7
|
+
const [name, setName] = React.useState('');
|
|
8
|
+
const [email, setEmail] = React.useState('');
|
|
9
|
+
const [isLoading, setIsLoading] = React.useState(false);
|
|
10
|
+
const [error, setError] = React.useState(null);
|
|
11
|
+
const handleSubmit = async (e)=>{
|
|
12
|
+
e.preventDefault();
|
|
13
|
+
setIsLoading(true);
|
|
14
|
+
setError(null);
|
|
15
|
+
try {
|
|
16
|
+
await onSignup({
|
|
17
|
+
name,
|
|
18
|
+
email
|
|
19
|
+
});
|
|
20
|
+
window.location.href = `/verify-otp?email=${encodeURIComponent(email)}&purpose=signup`;
|
|
21
|
+
} catch (err) {
|
|
22
|
+
setError(err.message || 'Signup failed');
|
|
23
|
+
} finally{
|
|
24
|
+
setIsLoading(false);
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
return /*#__PURE__*/ _jsxs(AuthLayout, {
|
|
28
|
+
logo: logo,
|
|
29
|
+
title: "Create Account",
|
|
30
|
+
subtitle: "Enter your details to get started",
|
|
31
|
+
poweredBy: poweredBy,
|
|
32
|
+
cardClassName: cardClassName,
|
|
33
|
+
backgroundClass: backgroundClass,
|
|
34
|
+
footer: /*#__PURE__*/ _jsxs("p", {
|
|
35
|
+
className: "text-center text-gray-600 text-sm",
|
|
36
|
+
children: [
|
|
37
|
+
"Already have an account?",
|
|
38
|
+
' ',
|
|
39
|
+
/*#__PURE__*/ _jsx("a", {
|
|
40
|
+
href: loginUrl,
|
|
41
|
+
className: "text-gray-900 font-medium hover:underline",
|
|
42
|
+
children: "Sign in"
|
|
43
|
+
})
|
|
44
|
+
]
|
|
45
|
+
}),
|
|
46
|
+
children: [
|
|
47
|
+
showGoogleOAuth && /*#__PURE__*/ _jsxs(_Fragment, {
|
|
48
|
+
children: [
|
|
49
|
+
/*#__PURE__*/ _jsxs(Button, {
|
|
50
|
+
fullWidth: true,
|
|
51
|
+
variant: "bordered",
|
|
52
|
+
size: "lg",
|
|
53
|
+
className: "mb-4",
|
|
54
|
+
children: [
|
|
55
|
+
/*#__PURE__*/ _jsx("span", {
|
|
56
|
+
className: "text-lg",
|
|
57
|
+
children: "G"
|
|
58
|
+
}),
|
|
59
|
+
" Continue with Google"
|
|
60
|
+
]
|
|
61
|
+
}),
|
|
62
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
63
|
+
className: "flex items-center gap-4 my-4",
|
|
64
|
+
children: [
|
|
65
|
+
/*#__PURE__*/ _jsx(Divider, {
|
|
66
|
+
className: "flex-1"
|
|
67
|
+
}),
|
|
68
|
+
/*#__PURE__*/ _jsx("span", {
|
|
69
|
+
className: "text-gray-500 text-sm",
|
|
70
|
+
children: "or"
|
|
71
|
+
}),
|
|
72
|
+
/*#__PURE__*/ _jsx(Divider, {
|
|
73
|
+
className: "flex-1"
|
|
74
|
+
})
|
|
75
|
+
]
|
|
76
|
+
})
|
|
77
|
+
]
|
|
78
|
+
}),
|
|
79
|
+
/*#__PURE__*/ _jsxs("form", {
|
|
80
|
+
onSubmit: handleSubmit,
|
|
81
|
+
className: "space-y-4",
|
|
82
|
+
children: [
|
|
83
|
+
error && /*#__PURE__*/ _jsx("div", {
|
|
84
|
+
className: "bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm animate-[fadeIn_0.2s_ease-out]",
|
|
85
|
+
children: error
|
|
86
|
+
}),
|
|
87
|
+
/*#__PURE__*/ _jsx(Input, {
|
|
88
|
+
label: "Full Name",
|
|
89
|
+
value: name,
|
|
90
|
+
onValueChange: setName,
|
|
91
|
+
isRequired: true
|
|
92
|
+
}),
|
|
93
|
+
/*#__PURE__*/ _jsx(Input, {
|
|
94
|
+
type: "email",
|
|
95
|
+
label: "Email",
|
|
96
|
+
value: email,
|
|
97
|
+
onValueChange: setEmail,
|
|
98
|
+
isRequired: true
|
|
99
|
+
}),
|
|
100
|
+
/*#__PURE__*/ _jsxs("p", {
|
|
101
|
+
className: "text-xs text-gray-600 text-center",
|
|
102
|
+
children: [
|
|
103
|
+
"By signing up, you agree to our",
|
|
104
|
+
' ',
|
|
105
|
+
/*#__PURE__*/ _jsx("a", {
|
|
106
|
+
href: "/terms",
|
|
107
|
+
className: "text-gray-900 hover:underline",
|
|
108
|
+
children: "Terms of Service"
|
|
109
|
+
}),
|
|
110
|
+
" and",
|
|
111
|
+
' ',
|
|
112
|
+
/*#__PURE__*/ _jsx("a", {
|
|
113
|
+
href: "/privacy",
|
|
114
|
+
className: "text-gray-900 hover:underline",
|
|
115
|
+
children: "Privacy Policy"
|
|
116
|
+
})
|
|
117
|
+
]
|
|
118
|
+
}),
|
|
119
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
120
|
+
type: "submit",
|
|
121
|
+
variant: "primary",
|
|
122
|
+
isLoading: isLoading,
|
|
123
|
+
children: "Create Account"
|
|
124
|
+
})
|
|
125
|
+
]
|
|
126
|
+
})
|
|
127
|
+
]
|
|
128
|
+
});
|
|
129
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import React, { Suspense } from 'react';
|
|
4
|
+
import { useSearchParams } from 'next/navigation';
|
|
5
|
+
import { Button, OtpInput, Spinner } from '../ui/index.js';
|
|
6
|
+
import { useVerifyOtpFlow } from '../../auth/application/hooks/useVerifyOtpFlow.js';
|
|
7
|
+
import { AuthLayout } from '../AuthLayout.js';
|
|
8
|
+
function VerifyOtpContent({ loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass }) {
|
|
9
|
+
const searchParams = useSearchParams();
|
|
10
|
+
const email = searchParams.get('email') || '';
|
|
11
|
+
const purpose = searchParams.get('purpose') || 'login';
|
|
12
|
+
const redirectTo = searchParams.get('redirect') || '/';
|
|
13
|
+
const { otp, error, isLoading, isResending, resendCooldown, setOtp, handleSubmit, handleResendCode } = useVerifyOtpFlow({
|
|
14
|
+
email,
|
|
15
|
+
purpose,
|
|
16
|
+
redirectTo
|
|
17
|
+
});
|
|
18
|
+
if (!email) return null;
|
|
19
|
+
const isPasswordReset = purpose === 'password-reset';
|
|
20
|
+
return /*#__PURE__*/ _jsx(AuthLayout, {
|
|
21
|
+
logo: logo,
|
|
22
|
+
title: isPasswordReset ? 'Reset Password' : 'Check Your Email',
|
|
23
|
+
subtitle: isPasswordReset ? 'Enter the code to reset your password' : 'We sent a 6-digit code to',
|
|
24
|
+
poweredBy: poweredBy,
|
|
25
|
+
cardClassName: cardClassName,
|
|
26
|
+
backgroundClass: backgroundClass,
|
|
27
|
+
footer: /*#__PURE__*/ _jsx("a", {
|
|
28
|
+
href: loginUrl,
|
|
29
|
+
className: "text-sm text-gray-600 hover:text-gray-900 flex items-center gap-1",
|
|
30
|
+
children: "← Back to Login"
|
|
31
|
+
}),
|
|
32
|
+
children: /*#__PURE__*/ _jsxs("div", {
|
|
33
|
+
className: "flex flex-col items-center gap-4",
|
|
34
|
+
children: [
|
|
35
|
+
/*#__PURE__*/ _jsx("p", {
|
|
36
|
+
className: "text-gray-700 text-sm font-medium",
|
|
37
|
+
children: email
|
|
38
|
+
}),
|
|
39
|
+
/*#__PURE__*/ _jsx(OtpInput, {
|
|
40
|
+
value: otp,
|
|
41
|
+
onValueChange: setOtp,
|
|
42
|
+
isDisabled: isLoading,
|
|
43
|
+
autoFocus: true
|
|
44
|
+
}),
|
|
45
|
+
error && /*#__PURE__*/ _jsx("div", {
|
|
46
|
+
className: "w-full bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm animate-[fadeIn_0.2s_ease-out]",
|
|
47
|
+
children: error
|
|
48
|
+
}),
|
|
49
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
50
|
+
variant: "primary",
|
|
51
|
+
isLoading: isLoading,
|
|
52
|
+
isDisabled: otp.length !== 6,
|
|
53
|
+
onPress: handleSubmit,
|
|
54
|
+
children: "Verify"
|
|
55
|
+
}),
|
|
56
|
+
/*#__PURE__*/ _jsxs("div", {
|
|
57
|
+
className: "text-center",
|
|
58
|
+
children: [
|
|
59
|
+
/*#__PURE__*/ _jsx("p", {
|
|
60
|
+
className: "text-gray-600 text-sm mb-2",
|
|
61
|
+
children: "Didn't receive a code?"
|
|
62
|
+
}),
|
|
63
|
+
/*#__PURE__*/ _jsx("button", {
|
|
64
|
+
onClick: handleResendCode,
|
|
65
|
+
disabled: isResending || resendCooldown > 0,
|
|
66
|
+
className: "text-[#0071e3] font-medium text-sm hover:underline disabled:opacity-50 disabled:cursor-not-allowed",
|
|
67
|
+
children: isResending ? 'Sending...' : resendCooldown > 0 ? `Resend in ${resendCooldown}s` : 'Resend Code'
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
})
|
|
71
|
+
]
|
|
72
|
+
})
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
export default function VerifyOtpPage(props) {
|
|
76
|
+
return /*#__PURE__*/ _jsx(Suspense, {
|
|
77
|
+
fallback: /*#__PURE__*/ _jsx("div", {
|
|
78
|
+
className: "min-h-screen flex items-center justify-center",
|
|
79
|
+
children: /*#__PURE__*/ _jsx(Spinner, {
|
|
80
|
+
size: "lg"
|
|
81
|
+
})
|
|
82
|
+
}),
|
|
83
|
+
children: /*#__PURE__*/ _jsx(VerifyOtpContent, {
|
|
84
|
+
...props
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface ButtonProps {
|
|
3
|
+
children: React.ReactNode;
|
|
4
|
+
type?: 'button' | 'submit';
|
|
5
|
+
fullWidth?: boolean;
|
|
6
|
+
size?: 'sm' | 'lg';
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
isDisabled?: boolean;
|
|
9
|
+
onPress?: () => void;
|
|
10
|
+
onClick?: () => void;
|
|
11
|
+
variant?: 'primary' | 'bordered' | 'ghost' | 'tertiary';
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare const Button: React.FC<ButtonProps>;
|
|
15
|
+
interface InputProps {
|
|
16
|
+
type?: string;
|
|
17
|
+
label?: string;
|
|
18
|
+
value: string;
|
|
19
|
+
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
|
|
20
|
+
onValueChange?: (value: string) => void;
|
|
21
|
+
isRequired?: boolean;
|
|
22
|
+
isDisabled?: boolean;
|
|
23
|
+
autoFocus?: boolean;
|
|
24
|
+
autoComplete?: string;
|
|
25
|
+
placeholder?: string;
|
|
26
|
+
className?: string;
|
|
27
|
+
name?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare const Input: React.FC<InputProps>;
|
|
30
|
+
interface CardProps {
|
|
31
|
+
children: React.ReactNode;
|
|
32
|
+
className?: string;
|
|
33
|
+
}
|
|
34
|
+
export declare const Card: React.FC<CardProps>;
|
|
35
|
+
export declare const CardHeader: React.FC<CardProps>;
|
|
36
|
+
export declare const CardContent: React.FC<CardProps>;
|
|
37
|
+
export declare const CardFooter: React.FC<CardProps>;
|
|
38
|
+
export declare const CardTitle: React.FC<CardProps>;
|
|
39
|
+
export declare const CardDescription: React.FC<CardProps>;
|
|
40
|
+
export declare const Divider: React.FC<{
|
|
41
|
+
className?: string;
|
|
42
|
+
}>;
|
|
43
|
+
interface SpinnerProps {
|
|
44
|
+
size?: 'sm' | 'lg';
|
|
45
|
+
className?: string;
|
|
46
|
+
}
|
|
47
|
+
export declare const Spinner: React.FC<SpinnerProps>;
|
|
48
|
+
interface OtpInputProps {
|
|
49
|
+
length?: number;
|
|
50
|
+
value: string;
|
|
51
|
+
onChange?: (value: string) => void;
|
|
52
|
+
onValueChange?: (value: string) => void;
|
|
53
|
+
isDisabled?: boolean;
|
|
54
|
+
autoFocus?: boolean;
|
|
55
|
+
}
|
|
56
|
+
export declare const OtpInput: React.FC<OtpInputProps>;
|
|
57
|
+
export {};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import React from 'react';
|
|
3
|
+
const variantClasses = {
|
|
4
|
+
primary: 'bg-[#D5E855] text-gray-900 hover:bg-[#C9DC4A] font-semibold',
|
|
5
|
+
bordered: 'border border-gray-300 text-gray-700 hover:bg-gray-50 bg-white',
|
|
6
|
+
ghost: 'text-gray-600 hover:text-gray-900 bg-transparent',
|
|
7
|
+
tertiary: 'text-gray-600 hover:text-gray-900 bg-transparent underline'
|
|
8
|
+
};
|
|
9
|
+
export const Button = ({ children, type = 'button', fullWidth = true, size = 'lg', isLoading, isDisabled, onPress, onClick, variant = 'primary', className = '' })=>/*#__PURE__*/ _jsxs("button", {
|
|
10
|
+
type: type,
|
|
11
|
+
disabled: isDisabled || isLoading,
|
|
12
|
+
onClick: onPress || onClick,
|
|
13
|
+
className: `
|
|
14
|
+
${fullWidth ? 'w-full' : ''}
|
|
15
|
+
${size === 'lg' ? 'h-12 px-6 text-base' : 'h-8 px-3 text-sm'}
|
|
16
|
+
rounded-full transition-all duration-200 flex items-center justify-center gap-2
|
|
17
|
+
disabled:opacity-50 disabled:cursor-not-allowed
|
|
18
|
+
${variantClasses[variant] || variantClasses.primary}
|
|
19
|
+
${className}
|
|
20
|
+
`.trim(),
|
|
21
|
+
children: [
|
|
22
|
+
isLoading ? /*#__PURE__*/ _jsx(Spinner, {
|
|
23
|
+
size: "sm"
|
|
24
|
+
}) : null,
|
|
25
|
+
children
|
|
26
|
+
]
|
|
27
|
+
});
|
|
28
|
+
export const Input = ({ type = 'text', label, value, onChange, onValueChange, isRequired, isDisabled, autoFocus, autoComplete, placeholder, className = '', name })=>/*#__PURE__*/ _jsxs("div", {
|
|
29
|
+
className: "w-full",
|
|
30
|
+
children: [
|
|
31
|
+
label && /*#__PURE__*/ _jsxs("label", {
|
|
32
|
+
className: "block text-sm font-medium text-gray-600 mb-1",
|
|
33
|
+
children: [
|
|
34
|
+
label,
|
|
35
|
+
isRequired ? ' *' : ''
|
|
36
|
+
]
|
|
37
|
+
}),
|
|
38
|
+
/*#__PURE__*/ _jsx("input", {
|
|
39
|
+
type: type,
|
|
40
|
+
value: value,
|
|
41
|
+
onChange: onChange || (onValueChange ? (e)=>onValueChange(e.target.value) : undefined),
|
|
42
|
+
required: isRequired,
|
|
43
|
+
disabled: isDisabled,
|
|
44
|
+
autoFocus: autoFocus,
|
|
45
|
+
autoComplete: autoComplete,
|
|
46
|
+
placeholder: placeholder,
|
|
47
|
+
name: name,
|
|
48
|
+
className: `w-full h-12 px-4 bg-white border border-gray-300 hover:border-gray-400 rounded-xl text-gray-900 text-base transition-colors outline-none focus:border-[#D5E855] focus:ring-2 focus:ring-[#D5E855]/30 ${className}`
|
|
49
|
+
})
|
|
50
|
+
]
|
|
51
|
+
});
|
|
52
|
+
export const Card = ({ children, className = '' })=>/*#__PURE__*/ _jsx("div", {
|
|
53
|
+
className: `bg-white rounded-2xl shadow-2xl ${className}`,
|
|
54
|
+
children: children
|
|
55
|
+
});
|
|
56
|
+
export const CardHeader = ({ children, className = '' })=>/*#__PURE__*/ _jsx("div", {
|
|
57
|
+
className: `flex flex-col items-center gap-2 pt-8 pb-2 px-6 ${className}`,
|
|
58
|
+
children: children
|
|
59
|
+
});
|
|
60
|
+
export const CardContent = ({ children, className = '' })=>/*#__PURE__*/ _jsx("div", {
|
|
61
|
+
className: `px-6 pb-4 ${className}`,
|
|
62
|
+
children: children
|
|
63
|
+
});
|
|
64
|
+
export const CardFooter = ({ children, className = '' })=>/*#__PURE__*/ _jsx("div", {
|
|
65
|
+
className: `px-6 pb-6 flex justify-center ${className}`,
|
|
66
|
+
children: children
|
|
67
|
+
});
|
|
68
|
+
export const CardTitle = ({ children, className = '' })=>/*#__PURE__*/ _jsx("h1", {
|
|
69
|
+
className: `text-xl font-semibold text-gray-900 ${className}`,
|
|
70
|
+
children: children
|
|
71
|
+
});
|
|
72
|
+
export const CardDescription = ({ children, className = '' })=>/*#__PURE__*/ _jsx("p", {
|
|
73
|
+
className: `text-gray-600 text-sm text-center ${className}`,
|
|
74
|
+
children: children
|
|
75
|
+
});
|
|
76
|
+
export const Divider = ({ className = '' })=>/*#__PURE__*/ _jsx("hr", {
|
|
77
|
+
className: `border-0 h-px bg-gray-200 ${className}`
|
|
78
|
+
});
|
|
79
|
+
export const Spinner = ({ size = 'lg', className = '' })=>/*#__PURE__*/ _jsx("div", {
|
|
80
|
+
className: `inline-block animate-spin rounded-full border-2 border-current border-t-transparent ${size === 'lg' ? 'w-6 h-6' : 'w-4 h-4'} ${className}`,
|
|
81
|
+
role: "status",
|
|
82
|
+
children: /*#__PURE__*/ _jsx("span", {
|
|
83
|
+
className: "sr-only",
|
|
84
|
+
children: "Loading..."
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
export const OtpInput = ({ length = 6, value, onChange, onValueChange, isDisabled, autoFocus })=>{
|
|
88
|
+
const setValue = onChange || onValueChange || (()=>{});
|
|
89
|
+
const inputs = Array.from({
|
|
90
|
+
length
|
|
91
|
+
}, (_, i)=>i);
|
|
92
|
+
return /*#__PURE__*/ _jsx("div", {
|
|
93
|
+
className: "flex justify-center gap-2",
|
|
94
|
+
children: inputs.map((i)=>/*#__PURE__*/ _jsx("input", {
|
|
95
|
+
type: "text",
|
|
96
|
+
inputMode: "numeric",
|
|
97
|
+
maxLength: 1,
|
|
98
|
+
value: value[i] || '',
|
|
99
|
+
disabled: isDisabled,
|
|
100
|
+
autoFocus: autoFocus && i === 0,
|
|
101
|
+
onChange: (e)=>{
|
|
102
|
+
const char = e.target.value.replace(/[^0-9]/g, '').slice(0, 1);
|
|
103
|
+
const newVal = value.split('');
|
|
104
|
+
newVal[i] = char;
|
|
105
|
+
setValue(newVal.join(''));
|
|
106
|
+
// Auto-focus next
|
|
107
|
+
if (char && i < length - 1) {
|
|
108
|
+
const next = e.target.parentElement?.nextElementSibling?.querySelector('input');
|
|
109
|
+
next?.focus();
|
|
110
|
+
}
|
|
111
|
+
},
|
|
112
|
+
onKeyDown: (e)=>{
|
|
113
|
+
if (e.key === 'Backspace' && !value[i] && i > 0) {
|
|
114
|
+
const prev = e.target.parentElement?.previousElementSibling?.querySelector('input');
|
|
115
|
+
prev?.focus();
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
className: "w-12 h-14 text-center text-2xl font-semibold text-gray-900 border-2 border-gray-300 rounded-xl focus:border-[#D5E855] focus:ring-2 focus:ring-[#D5E855]/30 outline-none transition-all bg-white"
|
|
119
|
+
}, i))
|
|
120
|
+
});
|
|
121
|
+
};
|
package/dist/css.d.js
ADDED
|
File without changes
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Endpoint } from 'payload';
|
|
2
|
+
/**
|
|
3
|
+
* POST /api/auth/check-email — Check if user exists and has password
|
|
4
|
+
*/
|
|
5
|
+
export declare const checkEmailEndpoint: Endpoint;
|
|
6
|
+
/**
|
|
7
|
+
* POST /api/auth/otp/send — Generate OTP, store it, send email via Payload
|
|
8
|
+
*/
|
|
9
|
+
export declare const sendOtpEndpoint: Endpoint;
|
|
10
|
+
/**
|
|
11
|
+
* POST /api/auth/otp/verify — Verify OTP and login the user
|
|
12
|
+
*/
|
|
13
|
+
export declare const verifyOtpEndpoint: Endpoint;
|
|
14
|
+
/**
|
|
15
|
+
* POST /api/auth/set-password — Set/update password for authenticated user
|
|
16
|
+
*/
|
|
17
|
+
export declare const setPasswordEndpoint: Endpoint;
|
|
18
|
+
/**
|
|
19
|
+
* POST /api/auth/signup — Create new user + send welcome email
|
|
20
|
+
*/
|
|
21
|
+
export declare const signupEndpoint: Endpoint;
|
|
22
|
+
export declare const authEndpoints: Endpoint[];
|