@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.
Files changed (59) hide show
  1. package/README.md +218 -0
  2. package/dist/auth/application/hooks/useForgotPasswordFlow.d.ts +10 -0
  3. package/dist/auth/application/hooks/useForgotPasswordFlow.js +45 -0
  4. package/dist/auth/application/hooks/useLoginFlow.d.ts +30 -0
  5. package/dist/auth/application/hooks/useLoginFlow.js +105 -0
  6. package/dist/auth/application/hooks/useSetPasswordFlow.d.ts +18 -0
  7. package/dist/auth/application/hooks/useSetPasswordFlow.js +59 -0
  8. package/dist/auth/application/hooks/useVerifyOtpFlow.d.ts +18 -0
  9. package/dist/auth/application/hooks/useVerifyOtpFlow.js +84 -0
  10. package/dist/auth/application/services/authService.d.ts +26 -0
  11. package/dist/auth/application/services/authService.js +90 -0
  12. package/dist/auth/domain/otp.d.ts +25 -0
  13. package/dist/auth/domain/otp.js +41 -0
  14. package/dist/auth/domain/passwordRules.d.ts +12 -0
  15. package/dist/auth/domain/passwordRules.js +34 -0
  16. package/dist/auth/domain/types.d.ts +35 -0
  17. package/dist/auth/domain/types.js +2 -0
  18. package/dist/components/AuthLayout.d.ts +20 -0
  19. package/dist/components/AuthLayout.js +49 -0
  20. package/dist/components/PoweredBy.d.ts +10 -0
  21. package/dist/components/PoweredBy.js +50 -0
  22. package/dist/components/email/baseTemplate.d.ts +13 -0
  23. package/dist/components/email/baseTemplate.js +69 -0
  24. package/dist/components/email/constants.d.ts +26 -0
  25. package/dist/components/email/constants.js +30 -0
  26. package/dist/components/email/index.d.ts +7 -0
  27. package/dist/components/email/index.js +7 -0
  28. package/dist/components/email/templates/otp.d.ts +16 -0
  29. package/dist/components/email/templates/otp.js +38 -0
  30. package/dist/components/email/templates/passwordChanged.d.ts +15 -0
  31. package/dist/components/email/templates/passwordChanged.js +33 -0
  32. package/dist/components/email/templates/passwordReset.d.ts +15 -0
  33. package/dist/components/email/templates/passwordReset.js +36 -0
  34. package/dist/components/email/templates/welcome.d.ts +16 -0
  35. package/dist/components/email/templates/welcome.js +38 -0
  36. package/dist/components/email/translations.d.ts +45 -0
  37. package/dist/components/email/translations.js +88 -0
  38. package/dist/components/pages/ForgotPasswordPage.d.ts +5 -0
  39. package/dist/components/pages/ForgotPasswordPage.js +45 -0
  40. package/dist/components/pages/LoginPage.d.ts +11 -0
  41. package/dist/components/pages/LoginPage.js +222 -0
  42. package/dist/components/pages/SetPasswordPage.d.ts +5 -0
  43. package/dist/components/pages/SetPasswordPage.js +74 -0
  44. package/dist/components/pages/SignupPage.d.ts +10 -0
  45. package/dist/components/pages/SignupPage.js +129 -0
  46. package/dist/components/pages/VerifyOtpPage.d.ts +5 -0
  47. package/dist/components/pages/VerifyOtpPage.js +87 -0
  48. package/dist/components/ui/index.d.ts +57 -0
  49. package/dist/components/ui/index.js +121 -0
  50. package/dist/css.d.js +0 -0
  51. package/dist/endpoints/authEndpoints.d.ts +22 -0
  52. package/dist/endpoints/authEndpoints.js +422 -0
  53. package/dist/exports/client.d.ts +24 -0
  54. package/dist/exports/client.js +22 -0
  55. package/dist/exports/rsc.d.ts +6 -0
  56. package/dist/exports/rsc.js +5 -0
  57. package/dist/index.d.ts +12 -0
  58. package/dist/index.js +16 -0
  59. package/package.json +115 -0
