@insforge/react 0.2.9 → 0.3.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 +71 -32
- package/dist/atoms.d.mts +23 -2
- package/dist/atoms.d.ts +23 -2
- package/dist/atoms.js +139 -0
- package/dist/atoms.js.map +1 -1
- package/dist/atoms.mjs +140 -2
- package/dist/atoms.mjs.map +1 -1
- package/dist/components.d.mts +127 -5
- package/dist/components.d.ts +127 -5
- package/dist/components.js +900 -342
- package/dist/components.js.map +1 -1
- package/dist/components.mjs +898 -344
- package/dist/components.mjs.map +1 -1
- package/dist/forms.js +4 -0
- package/dist/forms.js.map +1 -1
- package/dist/forms.mjs +5 -1
- package/dist/forms.mjs.map +1 -1
- package/dist/hooks.d.mts +4 -0
- package/dist/hooks.d.ts +4 -0
- package/dist/hooks.js.map +1 -1
- package/dist/hooks.mjs.map +1 -1
- package/dist/index.d.mts +6 -11
- package/dist/index.d.ts +6 -11
- package/dist/index.js +930 -458
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +927 -459
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/types.d.mts +1 -0
- package/dist/types.d.ts +1 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -110,19 +110,19 @@ export default function Home() {
|
|
|
110
110
|
|
|
111
111
|
### Built-in Auth (Recommended)
|
|
112
112
|
|
|
113
|
-
Uses your deployed Insforge auth pages:
|
|
113
|
+
Uses your deployed Insforge auth pages (includes all flows):
|
|
114
114
|
|
|
115
115
|
```tsx
|
|
116
116
|
...getInsforgeRoutes({
|
|
117
117
|
baseUrl: 'https://your-project.insforge.app',
|
|
118
118
|
builtInAuth: true, // Default
|
|
119
119
|
paths: {
|
|
120
|
-
signIn: '/sign-in',
|
|
121
|
-
signUp: '/sign-up',
|
|
122
|
-
verifyEmail: '/verify-email',
|
|
123
|
-
forgotPassword: '/forgot-password',
|
|
124
|
-
resetPassword: '/reset-password',
|
|
125
|
-
callback: '/auth/callback'
|
|
120
|
+
signIn: '/sign-in', // Sign in page
|
|
121
|
+
signUp: '/sign-up', // Sign up page
|
|
122
|
+
verifyEmail: '/verify-email', // Email verification page
|
|
123
|
+
forgotPassword: '/forgot-password', // Request password reset
|
|
124
|
+
resetPassword: '/reset-password', // Reset password with token
|
|
125
|
+
callback: '/auth/callback' // OAuth callback handler
|
|
126
126
|
}
|
|
127
127
|
})
|
|
128
128
|
```
|
|
@@ -132,7 +132,13 @@ Uses your deployed Insforge auth pages:
|
|
|
132
132
|
Use package components with your own styling:
|
|
133
133
|
|
|
134
134
|
```tsx
|
|
135
|
-
import {
|
|
135
|
+
import {
|
|
136
|
+
SignIn,
|
|
137
|
+
SignUp,
|
|
138
|
+
ForgotPassword,
|
|
139
|
+
ResetPassword,
|
|
140
|
+
VerifyEmail
|
|
141
|
+
} from '@insforge/react';
|
|
136
142
|
|
|
137
143
|
const router = createBrowserRouter([
|
|
138
144
|
{ path: '/', element: <Home /> },
|
|
@@ -143,9 +149,12 @@ const router = createBrowserRouter([
|
|
|
143
149
|
builtInAuth: false // Don't redirect to deployed UI
|
|
144
150
|
}),
|
|
145
151
|
|
|
146
|
-
// Use package components
|
|
152
|
+
// Use package components for complete auth flows
|
|
147
153
|
{ path: '/sign-in', element: <SignIn afterSignInUrl="/dashboard" /> },
|
|
148
|
-
{ path: '/sign-up', element: <SignUp afterSignUpUrl="/dashboard" /> }
|
|
154
|
+
{ path: '/sign-up', element: <SignUp afterSignUpUrl="/dashboard" /> },
|
|
155
|
+
{ path: '/forgot-password', element: <ForgotPassword backToSignInUrl="/sign-in" /> },
|
|
156
|
+
{ path: '/reset-password', element: <ResetPassword token={searchParams.get('token')} /> },
|
|
157
|
+
{ path: '/verify-email', element: <VerifyEmail token={searchParams.get('token')} /> }
|
|
149
158
|
]);
|
|
150
159
|
```
|
|
151
160
|
|
|
@@ -177,7 +186,10 @@ function CustomSignIn() {
|
|
|
177
186
|
|
|
178
187
|
**Pre-built with Business Logic:**
|
|
179
188
|
- `<SignIn />` - Complete sign-in with email/password & OAuth
|
|
180
|
-
- `<SignUp />` - Registration with password validation
|
|
189
|
+
- `<SignUp />` - Registration with password validation & email verification
|
|
190
|
+
- `<ForgotPassword />` - Request password reset with email validation
|
|
191
|
+
- `<ResetPassword />` - Reset password with token validation
|
|
192
|
+
- `<VerifyEmail />` - Verify email with automatic token handling
|
|
181
193
|
- `<UserButton />` - User dropdown with sign-out
|
|
182
194
|
- `<Protect />` - Route protection wrapper
|
|
183
195
|
- `<SignedIn>` / `<SignedOut>` - Conditional rendering
|
|
@@ -186,12 +198,12 @@ function CustomSignIn() {
|
|
|
186
198
|
**Form Components (Pure UI):**
|
|
187
199
|
- `<SignInForm />` - Sign-in UI without logic
|
|
188
200
|
- `<SignUpForm />` - Sign-up UI without logic
|
|
189
|
-
- `<ForgotPasswordForm />` - Password reset request
|
|
190
|
-
- `<ResetPasswordForm />` - Password reset with token
|
|
191
|
-
- `<VerifyEmailStatus />` - Email verification status
|
|
201
|
+
- `<ForgotPasswordForm />` - Password reset request UI
|
|
202
|
+
- `<ResetPasswordForm />` - Password reset with token UI
|
|
203
|
+
- `<VerifyEmailStatus />` - Email verification status UI
|
|
192
204
|
|
|
193
|
-
**Atomic Components (
|
|
194
|
-
- `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, etc.
|
|
205
|
+
**Atomic Components (14 total):**
|
|
206
|
+
- `<AuthContainer />`, `<AuthHeader />`, `<AuthFormField />`, `<AuthPasswordField />`, `<AuthEmailVerificationStep />`, etc.
|
|
195
207
|
|
|
196
208
|
### Hooks
|
|
197
209
|
|
|
@@ -217,6 +229,14 @@ All components support `appearance` props:
|
|
|
217
229
|
button: "bg-blue-600 hover:bg-blue-700"
|
|
218
230
|
}}
|
|
219
231
|
/>
|
|
232
|
+
|
|
233
|
+
// Works with all auth components
|
|
234
|
+
<ForgotPassword
|
|
235
|
+
appearance={{
|
|
236
|
+
card: "bg-gradient-to-br from-indigo-50 to-white",
|
|
237
|
+
button: "bg-indigo-600 hover:bg-indigo-700"
|
|
238
|
+
}}
|
|
239
|
+
/>
|
|
220
240
|
```
|
|
221
241
|
|
|
222
242
|
### Deep Customization (Hierarchical Appearance)
|
|
@@ -255,7 +275,7 @@ Style nested components through hierarchical structure:
|
|
|
255
275
|
|
|
256
276
|
#### Complete Appearance Structure
|
|
257
277
|
|
|
258
|
-
**SignIn
|
|
278
|
+
**All auth components** (`SignIn`, `SignUp`, `ForgotPassword`, `ResetPassword`) support hierarchical appearance:
|
|
259
279
|
|
|
260
280
|
```typescript
|
|
261
281
|
appearance?: {
|
|
@@ -269,17 +289,17 @@ appearance?: {
|
|
|
269
289
|
errorBanner?: string; // Error message banner
|
|
270
290
|
form?: {
|
|
271
291
|
container?: string; // Form wrapper
|
|
272
|
-
emailField?: {
|
|
273
|
-
container?: string;
|
|
274
|
-
label?: string;
|
|
275
|
-
input?: string;
|
|
292
|
+
emailField?: { // Available in SignIn, SignUp, ForgotPassword
|
|
293
|
+
container?: string;
|
|
294
|
+
label?: string;
|
|
295
|
+
input?: string;
|
|
276
296
|
};
|
|
277
|
-
passwordField?: {
|
|
278
|
-
container?: string;
|
|
279
|
-
label?: string;
|
|
280
|
-
input?: string;
|
|
281
|
-
forgotPasswordLink?: string; //
|
|
282
|
-
strengthIndicator?: { //
|
|
297
|
+
passwordField?: { // Available in SignIn, SignUp, ResetPassword
|
|
298
|
+
container?: string;
|
|
299
|
+
label?: string;
|
|
300
|
+
input?: string;
|
|
301
|
+
forgotPasswordLink?: string; // SignIn only
|
|
302
|
+
strengthIndicator?: { // SignUp and ResetPassword
|
|
283
303
|
container?: string;
|
|
284
304
|
requirement?: string;
|
|
285
305
|
};
|
|
@@ -291,17 +311,17 @@ appearance?: {
|
|
|
291
311
|
text?: string; // Link description text
|
|
292
312
|
link?: string; // Actual link element
|
|
293
313
|
};
|
|
294
|
-
divider?: string; // "or" divider
|
|
295
|
-
oauth?: {
|
|
296
|
-
container?: string;
|
|
297
|
-
button?: string;
|
|
314
|
+
divider?: string; // "or" divider (SignIn, SignUp)
|
|
315
|
+
oauth?: { // OAuth section (SignIn, SignUp)
|
|
316
|
+
container?: string;
|
|
317
|
+
button?: string;
|
|
298
318
|
};
|
|
299
319
|
}
|
|
300
320
|
```
|
|
301
321
|
|
|
302
322
|
### Text Customization
|
|
303
323
|
|
|
304
|
-
All text
|
|
324
|
+
All components support full text customization:
|
|
305
325
|
|
|
306
326
|
```tsx
|
|
307
327
|
<SignIn
|
|
@@ -316,6 +336,16 @@ All text is customizable:
|
|
|
316
336
|
signUpLinkText="Create an account"
|
|
317
337
|
dividerText="or continue with"
|
|
318
338
|
/>
|
|
339
|
+
|
|
340
|
+
<ForgotPassword
|
|
341
|
+
title="Reset Your Password"
|
|
342
|
+
subtitle="Enter your email to receive a reset code"
|
|
343
|
+
emailLabel="Email Address"
|
|
344
|
+
submitButtonText="Send Reset Code"
|
|
345
|
+
backToSignInText="Remember your password?"
|
|
346
|
+
successTitle="Check Your Email"
|
|
347
|
+
successMessage="We've sent a reset code to your inbox"
|
|
348
|
+
/>
|
|
319
349
|
```
|
|
320
350
|
|
|
321
351
|
---
|
|
@@ -483,14 +513,22 @@ import type {
|
|
|
483
513
|
InsforgeUser,
|
|
484
514
|
SignInProps,
|
|
485
515
|
SignUpProps,
|
|
516
|
+
ForgotPasswordProps,
|
|
517
|
+
ResetPasswordProps,
|
|
518
|
+
VerifyEmailProps,
|
|
486
519
|
SignInAppearance,
|
|
487
520
|
SignUpAppearance,
|
|
521
|
+
ForgotPasswordAppearance,
|
|
522
|
+
ResetPasswordAppearance,
|
|
488
523
|
UserButtonProps,
|
|
489
524
|
ProtectProps,
|
|
490
525
|
ConditionalProps,
|
|
491
526
|
InsforgeCallbackProps,
|
|
492
527
|
SignInFormProps,
|
|
493
528
|
SignUpFormProps,
|
|
529
|
+
ForgotPasswordFormProps,
|
|
530
|
+
ResetPasswordFormProps,
|
|
531
|
+
VerifyEmailStatusProps,
|
|
494
532
|
AuthFormFieldProps,
|
|
495
533
|
OAuthProvider,
|
|
496
534
|
EmailAuthConfig,
|
|
@@ -551,6 +589,7 @@ Low-level building blocks for complete customization:
|
|
|
551
589
|
- `<AuthOAuthButton />` - Single OAuth provider button
|
|
552
590
|
- `<AuthOAuthProviders />` - Smart OAuth grid
|
|
553
591
|
- `<AuthVerificationCodeInput />` - 6-digit OTP input
|
|
592
|
+
- `<AuthEmailVerificationStep />` - Email verification step with countdown and resend
|
|
554
593
|
|
|
555
594
|
---
|
|
556
595
|
|
package/dist/atoms.d.mts
CHANGED
|
@@ -361,6 +361,27 @@ declare function AuthOAuthProviders({ providers, onClick, disabled, loading, app
|
|
|
361
361
|
* - `appearance.containerClassName`: Container element
|
|
362
362
|
* - `appearance.inputClassName`: Input elements
|
|
363
363
|
*/
|
|
364
|
-
declare function AuthVerificationCodeInput({ length, value, email, onChange, disabled, appearance, }: AuthVerificationCodeInputProps): react_jsx_runtime.JSX.Element;
|
|
364
|
+
declare function AuthVerificationCodeInput({ length, value, email, onChange, disabled, onComplete, appearance, }: AuthVerificationCodeInputProps): react_jsx_runtime.JSX.Element;
|
|
365
365
|
|
|
366
|
-
|
|
366
|
+
type VerificationMethod = 'code' | 'link';
|
|
367
|
+
interface AuthEmailVerificationStepProps {
|
|
368
|
+
email: string;
|
|
369
|
+
title?: string;
|
|
370
|
+
description?: string;
|
|
371
|
+
method?: VerificationMethod;
|
|
372
|
+
onVerifyCode?: (code: string) => Promise<void>;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Email verification step component
|
|
376
|
+
*
|
|
377
|
+
* Handles the email verification flow:
|
|
378
|
+
* - Automatically sends verification email on mount
|
|
379
|
+
* - Shows countdown timer for resend functionality
|
|
380
|
+
* - Manages rate limiting for resend attempts
|
|
381
|
+
* - Supports both code and link verification methods
|
|
382
|
+
*
|
|
383
|
+
* @param method - 'code' for OTP input, 'link' for magic link (default: 'code')
|
|
384
|
+
*/
|
|
385
|
+
declare function AuthEmailVerificationStep({ email, title, description, method, onVerifyCode, }: AuthEmailVerificationStepProps): react_jsx_runtime.JSX.Element;
|
|
386
|
+
|
|
387
|
+
export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthSubmitButton, AuthVerificationCodeInput, validatePasswordStrength };
|
package/dist/atoms.d.ts
CHANGED
|
@@ -361,6 +361,27 @@ declare function AuthOAuthProviders({ providers, onClick, disabled, loading, app
|
|
|
361
361
|
* - `appearance.containerClassName`: Container element
|
|
362
362
|
* - `appearance.inputClassName`: Input elements
|
|
363
363
|
*/
|
|
364
|
-
declare function AuthVerificationCodeInput({ length, value, email, onChange, disabled, appearance, }: AuthVerificationCodeInputProps): react_jsx_runtime.JSX.Element;
|
|
364
|
+
declare function AuthVerificationCodeInput({ length, value, email, onChange, disabled, onComplete, appearance, }: AuthVerificationCodeInputProps): react_jsx_runtime.JSX.Element;
|
|
365
365
|
|
|
366
|
-
|
|
366
|
+
type VerificationMethod = 'code' | 'link';
|
|
367
|
+
interface AuthEmailVerificationStepProps {
|
|
368
|
+
email: string;
|
|
369
|
+
title?: string;
|
|
370
|
+
description?: string;
|
|
371
|
+
method?: VerificationMethod;
|
|
372
|
+
onVerifyCode?: (code: string) => Promise<void>;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Email verification step component
|
|
376
|
+
*
|
|
377
|
+
* Handles the email verification flow:
|
|
378
|
+
* - Automatically sends verification email on mount
|
|
379
|
+
* - Shows countdown timer for resend functionality
|
|
380
|
+
* - Manages rate limiting for resend attempts
|
|
381
|
+
* - Supports both code and link verification methods
|
|
382
|
+
*
|
|
383
|
+
* @param method - 'code' for OTP input, 'link' for magic link (default: 'code')
|
|
384
|
+
*/
|
|
385
|
+
declare function AuthEmailVerificationStep({ email, title, description, method, onVerifyCode, }: AuthEmailVerificationStepProps): react_jsx_runtime.JSX.Element;
|
|
386
|
+
|
|
387
|
+
export { AuthBranding, AuthContainer, AuthDivider, AuthEmailVerificationStep, AuthErrorBanner, AuthFormField, AuthHeader, AuthLink, AuthOAuthButton, AuthOAuthProviders, AuthPasswordField, AuthPasswordStrengthIndicator, AuthSubmitButton, AuthVerificationCodeInput, validatePasswordStrength };
|
package/dist/atoms.js
CHANGED
|
@@ -5,6 +5,7 @@ var clsx = require('clsx');
|
|
|
5
5
|
var tailwindMerge = require('tailwind-merge');
|
|
6
6
|
var lucideReact = require('lucide-react');
|
|
7
7
|
var react = require('react');
|
|
8
|
+
var sdk = require('@insforge/sdk');
|
|
8
9
|
|
|
9
10
|
function AuthBranding() {
|
|
10
11
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "bg-[#FAFAFA] px-2 py-4 flex flex-row justify-center items-center gap-1", children: [
|
|
@@ -655,6 +656,7 @@ function AuthVerificationCodeInput({
|
|
|
655
656
|
email,
|
|
656
657
|
onChange,
|
|
657
658
|
disabled = false,
|
|
659
|
+
onComplete,
|
|
658
660
|
appearance = {}
|
|
659
661
|
}) {
|
|
660
662
|
const inputRefs = react.useRef([]);
|
|
@@ -668,6 +670,9 @@ function AuthVerificationCodeInput({
|
|
|
668
670
|
if (digit && index < length - 1) {
|
|
669
671
|
inputRefs.current[index + 1]?.focus();
|
|
670
672
|
}
|
|
673
|
+
if (digit && index === length - 1 && updatedValue.length === length && onComplete) {
|
|
674
|
+
onComplete(updatedValue);
|
|
675
|
+
}
|
|
671
676
|
};
|
|
672
677
|
const handleKeyDown = (index, e) => {
|
|
673
678
|
if (e.key === "Backspace") {
|
|
@@ -688,6 +693,9 @@ function AuthVerificationCodeInput({
|
|
|
688
693
|
if (/^\d+$/.test(pastedData) && pastedData.length === length) {
|
|
689
694
|
onChange(pastedData);
|
|
690
695
|
inputRefs.current[length - 1]?.focus();
|
|
696
|
+
if (onComplete) {
|
|
697
|
+
onComplete(pastedData);
|
|
698
|
+
}
|
|
691
699
|
}
|
|
692
700
|
};
|
|
693
701
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: cn(
|
|
@@ -728,10 +736,141 @@ function AuthVerificationCodeInput({
|
|
|
728
736
|
)) })
|
|
729
737
|
] });
|
|
730
738
|
}
|
|
739
|
+
var InsforgeContext = react.createContext(
|
|
740
|
+
void 0
|
|
741
|
+
);
|
|
742
|
+
function useInsforge() {
|
|
743
|
+
const context = react.useContext(InsforgeContext);
|
|
744
|
+
if (!context) {
|
|
745
|
+
throw new Error("useInsforge must be used within InsforgeProvider");
|
|
746
|
+
}
|
|
747
|
+
return context;
|
|
748
|
+
}
|
|
749
|
+
function AuthEmailVerificationStep({
|
|
750
|
+
email,
|
|
751
|
+
title = "Verify Your Email",
|
|
752
|
+
description,
|
|
753
|
+
method = "code",
|
|
754
|
+
onVerifyCode
|
|
755
|
+
}) {
|
|
756
|
+
const { baseUrl } = useInsforge();
|
|
757
|
+
const [insforge] = react.useState(() => sdk.createClient({ baseUrl }));
|
|
758
|
+
const [resendDisabled, setResendDisabled] = react.useState(true);
|
|
759
|
+
const [resendCountdown, setResendCountdown] = react.useState(60);
|
|
760
|
+
const [isSending, setIsSending] = react.useState(false);
|
|
761
|
+
const [verificationCode, setVerificationCode] = react.useState("");
|
|
762
|
+
const [isVerifying, setIsVerifying] = react.useState(false);
|
|
763
|
+
const [verificationError, setVerificationError] = react.useState("");
|
|
764
|
+
const defaultDescription = method === "code" ? "We've sent a 6-digit verification code to {email}. Please enter it below to verify your account. The code will expire in 10 minutes." : "We've sent a verification link to {email}. Please check your email and click the link to verify your account. The link will expire in 10 minutes.";
|
|
765
|
+
react.useEffect(() => {
|
|
766
|
+
const sendInitialEmail = async () => {
|
|
767
|
+
try {
|
|
768
|
+
if (method === "code") {
|
|
769
|
+
await insforge.auth.sendVerificationCode({ email });
|
|
770
|
+
} else {
|
|
771
|
+
await insforge.auth.sendVerificationLink({ email });
|
|
772
|
+
}
|
|
773
|
+
} catch {
|
|
774
|
+
}
|
|
775
|
+
};
|
|
776
|
+
void sendInitialEmail();
|
|
777
|
+
}, [email, method, insforge.auth]);
|
|
778
|
+
react.useEffect(() => {
|
|
779
|
+
if (resendCountdown > 0) {
|
|
780
|
+
const timer = setInterval(() => {
|
|
781
|
+
setResendCountdown((prev) => {
|
|
782
|
+
if (prev <= 1) {
|
|
783
|
+
setResendDisabled(false);
|
|
784
|
+
return 0;
|
|
785
|
+
}
|
|
786
|
+
return prev - 1;
|
|
787
|
+
});
|
|
788
|
+
}, 1e3);
|
|
789
|
+
return () => clearInterval(timer);
|
|
790
|
+
}
|
|
791
|
+
}, [resendCountdown]);
|
|
792
|
+
const handleResend = async () => {
|
|
793
|
+
setResendDisabled(true);
|
|
794
|
+
setResendCountdown(60);
|
|
795
|
+
setIsSending(true);
|
|
796
|
+
setVerificationError("");
|
|
797
|
+
try {
|
|
798
|
+
if (method === "code") {
|
|
799
|
+
await insforge.auth.sendVerificationCode({ email });
|
|
800
|
+
} else {
|
|
801
|
+
await insforge.auth.sendVerificationLink({ email });
|
|
802
|
+
}
|
|
803
|
+
} catch {
|
|
804
|
+
setResendDisabled(false);
|
|
805
|
+
setResendCountdown(0);
|
|
806
|
+
} finally {
|
|
807
|
+
setIsSending(false);
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
const handleVerifyCode = async (code) => {
|
|
811
|
+
if (!onVerifyCode) {
|
|
812
|
+
return;
|
|
813
|
+
}
|
|
814
|
+
setIsVerifying(true);
|
|
815
|
+
setVerificationError("");
|
|
816
|
+
try {
|
|
817
|
+
await onVerifyCode(code);
|
|
818
|
+
} catch (error) {
|
|
819
|
+
setVerificationError(
|
|
820
|
+
error instanceof Error ? error.message : "Invalid verification code. Please try again."
|
|
821
|
+
);
|
|
822
|
+
setVerificationCode("");
|
|
823
|
+
} finally {
|
|
824
|
+
setIsVerifying(false);
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
const displayDescription = description || defaultDescription;
|
|
828
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full flex flex-col gap-6 items-center", children: [
|
|
829
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full bg-neutral-100 dark:bg-neutral-800 rounded-lg px-4 pt-4 pb-6 flex flex-col gap-4", children: [
|
|
830
|
+
/* @__PURE__ */ jsxRuntime.jsx("h2", { className: "text-lg font-semibold text-black dark:text-white", children: title }),
|
|
831
|
+
/* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-neutral-600 dark:text-neutral-400 text-sm leading-relaxed", children: displayDescription.split("{email}").map((part, index, array) => /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
|
|
832
|
+
part,
|
|
833
|
+
index < array.length - 1 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "font-medium text-black dark:text-white", children: email })
|
|
834
|
+
] }, index)) }),
|
|
835
|
+
method === "code" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-3 mt-2", children: [
|
|
836
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
837
|
+
AuthVerificationCodeInput,
|
|
838
|
+
{
|
|
839
|
+
value: verificationCode,
|
|
840
|
+
onChange: setVerificationCode,
|
|
841
|
+
email,
|
|
842
|
+
disabled: isVerifying,
|
|
843
|
+
onComplete: (code) => {
|
|
844
|
+
void handleVerifyCode(code);
|
|
845
|
+
}
|
|
846
|
+
}
|
|
847
|
+
),
|
|
848
|
+
verificationError && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-red-600 dark:text-red-400 text-center", children: verificationError }),
|
|
849
|
+
isVerifying && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "text-sm text-neutral-600 dark:text-neutral-400 text-center", children: "Verifying..." })
|
|
850
|
+
] })
|
|
851
|
+
] }),
|
|
852
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "w-full text-sm text-center text-neutral-600 dark:text-neutral-400", children: [
|
|
853
|
+
"Didn't receive the email?",
|
|
854
|
+
" ",
|
|
855
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
856
|
+
"button",
|
|
857
|
+
{
|
|
858
|
+
onClick: () => {
|
|
859
|
+
void handleResend();
|
|
860
|
+
},
|
|
861
|
+
disabled: resendDisabled || isSending,
|
|
862
|
+
className: "text-black dark:text-white font-medium transition-colors disabled:cursor-not-allowed cursor-pointer hover:underline disabled:no-underline disabled:opacity-50",
|
|
863
|
+
children: isSending ? "Sending..." : resendDisabled ? `Retry in (${resendCountdown}s)` : "Click to resend"
|
|
864
|
+
}
|
|
865
|
+
)
|
|
866
|
+
] })
|
|
867
|
+
] });
|
|
868
|
+
}
|
|
731
869
|
|
|
732
870
|
exports.AuthBranding = AuthBranding;
|
|
733
871
|
exports.AuthContainer = AuthContainer;
|
|
734
872
|
exports.AuthDivider = AuthDivider;
|
|
873
|
+
exports.AuthEmailVerificationStep = AuthEmailVerificationStep;
|
|
735
874
|
exports.AuthErrorBanner = AuthErrorBanner;
|
|
736
875
|
exports.AuthFormField = AuthFormField;
|
|
737
876
|
exports.AuthHeader = AuthHeader;
|