@main12/auth-login 0.3.8 → 0.4.1
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 +180 -4
- package/dist/components/AuthLayout.d.ts +9 -0
- package/dist/components/AuthPages.d.ts +15 -1
- package/dist/components/AuthPages.js +7 -1
- package/dist/components/AuthPagesServer.d.ts +6 -1
- package/dist/components/AuthPagesServer.js +11 -2
- package/dist/components/pages/ForgotPasswordPageHero.d.ts +1 -1
- package/dist/components/pages/ForgotPasswordPageHero.js +8 -6
- package/dist/components/pages/ForgotPasswordPageTailwind.d.ts +1 -1
- package/dist/components/pages/ForgotPasswordPageTailwind.js +12 -7
- package/dist/components/pages/LoginPageHero.js +18 -16
- package/dist/components/pages/LoginPageTailwind.js +18 -16
- package/dist/components/pages/SetPasswordPageHero.d.ts +1 -1
- package/dist/components/pages/SetPasswordPageHero.js +8 -6
- package/dist/components/pages/SetPasswordPageTailwind.d.ts +1 -1
- package/dist/components/pages/SetPasswordPageTailwind.js +9 -7
- package/dist/components/pages/SignupPageHero.d.ts +1 -1
- package/dist/components/pages/SignupPageHero.js +20 -14
- package/dist/components/pages/SignupPageTailwind.d.ts +1 -1
- package/dist/components/pages/SignupPageTailwind.js +17 -14
- package/dist/components/pages/VerifyOtpPageHero.js +9 -7
- package/dist/components/pages/VerifyOtpPageTailwind.js +13 -8
- package/dist/components/ui/locale.d.ts +29 -0
- package/dist/components/ui/locale.js +53 -0
- package/dist/components/ui/translations.d.ts +91 -0
- package/dist/components/ui/translations.js +179 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.js +3 -0
- package/package.json +1 -1
|
@@ -5,15 +5,17 @@ import { useSearchParams } from 'next/navigation';
|
|
|
5
5
|
import { Button, Input, Divider, Spinner } from '../ui/index.js';
|
|
6
6
|
import { useLoginFlow } from '../../auth/application/hooks/useLoginFlow.js';
|
|
7
7
|
import { AuthLayout } from '../AuthLayout.js';
|
|
8
|
-
|
|
8
|
+
import { getUiTranslations } from '../ui/translations.js';
|
|
9
|
+
function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = true, signupUrl = '/signup', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
|
|
9
10
|
const searchParams = useSearchParams();
|
|
10
11
|
const resolvedRedirect = searchParams.get('redirect') || redirectTo;
|
|
12
|
+
const t = getUiTranslations(locale, messages).login;
|
|
11
13
|
const { step, email, password, error, isLoading, isSendingOtp, showPassword, setEmail, setPassword, setShowPassword, handleEmailSubmit, handlePasswordSubmit, handleSendOtp, handleEditEmail, handleGoogleLogin } = useLoginFlow({
|
|
12
14
|
redirectTo: resolvedRedirect,
|
|
13
15
|
onPasswordLogin
|
|
14
16
|
});
|
|
15
|
-
const stepTitle = step === 'otp-prompt' ?
|
|
16
|
-
const stepSubtitle = step === 'otp-prompt' ?
|
|
17
|
+
const stepTitle = step === 'otp-prompt' ? t.otpPromptTitle : step === 'email' ? t.title : t.passwordStepTitle;
|
|
18
|
+
const stepSubtitle = step === 'otp-prompt' ? t.otpPromptSubtitle : step === 'email' ? t.subtitle : t.passwordStepSubtitle;
|
|
17
19
|
return /*#__PURE__*/ _jsxs(AuthLayout, {
|
|
18
20
|
logo: logo,
|
|
19
21
|
title: stepTitle,
|
|
@@ -24,12 +26,12 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
24
26
|
footer: signupUrl ? /*#__PURE__*/ _jsxs("p", {
|
|
25
27
|
className: "text-center text-gray-600 text-sm",
|
|
26
28
|
children: [
|
|
27
|
-
|
|
29
|
+
t.noAccount,
|
|
28
30
|
' ',
|
|
29
31
|
/*#__PURE__*/ _jsx("a", {
|
|
30
32
|
href: signupUrl,
|
|
31
33
|
className: "text-gray-900 font-medium hover:underline",
|
|
32
|
-
children:
|
|
34
|
+
children: t.signUpLink
|
|
33
35
|
})
|
|
34
36
|
]
|
|
35
37
|
}) : undefined,
|
|
@@ -69,7 +71,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
69
71
|
})
|
|
70
72
|
]
|
|
71
73
|
}),
|
|
72
|
-
|
|
74
|
+
t.continueWithGoogle
|
|
73
75
|
]
|
|
74
76
|
}),
|
|
75
77
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -80,7 +82,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
80
82
|
}),
|
|
81
83
|
/*#__PURE__*/ _jsx("span", {
|
|
82
84
|
className: "text-gray-500 text-sm",
|
|
83
|
-
children:
|
|
85
|
+
children: t.or
|
|
84
86
|
}),
|
|
85
87
|
/*#__PURE__*/ _jsx(Divider, {
|
|
86
88
|
className: "flex-1"
|
|
@@ -99,7 +101,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
99
101
|
}),
|
|
100
102
|
/*#__PURE__*/ _jsx(Input, {
|
|
101
103
|
type: "email",
|
|
102
|
-
label:
|
|
104
|
+
label: t.emailLabel,
|
|
103
105
|
value: email,
|
|
104
106
|
onValueChange: setEmail,
|
|
105
107
|
isRequired: true,
|
|
@@ -109,7 +111,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
109
111
|
type: "submit",
|
|
110
112
|
variant: "primary",
|
|
111
113
|
isLoading: isLoading,
|
|
112
|
-
children:
|
|
114
|
+
children: t.continue
|
|
113
115
|
})
|
|
114
116
|
]
|
|
115
117
|
})
|
|
@@ -129,7 +131,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
129
131
|
type: "button",
|
|
130
132
|
onClick: handleEditEmail,
|
|
131
133
|
className: "text-gray-600 text-sm font-medium hover:text-gray-900",
|
|
132
|
-
children:
|
|
134
|
+
children: t.edit
|
|
133
135
|
})
|
|
134
136
|
]
|
|
135
137
|
}),
|
|
@@ -143,7 +145,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
143
145
|
}),
|
|
144
146
|
/*#__PURE__*/ _jsx(Input, {
|
|
145
147
|
type: showPassword ? 'text' : 'password',
|
|
146
|
-
label:
|
|
148
|
+
label: t.passwordLabel,
|
|
147
149
|
value: password,
|
|
148
150
|
onValueChange: setPassword,
|
|
149
151
|
isRequired: true,
|
|
@@ -155,14 +157,14 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
155
157
|
children: /*#__PURE__*/ _jsx("a", {
|
|
156
158
|
href: "/forgot-password",
|
|
157
159
|
className: "text-sm text-gray-700 hover:text-gray-900 hover:underline",
|
|
158
|
-
children:
|
|
160
|
+
children: t.forgotPassword
|
|
159
161
|
})
|
|
160
162
|
}),
|
|
161
163
|
/*#__PURE__*/ _jsx(Button, {
|
|
162
164
|
type: "submit",
|
|
163
165
|
variant: "primary",
|
|
164
166
|
isLoading: isLoading,
|
|
165
|
-
children:
|
|
167
|
+
children: t.continue
|
|
166
168
|
})
|
|
167
169
|
]
|
|
168
170
|
})
|
|
@@ -182,7 +184,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
182
184
|
type: "button",
|
|
183
185
|
onClick: handleEditEmail,
|
|
184
186
|
className: "text-gray-600 text-sm font-medium hover:text-gray-900",
|
|
185
|
-
children:
|
|
187
|
+
children: t.edit
|
|
186
188
|
})
|
|
187
189
|
]
|
|
188
190
|
}),
|
|
@@ -201,7 +203,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
201
203
|
}),
|
|
202
204
|
/*#__PURE__*/ _jsx("p", {
|
|
203
205
|
className: "text-sm text-blue-700",
|
|
204
|
-
children:
|
|
206
|
+
children: t.verificationNotice
|
|
205
207
|
})
|
|
206
208
|
]
|
|
207
209
|
})
|
|
@@ -210,7 +212,7 @@ function LoginContent({ onPasswordLogin, redirectTo = '/', showGoogleOAuth = tru
|
|
|
210
212
|
variant: "primary",
|
|
211
213
|
isLoading: isSendingOtp,
|
|
212
214
|
onPress: handleSendOtp,
|
|
213
|
-
children: isSendingOtp ?
|
|
215
|
+
children: isSendingOtp ? t.sendingCode : t.sendCode
|
|
214
216
|
})
|
|
215
217
|
]
|
|
216
218
|
})
|
|
@@ -2,4 +2,4 @@ import type { AuthLayoutConfig } from '../AuthLayout';
|
|
|
2
2
|
export interface SetPasswordPageHeroProps extends AuthLayoutConfig {
|
|
3
3
|
redirectTo?: string;
|
|
4
4
|
}
|
|
5
|
-
export default function SetPasswordPageHero({ redirectTo, logo, poweredBy, cardClassName, backgroundClass }: SetPasswordPageHeroProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export default function SetPasswordPageHero({ redirectTo, logo, poweredBy, cardClassName, backgroundClass, locale, messages }: SetPasswordPageHeroProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,17 +6,19 @@ import { Icon } from '@iconify/react';
|
|
|
6
6
|
import { motion } from 'framer-motion';
|
|
7
7
|
import { useSetPasswordFlow } from '../../auth/application/hooks/useSetPasswordFlow.js';
|
|
8
8
|
import { AuthLayout } from '../AuthLayout.js';
|
|
9
|
-
|
|
9
|
+
import { getUiTranslations } from '../ui/translations.js';
|
|
10
|
+
export default function SetPasswordPageHero({ redirectTo = '/', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
|
|
10
11
|
const { password, confirmPassword, error, isLoading, showPassword, strength, setPassword, setConfirmPassword, setShowPassword, handleSubmit } = useSetPasswordFlow({
|
|
11
12
|
redirectTo
|
|
12
13
|
});
|
|
13
14
|
const bars = Array.from({
|
|
14
15
|
length: 5
|
|
15
16
|
}, (_, i)=>i < strength.score);
|
|
17
|
+
const t = getUiTranslations(locale, messages).setPassword;
|
|
16
18
|
return /*#__PURE__*/ _jsx(AuthLayout, {
|
|
17
19
|
logo: logo,
|
|
18
|
-
title:
|
|
19
|
-
subtitle:
|
|
20
|
+
title: t.title,
|
|
21
|
+
subtitle: t.subtitle,
|
|
20
22
|
poweredBy: poweredBy,
|
|
21
23
|
cardClassName: cardClassName,
|
|
22
24
|
backgroundClass: backgroundClass,
|
|
@@ -44,7 +46,7 @@ export default function SetPasswordPageHero({ redirectTo = '/', logo, poweredBy,
|
|
|
44
46
|
children: [
|
|
45
47
|
/*#__PURE__*/ _jsx(Label, {
|
|
46
48
|
className: "text-gray-600",
|
|
47
|
-
children:
|
|
49
|
+
children: t.newPasswordLabel
|
|
48
50
|
}),
|
|
49
51
|
/*#__PURE__*/ _jsxs("div", {
|
|
50
52
|
className: "relative",
|
|
@@ -82,7 +84,7 @@ export default function SetPasswordPageHero({ redirectTo = '/', logo, poweredBy,
|
|
|
82
84
|
children: [
|
|
83
85
|
/*#__PURE__*/ _jsx(Label, {
|
|
84
86
|
className: "text-gray-600",
|
|
85
|
-
children:
|
|
87
|
+
children: t.confirmPasswordLabel
|
|
86
88
|
}),
|
|
87
89
|
/*#__PURE__*/ _jsx(Input, {
|
|
88
90
|
variant: "secondary",
|
|
@@ -102,7 +104,7 @@ export default function SetPasswordPageHero({ redirectTo = '/', logo, poweredBy,
|
|
|
102
104
|
color: "current",
|
|
103
105
|
size: "sm"
|
|
104
106
|
}),
|
|
105
|
-
|
|
107
|
+
t.setPassword
|
|
106
108
|
]
|
|
107
109
|
})
|
|
108
110
|
})
|
|
@@ -2,4 +2,4 @@ import type { AuthLayoutConfig } from '../AuthLayout';
|
|
|
2
2
|
export interface SetPasswordPageProps extends AuthLayoutConfig {
|
|
3
3
|
redirectTo?: string;
|
|
4
4
|
}
|
|
5
|
-
export default function SetPasswordPage({ redirectTo, logo, poweredBy, cardClassName, backgroundClass, }: SetPasswordPageProps): import("react/jsx-runtime").JSX.Element;
|
|
5
|
+
export default function SetPasswordPage({ redirectTo, logo, poweredBy, cardClassName, backgroundClass, locale, messages, }: SetPasswordPageProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -4,17 +4,19 @@ import React from 'react';
|
|
|
4
4
|
import { Button, Input } from '../ui/index.js';
|
|
5
5
|
import { useSetPasswordFlow } from '../../auth/application/hooks/useSetPasswordFlow.js';
|
|
6
6
|
import { AuthLayout } from '../AuthLayout.js';
|
|
7
|
-
|
|
7
|
+
import { getUiTranslations } from '../ui/translations.js';
|
|
8
|
+
export default function SetPasswordPage({ redirectTo = '/', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
|
|
8
9
|
const { password, confirmPassword, error, isLoading, showPassword, strength, setPassword, setConfirmPassword, setShowPassword, handleSubmit } = useSetPasswordFlow({
|
|
9
10
|
redirectTo
|
|
10
11
|
});
|
|
11
12
|
const strengthBars = Array.from({
|
|
12
13
|
length: 5
|
|
13
14
|
}, (_, i)=>i < strength.score);
|
|
15
|
+
const t = getUiTranslations(locale, messages).setPassword;
|
|
14
16
|
return /*#__PURE__*/ _jsx(AuthLayout, {
|
|
15
17
|
logo: logo,
|
|
16
|
-
title:
|
|
17
|
-
subtitle:
|
|
18
|
+
title: t.title,
|
|
19
|
+
subtitle: t.subtitle,
|
|
18
20
|
poweredBy: poweredBy,
|
|
19
21
|
cardClassName: cardClassName,
|
|
20
22
|
backgroundClass: backgroundClass,
|
|
@@ -31,7 +33,7 @@ export default function SetPasswordPage({ redirectTo = '/', logo, poweredBy, car
|
|
|
31
33
|
children: [
|
|
32
34
|
/*#__PURE__*/ _jsx(Input, {
|
|
33
35
|
type: showPassword ? 'text' : 'password',
|
|
34
|
-
label:
|
|
36
|
+
label: t.newPasswordLabel,
|
|
35
37
|
value: password,
|
|
36
38
|
onValueChange: setPassword,
|
|
37
39
|
isRequired: true,
|
|
@@ -53,11 +55,11 @@ export default function SetPasswordPage({ redirectTo = '/', logo, poweredBy, car
|
|
|
53
55
|
}),
|
|
54
56
|
password.length > 0 && !strength.isValid && /*#__PURE__*/ _jsx("p", {
|
|
55
57
|
className: "text-xs text-gray-500",
|
|
56
|
-
children:
|
|
58
|
+
children: t.passwordRequirements
|
|
57
59
|
}),
|
|
58
60
|
/*#__PURE__*/ _jsx(Input, {
|
|
59
61
|
type: showPassword ? 'text' : 'password',
|
|
60
|
-
label:
|
|
62
|
+
label: t.confirmPasswordLabel,
|
|
61
63
|
value: confirmPassword,
|
|
62
64
|
onValueChange: setConfirmPassword,
|
|
63
65
|
isRequired: true
|
|
@@ -66,7 +68,7 @@ export default function SetPasswordPage({ redirectTo = '/', logo, poweredBy, car
|
|
|
66
68
|
type: "submit",
|
|
67
69
|
variant: "primary",
|
|
68
70
|
isLoading: isLoading,
|
|
69
|
-
children:
|
|
71
|
+
children: t.setPassword
|
|
70
72
|
})
|
|
71
73
|
]
|
|
72
74
|
})
|
|
@@ -7,4 +7,4 @@ export interface SignupPageHeroProps extends AuthLayoutConfig {
|
|
|
7
7
|
showGoogleOAuth?: boolean;
|
|
8
8
|
loginUrl?: string;
|
|
9
9
|
}
|
|
10
|
-
export default function SignupPageHero({ onSignup, showGoogleOAuth, loginUrl, logo, poweredBy, cardClassName, backgroundClass }: SignupPageHeroProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default function SignupPageHero({ onSignup, showGoogleOAuth, loginUrl, logo, poweredBy, cardClassName, backgroundClass, locale, messages }: SignupPageHeroProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -5,11 +5,13 @@ import { Button, Input, Label, TextField, Separator, Spinner } from '@heroui/rea
|
|
|
5
5
|
import { Icon } from '@iconify/react';
|
|
6
6
|
import { motion } from 'framer-motion';
|
|
7
7
|
import { AuthLayout } from '../AuthLayout.js';
|
|
8
|
-
|
|
8
|
+
import { getUiTranslations } from '../ui/translations.js';
|
|
9
|
+
export default function SignupPageHero({ onSignup, showGoogleOAuth = true, loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
|
|
9
10
|
const [name, setName] = React.useState('');
|
|
10
11
|
const [email, setEmail] = React.useState('');
|
|
11
12
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
12
13
|
const [error, setError] = React.useState(null);
|
|
14
|
+
const t = getUiTranslations(locale, messages).signup;
|
|
13
15
|
const handleSubmit = async (e)=>{
|
|
14
16
|
e.preventDefault();
|
|
15
17
|
setIsLoading(true);
|
|
@@ -28,19 +30,20 @@ export default function SignupPageHero({ onSignup, showGoogleOAuth = true, login
|
|
|
28
30
|
};
|
|
29
31
|
return /*#__PURE__*/ _jsxs(AuthLayout, {
|
|
30
32
|
logo: logo,
|
|
31
|
-
title:
|
|
32
|
-
subtitle:
|
|
33
|
+
title: t.title,
|
|
34
|
+
subtitle: t.subtitle,
|
|
33
35
|
poweredBy: poweredBy,
|
|
34
36
|
cardClassName: cardClassName,
|
|
35
37
|
backgroundClass: backgroundClass,
|
|
36
38
|
footer: /*#__PURE__*/ _jsxs("p", {
|
|
37
39
|
className: "text-center text-gray-600 text-sm",
|
|
38
40
|
children: [
|
|
39
|
-
|
|
41
|
+
t.haveAccount,
|
|
42
|
+
" ",
|
|
40
43
|
/*#__PURE__*/ _jsx("a", {
|
|
41
44
|
href: loginUrl,
|
|
42
45
|
className: "text-gray-900 font-medium hover:underline",
|
|
43
|
-
children:
|
|
46
|
+
children: t.loginLink
|
|
44
47
|
})
|
|
45
48
|
]
|
|
46
49
|
}),
|
|
@@ -57,7 +60,7 @@ export default function SignupPageHero({ onSignup, showGoogleOAuth = true, login
|
|
|
57
60
|
icon: "flat-color-icons:google",
|
|
58
61
|
width: 20
|
|
59
62
|
}),
|
|
60
|
-
|
|
63
|
+
t.continueWithGoogle
|
|
61
64
|
]
|
|
62
65
|
}),
|
|
63
66
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -68,7 +71,7 @@ export default function SignupPageHero({ onSignup, showGoogleOAuth = true, login
|
|
|
68
71
|
}),
|
|
69
72
|
/*#__PURE__*/ _jsx("span", {
|
|
70
73
|
className: "text-gray-500 text-sm",
|
|
71
|
-
children:
|
|
74
|
+
children: t.or
|
|
72
75
|
}),
|
|
73
76
|
/*#__PURE__*/ _jsx(Separator, {
|
|
74
77
|
className: "flex-1"
|
|
@@ -100,7 +103,7 @@ export default function SignupPageHero({ onSignup, showGoogleOAuth = true, login
|
|
|
100
103
|
children: [
|
|
101
104
|
/*#__PURE__*/ _jsx(Label, {
|
|
102
105
|
className: "text-gray-600",
|
|
103
|
-
children:
|
|
106
|
+
children: t.fullNameLabel
|
|
104
107
|
}),
|
|
105
108
|
/*#__PURE__*/ _jsx(Input, {
|
|
106
109
|
variant: "secondary"
|
|
@@ -116,7 +119,7 @@ export default function SignupPageHero({ onSignup, showGoogleOAuth = true, login
|
|
|
116
119
|
children: [
|
|
117
120
|
/*#__PURE__*/ _jsx(Label, {
|
|
118
121
|
className: "text-gray-600",
|
|
119
|
-
children:
|
|
122
|
+
children: t.emailLabel
|
|
120
123
|
}),
|
|
121
124
|
/*#__PURE__*/ _jsx(Input, {
|
|
122
125
|
variant: "secondary"
|
|
@@ -126,17 +129,20 @@ export default function SignupPageHero({ onSignup, showGoogleOAuth = true, login
|
|
|
126
129
|
/*#__PURE__*/ _jsxs("p", {
|
|
127
130
|
className: "text-xs text-gray-600 text-center",
|
|
128
131
|
children: [
|
|
129
|
-
|
|
132
|
+
t.termsNotice,
|
|
133
|
+
" ",
|
|
130
134
|
/*#__PURE__*/ _jsx("a", {
|
|
131
135
|
href: "/terms",
|
|
132
136
|
className: "text-gray-900 hover:underline",
|
|
133
|
-
children:
|
|
137
|
+
children: t.termsLink
|
|
134
138
|
}),
|
|
135
|
-
"
|
|
139
|
+
" ",
|
|
140
|
+
t.andSeparator,
|
|
141
|
+
" ",
|
|
136
142
|
/*#__PURE__*/ _jsx("a", {
|
|
137
143
|
href: "/privacy",
|
|
138
144
|
className: "text-gray-900 hover:underline",
|
|
139
|
-
children:
|
|
145
|
+
children: t.privacyLink
|
|
140
146
|
})
|
|
141
147
|
]
|
|
142
148
|
}),
|
|
@@ -152,7 +158,7 @@ export default function SignupPageHero({ onSignup, showGoogleOAuth = true, login
|
|
|
152
158
|
color: "current",
|
|
153
159
|
size: "sm"
|
|
154
160
|
}),
|
|
155
|
-
|
|
161
|
+
t.createAccount
|
|
156
162
|
]
|
|
157
163
|
})
|
|
158
164
|
})
|
|
@@ -7,4 +7,4 @@ export interface SignupPageProps extends AuthLayoutConfig {
|
|
|
7
7
|
showGoogleOAuth?: boolean;
|
|
8
8
|
loginUrl?: string;
|
|
9
9
|
}
|
|
10
|
-
export default function SignupPage({ onSignup, showGoogleOAuth, loginUrl, logo, poweredBy, cardClassName, backgroundClass, }: SignupPageProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export default function SignupPage({ onSignup, showGoogleOAuth, loginUrl, logo, poweredBy, cardClassName, backgroundClass, locale, messages, }: SignupPageProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -3,11 +3,13 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
|
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import { Button, Input, Divider } from '../ui/index.js';
|
|
5
5
|
import { AuthLayout } from '../AuthLayout.js';
|
|
6
|
-
|
|
6
|
+
import { getUiTranslations } from '../ui/translations.js';
|
|
7
|
+
export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
|
|
7
8
|
const [name, setName] = React.useState('');
|
|
8
9
|
const [email, setEmail] = React.useState('');
|
|
9
10
|
const [isLoading, setIsLoading] = React.useState(false);
|
|
10
11
|
const [error, setError] = React.useState(null);
|
|
12
|
+
const t = getUiTranslations(locale, messages).signup;
|
|
11
13
|
const handleSubmit = async (e)=>{
|
|
12
14
|
e.preventDefault();
|
|
13
15
|
setIsLoading(true);
|
|
@@ -26,20 +28,20 @@ export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl
|
|
|
26
28
|
};
|
|
27
29
|
return /*#__PURE__*/ _jsxs(AuthLayout, {
|
|
28
30
|
logo: logo,
|
|
29
|
-
title:
|
|
30
|
-
subtitle:
|
|
31
|
+
title: t.title,
|
|
32
|
+
subtitle: t.subtitle,
|
|
31
33
|
poweredBy: poweredBy,
|
|
32
34
|
cardClassName: cardClassName,
|
|
33
35
|
backgroundClass: backgroundClass,
|
|
34
36
|
footer: /*#__PURE__*/ _jsxs("p", {
|
|
35
37
|
className: "text-center text-gray-600 text-sm",
|
|
36
38
|
children: [
|
|
37
|
-
|
|
39
|
+
t.haveAccount,
|
|
38
40
|
' ',
|
|
39
41
|
/*#__PURE__*/ _jsx("a", {
|
|
40
42
|
href: loginUrl,
|
|
41
43
|
className: "text-gray-900 font-medium hover:underline",
|
|
42
|
-
children:
|
|
44
|
+
children: t.loginLink
|
|
43
45
|
})
|
|
44
46
|
]
|
|
45
47
|
}),
|
|
@@ -75,7 +77,7 @@ export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl
|
|
|
75
77
|
})
|
|
76
78
|
]
|
|
77
79
|
}),
|
|
78
|
-
|
|
80
|
+
t.continueWithGoogle
|
|
79
81
|
]
|
|
80
82
|
}),
|
|
81
83
|
/*#__PURE__*/ _jsxs("div", {
|
|
@@ -86,7 +88,7 @@ export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl
|
|
|
86
88
|
}),
|
|
87
89
|
/*#__PURE__*/ _jsx("span", {
|
|
88
90
|
className: "text-gray-500 text-sm",
|
|
89
|
-
children:
|
|
91
|
+
children: t.or
|
|
90
92
|
}),
|
|
91
93
|
/*#__PURE__*/ _jsx(Divider, {
|
|
92
94
|
className: "flex-1"
|
|
@@ -104,14 +106,14 @@ export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl
|
|
|
104
106
|
children: error
|
|
105
107
|
}),
|
|
106
108
|
/*#__PURE__*/ _jsx(Input, {
|
|
107
|
-
label:
|
|
109
|
+
label: t.fullNameLabel,
|
|
108
110
|
value: name,
|
|
109
111
|
onValueChange: setName,
|
|
110
112
|
isRequired: true
|
|
111
113
|
}),
|
|
112
114
|
/*#__PURE__*/ _jsx(Input, {
|
|
113
115
|
type: "email",
|
|
114
|
-
label:
|
|
116
|
+
label: t.emailLabel,
|
|
115
117
|
value: email,
|
|
116
118
|
onValueChange: setEmail,
|
|
117
119
|
isRequired: true
|
|
@@ -119,19 +121,20 @@ export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl
|
|
|
119
121
|
/*#__PURE__*/ _jsxs("p", {
|
|
120
122
|
className: "text-xs text-gray-600 text-center",
|
|
121
123
|
children: [
|
|
122
|
-
|
|
124
|
+
t.termsNotice,
|
|
123
125
|
' ',
|
|
124
126
|
/*#__PURE__*/ _jsx("a", {
|
|
125
127
|
href: "/terms",
|
|
126
128
|
className: "text-gray-900 hover:underline",
|
|
127
|
-
children:
|
|
129
|
+
children: t.termsLink
|
|
128
130
|
}),
|
|
129
|
-
"
|
|
131
|
+
" ",
|
|
132
|
+
t.andSeparator,
|
|
130
133
|
' ',
|
|
131
134
|
/*#__PURE__*/ _jsx("a", {
|
|
132
135
|
href: "/privacy",
|
|
133
136
|
className: "text-gray-900 hover:underline",
|
|
134
|
-
children:
|
|
137
|
+
children: t.privacyLink
|
|
135
138
|
})
|
|
136
139
|
]
|
|
137
140
|
}),
|
|
@@ -139,7 +142,7 @@ export default function SignupPage({ onSignup, showGoogleOAuth = true, loginUrl
|
|
|
139
142
|
type: "submit",
|
|
140
143
|
variant: "primary",
|
|
141
144
|
isLoading: isLoading,
|
|
142
|
-
children:
|
|
145
|
+
children: t.createAccount
|
|
143
146
|
})
|
|
144
147
|
]
|
|
145
148
|
})
|
|
@@ -7,7 +7,8 @@ import { Icon } from '@iconify/react';
|
|
|
7
7
|
import { motion } from 'framer-motion';
|
|
8
8
|
import { useVerifyOtpFlow } from '../../auth/application/hooks/useVerifyOtpFlow.js';
|
|
9
9
|
import { AuthLayout } from '../AuthLayout.js';
|
|
10
|
-
|
|
10
|
+
import { getUiTranslations } from '../ui/translations.js';
|
|
11
|
+
function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
|
|
11
12
|
const searchParams = useSearchParams();
|
|
12
13
|
const email = searchParams.get('email') || '';
|
|
13
14
|
const purpose = searchParams.get('purpose') || 'login';
|
|
@@ -17,11 +18,12 @@ function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassN
|
|
|
17
18
|
purpose,
|
|
18
19
|
redirectTo
|
|
19
20
|
});
|
|
21
|
+
const t = getUiTranslations(locale, messages).verifyOtp;
|
|
20
22
|
if (!email) return null;
|
|
21
23
|
return /*#__PURE__*/ _jsx(AuthLayout, {
|
|
22
24
|
logo: logo,
|
|
23
|
-
title: purpose === 'password-reset' ?
|
|
24
|
-
subtitle: purpose === 'password-reset' ?
|
|
25
|
+
title: purpose === 'password-reset' ? t.passwordResetTitle : t.title,
|
|
26
|
+
subtitle: purpose === 'password-reset' ? t.passwordResetSubtitle : t.subtitle,
|
|
25
27
|
poweredBy: poweredBy,
|
|
26
28
|
cardClassName: cardClassName,
|
|
27
29
|
backgroundClass: backgroundClass,
|
|
@@ -33,7 +35,7 @@ function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassN
|
|
|
33
35
|
icon: "lucide:arrow-left",
|
|
34
36
|
width: 16
|
|
35
37
|
}),
|
|
36
|
-
|
|
38
|
+
t.backToLogin
|
|
37
39
|
]
|
|
38
40
|
}),
|
|
39
41
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
@@ -103,7 +105,7 @@ function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassN
|
|
|
103
105
|
color: "current",
|
|
104
106
|
size: "sm"
|
|
105
107
|
}),
|
|
106
|
-
|
|
108
|
+
t.verify
|
|
107
109
|
]
|
|
108
110
|
})
|
|
109
111
|
}),
|
|
@@ -112,13 +114,13 @@ function VerifyOtpHeroContent({ loginUrl = '/login', logo, poweredBy, cardClassN
|
|
|
112
114
|
children: [
|
|
113
115
|
/*#__PURE__*/ _jsx("p", {
|
|
114
116
|
className: "text-gray-600 text-sm mb-2",
|
|
115
|
-
children:
|
|
117
|
+
children: t.noCodeReceived
|
|
116
118
|
}),
|
|
117
119
|
/*#__PURE__*/ _jsx("button", {
|
|
118
120
|
onClick: handleResendCode,
|
|
119
121
|
disabled: isResending || resendCooldown > 0,
|
|
120
122
|
className: "text-primary font-medium text-sm hover:underline disabled:opacity-50",
|
|
121
|
-
children: isResending ?
|
|
123
|
+
children: isResending ? t.resending : resendCooldown > 0 ? t.resendIn.replace('{seconds}', String(resendCooldown)) : t.resendCode
|
|
122
124
|
})
|
|
123
125
|
]
|
|
124
126
|
})
|
|
@@ -5,7 +5,8 @@ import { useSearchParams } from 'next/navigation';
|
|
|
5
5
|
import { Button, OtpInput, Spinner } from '../ui/index.js';
|
|
6
6
|
import { useVerifyOtpFlow } from '../../auth/application/hooks/useVerifyOtpFlow.js';
|
|
7
7
|
import { AuthLayout } from '../AuthLayout.js';
|
|
8
|
-
|
|
8
|
+
import { getUiTranslations } from '../ui/translations.js';
|
|
9
|
+
function VerifyOtpContent({ loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass, locale, messages }) {
|
|
9
10
|
const searchParams = useSearchParams();
|
|
10
11
|
const email = searchParams.get('email') || '';
|
|
11
12
|
const purpose = searchParams.get('purpose') || 'login';
|
|
@@ -15,19 +16,23 @@ function VerifyOtpContent({ loginUrl = '/login', logo, poweredBy, cardClassName,
|
|
|
15
16
|
purpose,
|
|
16
17
|
redirectTo
|
|
17
18
|
});
|
|
19
|
+
const t = getUiTranslations(locale, messages).verifyOtp;
|
|
18
20
|
if (!email) return null;
|
|
19
21
|
const isPasswordReset = purpose === 'password-reset';
|
|
20
22
|
return /*#__PURE__*/ _jsx(AuthLayout, {
|
|
21
23
|
logo: logo,
|
|
22
|
-
title: isPasswordReset ?
|
|
23
|
-
subtitle: isPasswordReset ?
|
|
24
|
+
title: isPasswordReset ? t.passwordResetTitle : t.title,
|
|
25
|
+
subtitle: isPasswordReset ? t.passwordResetSubtitle : t.subtitle,
|
|
24
26
|
poweredBy: poweredBy,
|
|
25
27
|
cardClassName: cardClassName,
|
|
26
28
|
backgroundClass: backgroundClass,
|
|
27
|
-
footer: /*#__PURE__*/
|
|
29
|
+
footer: /*#__PURE__*/ _jsxs("a", {
|
|
28
30
|
href: loginUrl,
|
|
29
31
|
className: "text-sm text-gray-600 hover:text-gray-900 flex items-center gap-1",
|
|
30
|
-
children:
|
|
32
|
+
children: [
|
|
33
|
+
"← ",
|
|
34
|
+
t.backToLogin
|
|
35
|
+
]
|
|
31
36
|
}),
|
|
32
37
|
children: /*#__PURE__*/ _jsxs("div", {
|
|
33
38
|
className: "flex flex-col items-center gap-4",
|
|
@@ -51,20 +56,20 @@ function VerifyOtpContent({ loginUrl = '/login', logo, poweredBy, cardClassName,
|
|
|
51
56
|
isLoading: isLoading,
|
|
52
57
|
isDisabled: otp.length !== 6,
|
|
53
58
|
onPress: handleSubmit,
|
|
54
|
-
children:
|
|
59
|
+
children: t.verify
|
|
55
60
|
}),
|
|
56
61
|
/*#__PURE__*/ _jsxs("div", {
|
|
57
62
|
className: "text-center",
|
|
58
63
|
children: [
|
|
59
64
|
/*#__PURE__*/ _jsx("p", {
|
|
60
65
|
className: "text-gray-600 text-sm mb-2",
|
|
61
|
-
children:
|
|
66
|
+
children: t.noCodeReceived
|
|
62
67
|
}),
|
|
63
68
|
/*#__PURE__*/ _jsx("button", {
|
|
64
69
|
onClick: handleResendCode,
|
|
65
70
|
disabled: isResending || resendCooldown > 0,
|
|
66
71
|
className: "text-[#0071e3] font-medium text-sm hover:underline disabled:opacity-50 disabled:cursor-not-allowed",
|
|
67
|
-
children: isResending ?
|
|
72
|
+
children: isResending ? t.resending : resendCooldown > 0 ? t.resendIn.replace('{seconds}', String(resendCooldown)) : t.resendCode
|
|
68
73
|
})
|
|
69
74
|
]
|
|
70
75
|
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Zero-dependency locale detection.
|
|
3
|
+
*
|
|
4
|
+
* The plugin never imports next-intl, next-i18next, or any i18n library —
|
|
5
|
+
* instead it reads the same conventional signals those libraries already
|
|
6
|
+
* write, so `locale` "just works" automatically for consumers using them,
|
|
7
|
+
* while still defaulting sanely (`en`) for consumers with no i18n setup.
|
|
8
|
+
*
|
|
9
|
+
* Priority order:
|
|
10
|
+
* 1. Explicit `locale` prop passed to `<AuthPages />` (always wins, handled by caller)
|
|
11
|
+
* 2. `NEXT_LOCALE` cookie — written by next-intl, next-i18next, and most
|
|
12
|
+
* i18n routing middlewares by convention
|
|
13
|
+
* 3. `Accept-Language` request header (server-side only)
|
|
14
|
+
* 4. `<html lang="...">` attribute (client-side only)
|
|
15
|
+
* 5. Fallback: 'en'
|
|
16
|
+
*/
|
|
17
|
+
/**
|
|
18
|
+
* Server-side locale detection — reads `Cookie` and `Accept-Language` headers.
|
|
19
|
+
* Use inside an RSC (e.g. `AuthPagesServer`) where `next/headers` is available.
|
|
20
|
+
*/
|
|
21
|
+
export declare function detectServerLocale(headers: {
|
|
22
|
+
get(name: string): string | null;
|
|
23
|
+
}): string;
|
|
24
|
+
/**
|
|
25
|
+
* Client-side locale detection — reads the `NEXT_LOCALE` cookie or falls back
|
|
26
|
+
* to `<html lang>`. Use inside client components when no explicit locale was
|
|
27
|
+
* passed down from the server.
|
|
28
|
+
*/
|
|
29
|
+
export declare function detectClientLocale(): string;
|