@@ -0,0 +1,15 @@
1
+ import { type SocialLink } from '../constants.js';
2
+ import { type BaseTemplateOptions } from '../baseTemplate.js';
3
+ import { type SupportedLanguage } from '../translations.js';
4
+ export interface PasswordResetEmailParams {
5
+ userName: string;
6
+ otp: string;
7
+ language?: SupportedLanguage;
8
+ socialLinks?: SocialLink[];
9
+ baseOptions?: BaseTemplateOptions;
10
+ }
11
+ export interface PasswordResetEmailResult {
12
+ subject: string;
13
+ html: string;
14
+ }
15
+ export declare function generatePasswordResetEmail(params: PasswordResetEmailParams): PasswordResetEmailResult;
@@ -0,0 +1,36 @@
1
+ import { DEFAULT_COLORS } from '../constants.js';
2
+ import { wrapInBaseTemplate } from '../baseTemplate.js';
3
+ import { getEmailTranslations } from '../translations.js';
4
+ export function generatePasswordResetEmail(params) {
5
+ const { userName, otp, language = 'en', socialLinks, baseOptions } = params;
6
+ const t = getEmailTranslations(language);
7
+ const content = `
8
+ <tr>
9
+ <td style="text-align:center;padding-bottom:32px;">
10
+ <h1 style="margin:0 0 12px;font-size:28px;font-weight:600;color:${DEFAULT_COLORS.text};">${t.passwordReset.title}</h1>
11
+ <p style="margin:0;font-size:17px;color:${DEFAULT_COLORS.textSecondary};line-height:1.5;">${t.greeting} ${userName}, ${t.passwordReset.intro}</p>
12
+ </td>
13
+ </tr>
14
+ <tr>
15
+ <td style="text-align:center;padding-bottom:32px;">
16
+ <div style="display:inline-block;background-color:${DEFAULT_COLORS.backgroundSecondary};border-radius:12px;padding:20px 32px;">
17
+ <span style="font-size:32px;font-weight:600;letter-spacing:6px;color:${DEFAULT_COLORS.text};font-family:'SF Mono',SFMono-Regular,ui-monospace,Menlo,monospace;">${otp}</span>
18
+ </div>
19
+ </td>
20
+ </tr>
21
+ <tr>
22
+ <td style="text-align:center;">
23
+ <p style="margin:0 0 8px;font-size:14px;color:${DEFAULT_COLORS.textTertiary};">${t.passwordReset.expiresIn} <span style="color:${DEFAULT_COLORS.textSecondary};">10 ${language === 'es' ? 'minutos' : 'minutes'}</span></p>
24
+ <p style="margin:0;font-size:13px;color:${DEFAULT_COLORS.textTertiary};">${t.passwordReset.warningMessage}</p>
25
+ </td>
26
+ </tr>`;
27
+ return {
28
+ subject: t.passwordReset.subject,
29
+ html: wrapInBaseTemplate(content, {
30
+ ...baseOptions,
31
+ preheader: `${t.passwordReset.preheader}: ${otp}`,
32
+ language,
33
+ socialLinks
34
+ })
35
+ };
36
+ }
@@ -0,0 +1,16 @@
1
+ import { type SocialLink } from '../constants.js';
2
+ import { type BaseTemplateOptions } from '../baseTemplate.js';
3
+ import { type SupportedLanguage } from '../translations.js';
4
+ export interface WelcomeEmailParams {
5
+ userName: string;
6
+ userEmail?: string;
7
+ loginUrl?: string;
8
+ language?: SupportedLanguage;
9
+ socialLinks?: SocialLink[];
10
+ baseOptions?: BaseTemplateOptions;
11
+ }
12
+ export interface WelcomeEmailResult {
13
+ subject: string;
14
+ html: string;
15
+ }
16
+ export declare function generateWelcomeEmail(params: WelcomeEmailParams): WelcomeEmailResult;
@@ -0,0 +1,38 @@
1
+ import { DEFAULT_COLORS, getBaseUrl } from '../constants.js';
2
+ import { wrapInBaseTemplate } from '../baseTemplate.js';
3
+ import { getEmailTranslations } from '../translations.js';
4
+ export function generateWelcomeEmail(params) {
5
+ const { userName, userEmail, loginUrl = `${getBaseUrl()}/login`, language = 'en', socialLinks, baseOptions } = params;
6
+ const t = getEmailTranslations(language);
7
+ const content = `
8
+ <tr>
9
+ <td style="text-align:center;padding:24px 16px 8px;">
10
+ <h1 style="margin:0;font-size:32px;font-weight:700;color:${DEFAULT_COLORS.text};letter-spacing:-0.02em;">${t.welcome.title}</h1>
11
+ </td>
12
+ </tr>
13
+ <tr>
14
+ <td style="text-align:center;padding:16px 16px 32px;line-height:1.6;color:${DEFAULT_COLORS.textSecondary};">
15
+ <p style="margin:0;font-size:16px;">${t.welcome.introMessage}</p>
16
+ </td>
17
+ </tr>
18
+ <tr>
19
+ <td style="text-align:center;padding:16px;">
20
+ <a href="${loginUrl}" style="display:inline-block;background-color:${DEFAULT_COLORS.primary};color:${DEFAULT_COLORS.primaryText};font-weight:600;text-decoration:none;padding:14px 40px;border-radius:980px;font-size:16px;">${t.welcome.ctaButton}</a>
21
+ </td>
22
+ </tr>
23
+ <tr>
24
+ <td style="text-align:center;padding:24px 16px 8px;">
25
+ <p style="margin:0;font-size:14px;color:${DEFAULT_COLORS.textTertiary};line-height:1.6;">${t.welcome.helpMessage}</p>
26
+ </td>
27
+ </tr>`;
28
+ return {
29
+ subject: t.welcome.subject,
30
+ html: wrapInBaseTemplate(content, {
31
+ ...baseOptions,
32
+ preheader: t.welcome.preheader,
33
+ language,
34
+ socialLinks,
35
+ userEmail
36
+ })
37
+ };
38
+ }
@@ -0,0 +1,45 @@
1
+ export type SupportedLanguage = 'en' | 'es';
2
+ export interface EmailTranslations {
3
+ greeting: string;
4
+ footerCopyright: string;
5
+ footerTagline: string;
6
+ footerContactMessage: string;
7
+ footerEmailSentTo: string;
8
+ footerSecurityNotice: string;
9
+ otp: {
10
+ subjectLogin: string;
11
+ subjectPasswordReset: string;
12
+ preheader: string;
13
+ purposeLogin: string;
14
+ purposePasswordReset: string;
15
+ expiresIn: string;
16
+ ignoreMessage: string;
17
+ };
18
+ welcome: {
19
+ subject: string;
20
+ preheader: string;
21
+ title: string;
22
+ introMessage: string;
23
+ ctaButton: string;
24
+ helpMessage: string;
25
+ };
26
+ passwordReset: {
27
+ subject: string;
28
+ preheader: string;
29
+ title: string;
30
+ intro: string;
31
+ expiresIn: string;
32
+ warningMessage: string;
33
+ };
34
+ passwordChanged: {
35
+ subject: string;
36
+ preheader: string;
37
+ title: string;
38
+ message: string;
39
+ warningMessage: string;
40
+ ctaButton: string;
41
+ };
42
+ }
43
+ declare const translations: Record<SupportedLanguage, EmailTranslations>;
44
+ export declare function getEmailTranslations(language?: SupportedLanguage): EmailTranslations;
45
+ export default translations;
@@ -0,0 +1,88 @@
1
+ const translations = {
2
+ en: {
3
+ greeting: 'Hi',
4
+ footerCopyright: 'All rights reserved.',
5
+ footerTagline: 'Powered by Main12',
6
+ footerContactMessage: 'If you have any issues, contact us at',
7
+ footerEmailSentTo: 'This email was sent to',
8
+ footerSecurityNotice: "If you don't recognize this action, please contact us.",
9
+ otp: {
10
+ subjectLogin: 'Your verification code',
11
+ subjectPasswordReset: 'Your password reset code',
12
+ preheader: 'Your verification code is',
13
+ purposeLogin: 'Use this code to sign in to your account:',
14
+ purposePasswordReset: 'Use this code to reset your password:',
15
+ expiresIn: 'This code expires in',
16
+ ignoreMessage: "If you didn't request this code, you can safely ignore this email."
17
+ },
18
+ welcome: {
19
+ subject: 'Welcome! 🎉',
20
+ preheader: 'Your account is ready',
21
+ title: 'Welcome',
22
+ introMessage: 'Your account is ready. Start exploring and get the most out of the platform.',
23
+ ctaButton: 'Get Started',
24
+ helpMessage: "Questions? We're here to help. Just reply to this email anytime."
25
+ },
26
+ passwordReset: {
27
+ subject: 'Reset your password',
28
+ preheader: 'Your password reset code is',
29
+ title: 'Reset your password',
30
+ intro: 'We received a request to reset your password. Use this code to continue:',
31
+ expiresIn: 'This code expires in',
32
+ warningMessage: "If you didn't request a password reset, please ignore this email or contact support."
33
+ },
34
+ passwordChanged: {
35
+ subject: 'Your password has been updated',
36
+ preheader: 'Your password has been changed successfully.',
37
+ title: 'Password updated',
38
+ message: 'Your password has been successfully changed. You can now use your new password to sign in.',
39
+ warningMessage: "If you didn't make this change, please reset your password immediately and contact support.",
40
+ ctaButton: 'Sign In'
41
+ }
42
+ },
43
+ es: {
44
+ greeting: 'Hola',
45
+ footerCopyright: 'Todos los derechos reservados.',
46
+ footerTagline: 'Desarrollado por Main12',
47
+ footerContactMessage: 'Si tienes algún problema, contáctanos a',
48
+ footerEmailSentTo: 'Este correo fue enviado a',
49
+ footerSecurityNotice: 'Si no reconoces esta acción, por favor contáctanos.',
50
+ otp: {
51
+ subjectLogin: 'Tu código de verificación',
52
+ subjectPasswordReset: 'Tu código para restablecer la contraseña',
53
+ preheader: 'Tu código de verificación es',
54
+ purposeLogin: 'Usa este código para iniciar sesión en tu cuenta:',
55
+ purposePasswordReset: 'Usa este código para restablecer tu contraseña:',
56
+ expiresIn: 'Este código expira en',
57
+ ignoreMessage: 'Si no solicitaste este código, puedes ignorar este correo.'
58
+ },
59
+ welcome: {
60
+ subject: '¡Bienvenido! 🎉',
61
+ preheader: 'Tu cuenta está lista',
62
+ title: 'Bienvenido',
63
+ introMessage: 'Tu cuenta está lista. Comienza a explorar y aprovecha la plataforma al máximo.',
64
+ ctaButton: 'Comenzar',
65
+ helpMessage: '¿Preguntas? Estamos aquí para ayudar. Solo responde a este correo.'
66
+ },
67
+ passwordReset: {
68
+ subject: 'Restablece tu contraseña',
69
+ preheader: 'Tu código para restablecer la contraseña es',
70
+ title: 'Restablece tu contraseña',
71
+ intro: 'Recibimos una solicitud para restablecer tu contraseña. Usa este código:',
72
+ expiresIn: 'Este código expira en',
73
+ warningMessage: 'Si no solicitaste restablecer tu contraseña, ignora este correo o contacta a soporte.'
74
+ },
75
+ passwordChanged: {
76
+ subject: 'Tu contraseña ha sido actualizada',
77
+ preheader: 'Tu contraseña ha sido cambiada exitosamente.',
78
+ title: 'Contraseña actualizada',
79
+ message: 'Tu contraseña ha sido cambiada exitosamente. Ahora puedes usar tu nueva contraseña.',
80
+ warningMessage: 'Si no realizaste este cambio, restablece tu contraseña inmediatamente y contacta a soporte.',
81
+ ctaButton: 'Iniciar Sesión'
82
+ }
83
+ }
84
+ };
85
+ export function getEmailTranslations(language = 'en') {
86
+ return translations[language] || translations.en;
87
+ }
88
+ export default translations;
@@ -0,0 +1,5 @@
1
+ import type { AuthLayoutConfig } from '../AuthLayout.js';
2
+ export interface ForgotPasswordPageProps extends AuthLayoutConfig {
3
+ loginUrl?: string;
4
+ }
5
+ export default function ForgotPasswordPage({ loginUrl, logo, poweredBy, cardClassName, backgroundClass, }: ForgotPasswordPageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,45 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from 'react';
4
+ import { Button, Input } from '../ui/index.js';
5
+ import { useForgotPasswordFlow } from '../../auth/application/hooks/useForgotPasswordFlow.js';
6
+ import { AuthLayout } from '../AuthLayout.js';
7
+ export default function ForgotPasswordPage({ loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass }) {
8
+ const { email, error, isLoading, setEmail, handleSubmit } = useForgotPasswordFlow();
9
+ return /*#__PURE__*/ _jsx(AuthLayout, {
10
+ logo: logo,
11
+ title: "Forgot Password",
12
+ subtitle: "Enter your email and we'll send you a reset code",
13
+ poweredBy: poweredBy,
14
+ cardClassName: cardClassName,
15
+ backgroundClass: backgroundClass,
16
+ footer: /*#__PURE__*/ _jsx("a", {
17
+ href: loginUrl,
18
+ className: "text-sm text-gray-600 hover:text-gray-900 inline-flex items-center gap-1",
19
+ children: "← Back to Login"
20
+ }),
21
+ children: /*#__PURE__*/ _jsxs("form", {
22
+ onSubmit: handleSubmit,
23
+ className: "space-y-4",
24
+ children: [
25
+ error && /*#__PURE__*/ _jsx("div", {
26
+ className: "bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm animate-[fadeIn_0.2s_ease-out]",
27
+ children: error
28
+ }),
29
+ /*#__PURE__*/ _jsx(Input, {
30
+ type: "email",
31
+ label: "Email",
32
+ value: email,
33
+ onChange: (e)=>setEmail(e.target.value),
34
+ isRequired: true
35
+ }),
36
+ /*#__PURE__*/ _jsx(Button, {
37
+ type: "submit",
38
+ variant: "primary",
39
+ isLoading: isLoading,
40
+ children: "Send Reset Code"
41
+ })
42
+ ]
43
+ })
44
+ });
45
+ }
@@ -0,0 +1,11 @@
1
+ import type { AuthLayoutConfig } from '../AuthLayout.js';
2
+ export interface LoginPageProps extends AuthLayoutConfig {
3
+ onPasswordLogin: (credentials: {
4
+ email: string;
5
+ password: string;
6
+ }) => Promise<void>;
7
+ redirectTo?: string;
8
+ showGoogleOAuth?: boolean;
9
+ signupUrl?: string;
10
+ }
11
+ export default function LoginPage(props: LoginPageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,222 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import React, { Suspense } from 'react';
4
+ import { useSearchParams } from 'next/navigation';
5
+ import { Button, Input, Divider, Spinner } from '../ui/index.js';
6
+ import { useLoginFlow } from '../../auth/application/hooks/useLoginFlow.js';
7
+ import { AuthLayout } from '../AuthLayout.js';
8
+ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = true, signupUrl = '/signup', logo, poweredBy, cardClassName, backgroundClass }) {
9
+ const searchParams = useSearchParams();
10
+ const resolvedRedirect = searchParams.get('redirect') || redirectTo;
11
+ const { step, email, password, error, isLoading, isSendingOtp, showPassword, setEmail, setPassword, setShowPassword, handleEmailSubmit, handlePasswordSubmit, handleSendOtp, handleEditEmail, handleGoogleLogin } = useLoginFlow({
12
+ redirectTo: resolvedRedirect,
13
+ onPasswordLogin
14
+ });
15
+ const stepTitle = step === 'otp-prompt' ? 'Verify Identity' : step === 'email' ? 'Welcome Back' : 'Enter Password';
16
+ const stepSubtitle = step === 'otp-prompt' ? "We need to verify it's you." : step === 'email' ? 'Sign in with your email to continue.' : 'Enter your password to sign in.';
17
+ return /*#__PURE__*/ _jsxs(AuthLayout, {
18
+ logo: logo,
19
+ title: stepTitle,
20
+ subtitle: stepSubtitle,
21
+ poweredBy: poweredBy,
22
+ cardClassName: cardClassName,
23
+ backgroundClass: backgroundClass,
24
+ footer: /*#__PURE__*/ _jsxs("p", {
25
+ className: "text-center text-gray-600 text-sm",
26
+ children: [
27
+ "Don't have an account?",
28
+ ' ',
29
+ /*#__PURE__*/ _jsx("a", {
30
+ href: signupUrl,
31
+ className: "text-gray-900 font-medium hover:underline",
32
+ children: "Sign up"
33
+ })
34
+ ]
35
+ }),
36
+ children: [
37
+ step === 'email' && /*#__PURE__*/ _jsxs("div", {
38
+ className: "animate-[fadeIn_0.3s_ease-out]",
39
+ children: [
40
+ showGoogleOAuth && /*#__PURE__*/ _jsxs(_Fragment, {
41
+ children: [
42
+ /*#__PURE__*/ _jsxs(Button, {
43
+ fullWidth: true,
44
+ variant: "bordered",
45
+ size: "lg",
46
+ className: "mb-4",
47
+ onPress: handleGoogleLogin,
48
+ children: [
49
+ /*#__PURE__*/ _jsx("span", {
50
+ className: "text-lg",
51
+ children: "G"
52
+ }),
53
+ " Continue with Google"
54
+ ]
55
+ }),
56
+ /*#__PURE__*/ _jsxs("div", {
57
+ className: "flex items-center gap-4 my-4",
58
+ children: [
59
+ /*#__PURE__*/ _jsx(Divider, {
60
+ className: "flex-1"
61
+ }),
62
+ /*#__PURE__*/ _jsx("span", {
63
+ className: "text-gray-500 text-sm",
64
+ children: "or"
65
+ }),
66
+ /*#__PURE__*/ _jsx(Divider, {
67
+ className: "flex-1"
68
+ })
69
+ ]
70
+ })
71
+ ]
72
+ }),
73
+ /*#__PURE__*/ _jsxs("form", {
74
+ onSubmit: handleEmailSubmit,
75
+ className: "space-y-4",
76
+ children: [
77
+ error && /*#__PURE__*/ _jsx("div", {
78
+ className: "bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm",
79
+ children: error
80
+ }),
81
+ /*#__PURE__*/ _jsx(Input, {
82
+ type: "email",
83
+ label: "Email",
84
+ value: email,
85
+ onValueChange: setEmail,
86
+ isRequired: true
87
+ }),
88
+ /*#__PURE__*/ _jsx(Button, {
89
+ type: "submit",
90
+ variant: "primary",
91
+ isLoading: isLoading,
92
+ children: "Continue"
93
+ })
94
+ ]
95
+ })
96
+ ]
97
+ }),
98
+ step === 'password' && /*#__PURE__*/ _jsxs("div", {
99
+ className: "animate-[fadeIn_0.3s_ease-out]",
100
+ children: [
101
+ /*#__PURE__*/ _jsxs("div", {
102
+ className: "flex items-center justify-between border border-gray-300 rounded-xl px-4 py-3 mb-4",
103
+ children: [
104
+ /*#__PURE__*/ _jsx("span", {
105
+ className: "text-gray-900 text-sm",
106
+ children: email
107
+ }),
108
+ /*#__PURE__*/ _jsx("button", {
109
+ type: "button",
110
+ onClick: handleEditEmail,
111
+ className: "text-gray-600 text-sm font-medium hover:text-gray-900",
112
+ children: "Edit"
113
+ })
114
+ ]
115
+ }),
116
+ /*#__PURE__*/ _jsxs("form", {
117
+ onSubmit: handlePasswordSubmit,
118
+ className: "space-y-4",
119
+ children: [
120
+ error && /*#__PURE__*/ _jsx("div", {
121
+ className: "bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm",
122
+ children: error
123
+ }),
124
+ /*#__PURE__*/ _jsxs("div", {
125
+ className: "relative",
126
+ children: [
127
+ /*#__PURE__*/ _jsx(Input, {
128
+ type: showPassword ? 'text' : 'password',
129
+ label: "Password",
130
+ value: password,
131
+ onValueChange: setPassword,
132
+ isRequired: true,
133
+ autoFocus: true
134
+ }),
135
+ /*#__PURE__*/ _jsx("button", {
136
+ type: "button",
137
+ onClick: ()=>setShowPassword(!showPassword),
138
+ className: "absolute right-4 top-9 text-gray-400 hover:text-gray-600",
139
+ children: showPassword ? '🙈' : '👁'
140
+ })
141
+ ]
142
+ }),
143
+ /*#__PURE__*/ _jsx("div", {
144
+ className: "text-left",
145
+ children: /*#__PURE__*/ _jsx("a", {
146
+ href: "/forgot-password",
147
+ className: "text-sm text-gray-700 hover:text-gray-900 hover:underline",
148
+ children: "Forgot password?"
149
+ })
150
+ }),
151
+ /*#__PURE__*/ _jsx(Button, {
152
+ type: "submit",
153
+ variant: "primary",
154
+ isLoading: isLoading,
155
+ children: "Continue"
156
+ })
157
+ ]
158
+ })
159
+ ]
160
+ }),
161
+ step === 'otp-prompt' && /*#__PURE__*/ _jsxs("div", {
162
+ className: "animate-[fadeIn_0.3s_ease-out]",
163
+ children: [
164
+ /*#__PURE__*/ _jsxs("div", {
165
+ className: "flex items-center justify-between border border-gray-300 rounded-xl px-4 py-3 mb-4",
166
+ children: [
167
+ /*#__PURE__*/ _jsx("span", {
168
+ className: "text-gray-900 text-sm",
169
+ children: email
170
+ }),
171
+ /*#__PURE__*/ _jsx("button", {
172
+ type: "button",
173
+ onClick: handleEditEmail,
174
+ className: "text-gray-600 text-sm font-medium hover:text-gray-900",
175
+ children: "Edit"
176
+ })
177
+ ]
178
+ }),
179
+ error && /*#__PURE__*/ _jsx("div", {
180
+ className: "bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm mb-4",
181
+ children: error
182
+ }),
183
+ /*#__PURE__*/ _jsx("div", {
184
+ className: "bg-blue-50 border border-blue-200 rounded-lg p-4 mb-4",
185
+ children: /*#__PURE__*/ _jsxs("div", {
186
+ className: "flex gap-3",
187
+ children: [
188
+ /*#__PURE__*/ _jsx("span", {
189
+ className: "text-blue-500 text-lg",
190
+ children: "✉"
191
+ }),
192
+ /*#__PURE__*/ _jsx("p", {
193
+ className: "text-sm text-blue-700",
194
+ children: "We'll send a verification code to this email."
195
+ })
196
+ ]
197
+ })
198
+ }),
199
+ /*#__PURE__*/ _jsx(Button, {
200
+ variant: "primary",
201
+ isLoading: isSendingOtp,
202
+ onPress: handleSendOtp,
203
+ children: isSendingOtp ? 'Sending...' : 'Send Code'
204
+ })
205
+ ]
206
+ })
207
+ ]
208
+ });
209
+ }
210
+ export default function LoginPage(props) {
211
+ return /*#__PURE__*/ _jsx(Suspense, {
212
+ fallback: /*#__PURE__*/ _jsx("div", {
213
+ className: "min-h-screen flex items-center justify-center",
214
+ children: /*#__PURE__*/ _jsx(Spinner, {
215
+ size: "lg"
216
+ })
217
+ }),
218
+ children: /*#__PURE__*/ _jsx(LoginContent, {
219
+ ...props
220
+ })
221
+ });
222
+ }
@@ -0,0 +1,5 @@
1
+ import type { AuthLayoutConfig } from '../AuthLayout.js';
2
+ export interface SetPasswordPageProps extends AuthLayoutConfig {
3
+ redirectTo?: string;
4
+ }
5
+ export default function SetPasswordPage({ redirectTo, logo, poweredBy, cardClassName, backgroundClass, }: SetPasswordPageProps): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,74 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import React from 'react';
4
+ import { Button, Input } from '../ui/index.js';
5
+ import { useSetPasswordFlow } from '../../auth/application/hooks/useSetPasswordFlow.js';
6
+ import { AuthLayout } from '../AuthLayout.js';
7
+ export default function SetPasswordPage({ redirectTo = '/', logo, poweredBy, cardClassName, backgroundClass }) {
8
+ const { password, confirmPassword, error, isLoading, showPassword, strength, setPassword, setConfirmPassword, setShowPassword, handleSubmit } = useSetPasswordFlow({
9
+ redirectTo
10
+ });
11
+ const strengthBars = Array.from({
12
+ length: 5
13
+ }, (_, i)=>i < strength.score);
14
+ return /*#__PURE__*/ _jsx(AuthLayout, {
15
+ logo: logo,
16
+ title: "Set Your Password",
17
+ subtitle: "Create a secure password for your account",
18
+ poweredBy: poweredBy,
19
+ cardClassName: cardClassName,
20
+ backgroundClass: backgroundClass,
21
+ children: /*#__PURE__*/ _jsxs("form", {
22
+ onSubmit: handleSubmit,
23
+ className: "space-y-4",
24
+ children: [
25
+ error && /*#__PURE__*/ _jsx("div", {
26
+ className: "bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm animate-[fadeIn_0.2s_ease-out]",
27
+ children: error
28
+ }),
29
+ /*#__PURE__*/ _jsxs("div", {
30
+ className: "relative",
31
+ children: [
32
+ /*#__PURE__*/ _jsx(Input, {
33
+ type: showPassword ? 'text' : 'password',
34
+ label: "New Password",
35
+ value: password,
36
+ onValueChange: setPassword,
37
+ isRequired: true,
38
+ autoFocus: true
39
+ }),
40
+ /*#__PURE__*/ _jsx("button", {
41
+ type: "button",
42
+ onClick: ()=>setShowPassword(!showPassword),
43
+ className: "absolute right-4 top-9 text-gray-400 hover:text-gray-600",
44
+ children: showPassword ? '🙈' : '👁'
45
+ })
46
+ ]
47
+ }),
48
+ password.length > 0 && /*#__PURE__*/ _jsx("div", {
49
+ className: "flex gap-1",
50
+ children: strengthBars.map((active, i)=>/*#__PURE__*/ _jsx("div", {
51
+ className: `h-1 flex-1 rounded-full ${active ? 'bg-[#D5E855]' : 'bg-gray-200'}`
52
+ }, i))
53
+ }),
54
+ password.length > 0 && !strength.isValid && /*#__PURE__*/ _jsx("p", {
55
+ className: "text-xs text-gray-500",
56
+ children: "At least 8 chars with 3 of: uppercase, lowercase, number, special character"
57
+ }),
58
+ /*#__PURE__*/ _jsx(Input, {
59
+ type: showPassword ? 'text' : 'password',
60
+ label: "Confirm Password",
61
+ value: confirmPassword,
62
+ onValueChange: setConfirmPassword,
63
+ isRequired: true
64
+ }),
65
+ /*#__PURE__*/ _jsx(Button, {
66
+ type: "submit",
67
+ variant: "primary",
68
+ isLoading: isLoading,
69
+ children: "Set Password"
70
+ })
71
+ ]
72
+ })
73
+ });
74
+ }
@@ -0,0 +1,10 @@
1
+ import type { AuthLayoutConfig } from '../AuthLayout.js';
2
+ export interface SignupPageProps extends AuthLayoutConfig {
3
+ onSignup: (data: {
4
+ name: string;
5
+ email: string;
6
+ }) => Promise<void>;
7
+ showGoogleOAuth?: boolean;
8
+ loginUrl?: string;
9
+ }
10
+ export default function SignupPage({ onSignup, showGoogleOAuth, loginUrl, logo, poweredBy, cardClassName, backgroundClass, }: SignupPageProps): import("react/jsx-runtime").JSX.Element;