@main12/auth-login 0.1.0 → 0.1.2
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 +187 -151
- package/dist/components/pages/ForgotPasswordPage.d.ts +1 -1
- package/dist/components/pages/ForgotPasswordPage.js +9 -42
- package/dist/components/pages/ForgotPasswordPageHero.d.ts +5 -0
- package/dist/components/pages/ForgotPasswordPageHero.js +69 -0
- package/dist/components/pages/ForgotPasswordPageTailwind.d.ts +5 -0
- package/dist/components/pages/ForgotPasswordPageTailwind.js +45 -0
- package/dist/components/pages/LoginPage.js +8 -218
- package/dist/components/pages/LoginPageHero.d.ts +11 -0
- package/dist/components/pages/LoginPageHero.js +298 -0
- package/dist/components/pages/LoginPageTailwind.d.ts +11 -0
- package/dist/components/pages/LoginPageTailwind.js +222 -0
- package/dist/components/pages/SetPasswordPage.d.ts +1 -1
- package/dist/components/pages/SetPasswordPage.js +9 -71
- package/dist/components/pages/SetPasswordPageHero.d.ts +5 -0
- package/dist/components/pages/SetPasswordPageHero.js +93 -0
- package/dist/components/pages/SetPasswordPageTailwind.d.ts +5 -0
- package/dist/components/pages/SetPasswordPageTailwind.js +74 -0
- package/dist/components/pages/SignupPage.d.ts +1 -1
- package/dist/components/pages/SignupPage.js +9 -126
- package/dist/components/pages/SignupPageHero.d.ts +10 -0
- package/dist/components/pages/SignupPageHero.js +150 -0
- package/dist/components/pages/SignupPageTailwind.d.ts +10 -0
- package/dist/components/pages/SignupPageTailwind.js +129 -0
- package/dist/components/pages/VerifyOtpPage.js +8 -83
- package/dist/components/pages/VerifyOtpPageHero.d.ts +5 -0
- package/dist/components/pages/VerifyOtpPageHero.js +104 -0
- package/dist/components/pages/VerifyOtpPageTailwind.d.ts +5 -0
- package/dist/components/pages/VerifyOtpPageTailwind.js +87 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +6 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +5 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -1,218 +1,254 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @main12/auth-login
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Payload CMS authentication plugin** — login, signup, OTP, forgot password, branded emails, and "Powered by Main 12" footer. Install once, configure your project name and logo, done.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
```ts
|
|
6
|
+
// payload.config.ts
|
|
7
|
+
import { authLoginPlugin } from '@main12/auth-login'
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
plugins: [
|
|
10
|
+
authLoginPlugin({
|
|
11
|
+
projectName: 'My SaaS',
|
|
12
|
+
domain: 'https://myapp.com',
|
|
13
|
+
style: 'hero-ui', // 'tailwind' (default) | 'hero-ui'
|
|
14
|
+
}),
|
|
15
|
+
]
|
|
16
|
+
```
|
|
11
17
|
|
|
12
|
-
|
|
18
|
+
---
|
|
13
19
|
|
|
14
|
-
|
|
20
|
+
## Features
|
|
15
21
|
|
|
16
|
-
|
|
22
|
+
- **5 auth pages** — login (multi-step), signup, forgot password, verify OTP, set password
|
|
23
|
+
- **Multi-style** — `tailwind` (zero UI deps) or `hero-ui` (HeroUI + framer-motion). Set once in config
|
|
24
|
+
- **5 API endpoints** — `check-email`, `otp/send`, `otp/verify`, `set-password`, `signup`
|
|
25
|
+
- **OTP engine** — SHA-256 hashing + `timingSafeEqual` comparison, 10-min expiry, 3 attempts
|
|
26
|
+
- **Email templates** — welcome, OTP login, password reset, password changed (EN/ES)
|
|
27
|
+
- **Powered by Main 12** — bundled inline SVG, linked to main12.com by default
|
|
28
|
+
- **Zero runtime deps** (Tailwind mode) — Next.js + React are peer dependencies
|
|
17
29
|
|
|
18
|
-
|
|
30
|
+
---
|
|
19
31
|
|
|
20
|
-
|
|
21
|
-
import myPlugin from 'my-plugin'
|
|
32
|
+
## Installation
|
|
22
33
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
// You can pass options to the plugin
|
|
26
|
-
myPlugin({
|
|
27
|
-
enabled: true,
|
|
28
|
-
}),
|
|
29
|
-
],
|
|
30
|
-
})
|
|
34
|
+
```bash
|
|
35
|
+
pnpm add @main12/auth-login
|
|
31
36
|
```
|
|
32
37
|
|
|
33
|
-
###
|
|
34
|
-
|
|
35
|
-
The initialization process goes in the following order:
|
|
38
|
+
### Tailwind mode (default, zero UI deps)
|
|
36
39
|
|
|
37
|
-
|
|
38
|
-
2. **Plugins execute**
|
|
39
|
-
3. Default options are integrated
|
|
40
|
-
4. Sanitization cleans and validates data
|
|
41
|
-
5. Final config gets initialized
|
|
40
|
+
No extra dependencies needed.
|
|
42
41
|
|
|
43
|
-
|
|
42
|
+
### HeroUI mode
|
|
44
43
|
|
|
45
|
-
|
|
44
|
+
```bash
|
|
45
|
+
pnpm add @heroui/react framer-motion @iconify/react
|
|
46
|
+
```
|
|
46
47
|
|
|
47
|
-
|
|
48
|
+
---
|
|
48
49
|
|
|
49
|
-
|
|
50
|
+
## Quick Start
|
|
50
51
|
|
|
51
|
-
1.
|
|
52
|
-
2. /src folder
|
|
53
|
-
3. /dev folder
|
|
52
|
+
### 1. Add the plugin to your Payload config
|
|
54
53
|
|
|
55
|
-
|
|
54
|
+
```ts
|
|
55
|
+
import { authLoginPlugin } from '@main12/auth-login'
|
|
56
56
|
|
|
57
|
-
|
|
57
|
+
export default buildConfig({
|
|
58
|
+
plugins: [
|
|
59
|
+
authLoginPlugin({
|
|
60
|
+
projectName: 'My App',
|
|
61
|
+
domain: 'https://myapp.com',
|
|
62
|
+
contactEmail: 'support@myapp.com',
|
|
63
|
+
style: 'tailwind', // or 'hero-ui'
|
|
64
|
+
}),
|
|
65
|
+
],
|
|
66
|
+
// ... rest of your config
|
|
67
|
+
})
|
|
68
|
+
```
|
|
58
69
|
|
|
59
|
-
|
|
60
|
-
- **package**.json\* - Contains necessary scripts and dependencies. Overwrite the metadata in this file to describe your Plugin.
|
|
61
|
-
- .**eslint**.config.js - Eslint configuration for reporting on problematic patterns.
|
|
62
|
-
- .**gitignore** - List specific untracked files to omit from Git.
|
|
63
|
-
- .**prettierrc**.json - Configuration for Prettier code formatting.
|
|
64
|
-
- **tsconfig**.json - Configures the compiler options for TypeScript
|
|
65
|
-
- .**swcrc** - Configuration for SWC, a fast compiler that transpiles and bundles TypeScript.
|
|
66
|
-
- **vitest**.config.js - Config file for Vitest, defining how tests are run and how modules are resolved
|
|
70
|
+
### 2. Add auth pages to your app
|
|
67
71
|
|
|
68
|
-
|
|
72
|
+
Create one-line route files under `src/app/(frontend)/(auth)/`:
|
|
69
73
|
|
|
70
|
-
|
|
74
|
+
```tsx
|
|
75
|
+
// login/page.tsx
|
|
76
|
+
export { LoginPage as default } from '@main12/auth-login/client'
|
|
71
77
|
|
|
72
|
-
|
|
78
|
+
// signup/page.tsx
|
|
79
|
+
export { SignupPage as default } from '@main12/auth-login/client'
|
|
73
80
|
|
|
74
|
-
|
|
75
|
-
|
|
81
|
+
// forgot-password/page.tsx
|
|
82
|
+
export { ForgotPasswordPage as default } from '@main12/auth-login/client'
|
|
76
83
|
|
|
77
|
-
|
|
84
|
+
// verify-otp/page.tsx
|
|
85
|
+
export { VerifyOtpPage as default } from '@main12/auth-login/client'
|
|
78
86
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
myPlugin({
|
|
82
|
-
collections: {
|
|
83
|
-
posts: true,
|
|
84
|
-
},
|
|
85
|
-
}),
|
|
86
|
-
]
|
|
87
|
+
// set-password/page.tsx
|
|
88
|
+
export { SetPasswordPage as default } from '@main12/auth-login/client'
|
|
87
89
|
```
|
|
88
90
|
|
|
89
|
-
|
|
91
|
+
### 3. Wire up the login action
|
|
92
|
+
|
|
93
|
+
The plugin needs a `login` function. Pass yours from Payload's `useAuth()`:
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
// login/page.tsx
|
|
97
|
+
'use client'
|
|
98
|
+
import { LoginPage } from '@main12/auth-login/client'
|
|
99
|
+
import { useAuth } from '@/providers/Auth'
|
|
100
|
+
import AppLogo from '@/components/Logo/AppLogo'
|
|
101
|
+
|
|
102
|
+
export default function Page() {
|
|
103
|
+
const { login } = useAuth()
|
|
104
|
+
return (
|
|
105
|
+
<LoginPage
|
|
106
|
+
logo={<AppLogo width={180} height={42} />}
|
|
107
|
+
onPasswordLogin={login}
|
|
108
|
+
redirectTo="/dashboard"
|
|
109
|
+
poweredBy={{ enabled: true }}
|
|
110
|
+
/>
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
```
|
|
90
114
|
|
|
91
|
-
|
|
115
|
+
---
|
|
92
116
|
|
|
93
|
-
|
|
117
|
+
## Configuration Options
|
|
94
118
|
|
|
95
|
-
|
|
119
|
+
```ts
|
|
120
|
+
authLoginPlugin({
|
|
121
|
+
// === Branding ===
|
|
122
|
+
projectName: 'My App', // Used in email subjects and footers
|
|
123
|
+
contactEmail: 'hi@myapp.com', // Email footer contact
|
|
124
|
+
domain: 'https://myapp.com', // Links in emails
|
|
96
125
|
|
|
97
|
-
|
|
126
|
+
// === Style ===
|
|
127
|
+
style: 'tailwind', // 'tailwind' | 'hero-ui'
|
|
98
128
|
|
|
99
|
-
|
|
129
|
+
// === Enable/Disable ===
|
|
130
|
+
enabled: true, // Set false to disable the plugin
|
|
131
|
+
})
|
|
132
|
+
```
|
|
100
133
|
|
|
101
|
-
|
|
134
|
+
Each page component also accepts these props:
|
|
102
135
|
|
|
103
136
|
```ts
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
137
|
+
<LoginPage
|
|
138
|
+
logo={...} // React node — your brand logo
|
|
139
|
+
onPasswordLogin={login} // Required — Payload's login function
|
|
140
|
+
redirectTo="/dashboard" // Where to go after login
|
|
141
|
+
showGoogleOAuth={true} // Show "Continue with Google" button
|
|
142
|
+
signupUrl="/signup" // Link to signup page
|
|
143
|
+
poweredBy={{ // Powered by logo config
|
|
144
|
+
enabled: true,
|
|
145
|
+
logoUrl: '/custom-logo.png', // Override the default Main12 logo
|
|
146
|
+
linkUrl: 'https://your-site.com',
|
|
147
|
+
width: 28,
|
|
148
|
+
height: 28,
|
|
149
|
+
}}
|
|
150
|
+
/>
|
|
111
151
|
```
|
|
112
152
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
From here, you can extend the config as you wish.
|
|
153
|
+
---
|
|
116
154
|
|
|
117
|
-
|
|
155
|
+
## Using Hooks & Services Directly
|
|
118
156
|
|
|
119
|
-
|
|
157
|
+
Don't want the pre-built pages? Use the hooks and services to build your own:
|
|
120
158
|
|
|
121
|
-
|
|
159
|
+
```tsx
|
|
160
|
+
import { useLoginFlow, useVerifyOtpFlow, checkEmail, sendOtp } from '@main12/auth-login/client'
|
|
122
161
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
// Add additional collections here
|
|
131
|
-
]
|
|
162
|
+
function MyCustomLogin() {
|
|
163
|
+
const { email, handleEmailSubmit, ... } = useLoginFlow({
|
|
164
|
+
redirectTo: '/dashboard',
|
|
165
|
+
onPasswordLogin: login,
|
|
166
|
+
})
|
|
167
|
+
// Build your own UI with these values
|
|
168
|
+
}
|
|
132
169
|
```
|
|
133
170
|
|
|
134
|
-
|
|
171
|
+
### Exported Hooks
|
|
135
172
|
|
|
136
|
-
|
|
173
|
+
| Hook | Purpose |
|
|
174
|
+
|------|---------|
|
|
175
|
+
| `useLoginFlow` | Multi-step login state machine (email → password/OTP) |
|
|
176
|
+
| `useVerifyOtpFlow` | OTP input, verify, resend with cooldown |
|
|
177
|
+
| `useForgotPasswordFlow` | Email → check → send OTP |
|
|
178
|
+
| `useSetPasswordFlow` | Set password with strength indicator |
|
|
137
179
|
|
|
138
|
-
|
|
139
|
-
config.globals = [
|
|
140
|
-
...(config.globals || []),
|
|
141
|
-
// Add additional globals here
|
|
142
|
-
]
|
|
180
|
+
### Exported Services
|
|
143
181
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
182
|
+
| Function | Description |
|
|
183
|
+
|----------|-------------|
|
|
184
|
+
| `checkEmail(email)` | Check if user exists and has password |
|
|
185
|
+
| `sendOtp(email, purpose)` | Send OTP to email |
|
|
186
|
+
| `verifyOtp(email, otp)` | Verify OTP code |
|
|
187
|
+
| `setUserPassword(password, confirm)` | Set/update password |
|
|
188
|
+
| `signup(name, email)` | Create new user |
|
|
189
|
+
| `initiateGoogleLogin(redirect)` | Redirect to Google OAuth |
|
|
149
190
|
|
|
150
|
-
|
|
191
|
+
---
|
|
151
192
|
|
|
152
|
-
|
|
153
|
-
import { onInitExtension } from './onInitExtension' // example file
|
|
193
|
+
## API Endpoints
|
|
154
194
|
|
|
155
|
-
|
|
156
|
-
if (incomingConfig.onInit) await incomingConfig.onInit(payload)
|
|
157
|
-
// Add additional onInit code by defining an onInitExtension function
|
|
158
|
-
onInitExtension(pluginOptions, payload)
|
|
159
|
-
}
|
|
160
|
-
```
|
|
195
|
+
Registered automatically by the plugin:
|
|
161
196
|
|
|
162
|
-
|
|
197
|
+
| Method | Path | Description |
|
|
198
|
+
|--------|------|-------------|
|
|
199
|
+
| POST | `/api/auth/check-email` | Check if email is registered |
|
|
200
|
+
| POST | `/api/auth/otp/send` | Generate + send OTP |
|
|
201
|
+
| POST | `/api/auth/otp/verify` | Verify OTP + login |
|
|
202
|
+
| POST | `/api/auth/set-password` | Set/update password |
|
|
203
|
+
| POST | `/api/auth/signup` | Create account |
|
|
163
204
|
|
|
164
|
-
|
|
205
|
+
---
|
|
165
206
|
|
|
166
|
-
|
|
207
|
+
## Email Templates
|
|
167
208
|
|
|
168
|
-
|
|
209
|
+
Four HTML email templates in EN/ES, using the host project's Payload email adapter:
|
|
169
210
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
*/
|
|
175
|
-
collections?: Partial<Record<CollectionSlug, true>>
|
|
176
|
-
/**
|
|
177
|
-
* Disable the plugin
|
|
178
|
-
*/
|
|
179
|
-
disabled?: boolean
|
|
180
|
-
}
|
|
181
|
-
```
|
|
211
|
+
- **Welcome** — sent on signup
|
|
212
|
+
- **OTP** — 6-digit code for login or password reset
|
|
213
|
+
- **Password Reset** — OTP email for forgot password flow
|
|
214
|
+
- **Password Changed** — confirmation after password update
|
|
182
215
|
|
|
183
|
-
|
|
216
|
+
Override translations or template functions via the `emails` option (Phase 2).
|
|
184
217
|
|
|
185
|
-
|
|
218
|
+
---
|
|
186
219
|
|
|
187
|
-
|
|
220
|
+
## Dev Testing
|
|
188
221
|
|
|
189
|
-
|
|
222
|
+
This repo ships with a dev harness. To test locally:
|
|
190
223
|
|
|
191
|
-
|
|
224
|
+
```bash
|
|
225
|
+
cd auth-login-plugin
|
|
226
|
+
pnpm install
|
|
227
|
+
pnpm dev
|
|
228
|
+
```
|
|
192
229
|
|
|
193
|
-
|
|
230
|
+
Visits:
|
|
231
|
+
- `http://localhost:3000/login` — multi-step login
|
|
232
|
+
- `http://localhost:3000/signup` — create account
|
|
233
|
+
- `http://localhost:3000/forgot-password` — password reset
|
|
234
|
+
- `http://localhost:3000/admin` — Payload admin panel
|
|
194
235
|
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
it('some condition that must be met', () => {
|
|
199
|
-
// Write your test logic here
|
|
200
|
-
expect(...)
|
|
201
|
-
})
|
|
202
|
-
})
|
|
203
|
-
```
|
|
236
|
+
The dev config uses SQLite (no external DB needed) with a Users collection pre-configured.
|
|
237
|
+
|
|
238
|
+
---
|
|
204
239
|
|
|
205
|
-
##
|
|
240
|
+
## Requirements
|
|
206
241
|
|
|
207
|
-
|
|
208
|
-
|
|
242
|
+
| Dependency | Version | Required |
|
|
243
|
+
|------------|---------|----------|
|
|
244
|
+
| Payload CMS | `^3.82.0` | ✅ |
|
|
245
|
+
| Next.js | `^16.0.0` | ✅ |
|
|
246
|
+
| React | `^19.0.0` | ✅ |
|
|
247
|
+
| HeroUI | `^2.x` | Only for `style: 'hero-ui'` |
|
|
248
|
+
| Framer Motion | `^12.x` | Only for `style: 'hero-ui'` |
|
|
209
249
|
|
|
210
|
-
|
|
211
|
-
- **Include tests in your GitHub CI workflow**: If you’ve configured tests for your package, integrate them into your workflow to run the tests each time you commit to the plugin repository. Learn more about [how to configure tests into your GitHub CI workflow.](https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs)
|
|
212
|
-
- **Publish your finished plugin to NPM**: The best way to share and allow others to use your plugin once it is complete is to publish an NPM package. This process is straightforward and well documented, find out more [creating and publishing a NPM package here.](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
|
|
213
|
-
- **Add payload-plugin topic tag**: Apply the tag **payload-plugin **to your GitHub repository. This will boost the visibility of your plugin and ensure it gets listed with [existing payload plugins](https://github.com/topics/payload-plugin).
|
|
214
|
-
- **Use [Semantic Versioning](https://semver.org/) (SemVar)** - With the SemVar system you release version numbers that reflect the nature of changes (major, minor, patch). Ensure all major versions reference their Payload compatibility.
|
|
250
|
+
---
|
|
215
251
|
|
|
216
|
-
|
|
252
|
+
## License
|
|
217
253
|
|
|
218
|
-
|
|
254
|
+
MIT © Main 12
|
|
@@ -2,4 +2,4 @@ import type { AuthLayoutConfig } from '../AuthLayout.js';
|
|
|
2
2
|
export interface ForgotPasswordPageProps extends AuthLayoutConfig {
|
|
3
3
|
loginUrl?: string;
|
|
4
4
|
}
|
|
5
|
-
export default function ForgotPasswordPage(
|
|
5
|
+
export default function ForgotPasswordPage(props: ForgotPasswordPageProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,45 +1,12 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
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
|
-
})
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { pluginConfig } from '../../config.js';
|
|
4
|
+
import ForgotPasswordPageTailwind from './ForgotPasswordPageTailwind.js';
|
|
5
|
+
import ForgotPasswordPageHero from './ForgotPasswordPageHero.js';
|
|
6
|
+
export default function ForgotPasswordPage(props) {
|
|
7
|
+
return pluginConfig.style === 'hero-ui' ? /*#__PURE__*/ _jsx(ForgotPasswordPageHero, {
|
|
8
|
+
...props
|
|
9
|
+
}) : /*#__PURE__*/ _jsx(ForgotPasswordPageTailwind, {
|
|
10
|
+
...props
|
|
44
11
|
});
|
|
45
12
|
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { AuthLayoutConfig } from '../AuthLayout.js';
|
|
2
|
+
export interface ForgotPasswordPageHeroProps extends AuthLayoutConfig {
|
|
3
|
+
loginUrl?: string;
|
|
4
|
+
}
|
|
5
|
+
export default function ForgotPasswordPageHero({ loginUrl, logo, poweredBy, cardClassName, backgroundClass }: ForgotPasswordPageHeroProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,69 @@
|
|
|
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 '@heroui/react';
|
|
5
|
+
import { Icon } from '@iconify/react';
|
|
6
|
+
import { motion } from 'framer-motion';
|
|
7
|
+
import { useForgotPasswordFlow } from '../../auth/application/hooks/useForgotPasswordFlow.js';
|
|
8
|
+
import { AuthLayout } from '../AuthLayout.js';
|
|
9
|
+
export default function ForgotPasswordPageHero({ loginUrl = '/login', logo, poweredBy, cardClassName, backgroundClass }) {
|
|
10
|
+
const { email, error, isLoading, setEmail, handleSubmit } = useForgotPasswordFlow();
|
|
11
|
+
return /*#__PURE__*/ _jsx(AuthLayout, {
|
|
12
|
+
logo: logo,
|
|
13
|
+
title: "Forgot Password",
|
|
14
|
+
subtitle: "Enter your email and we'll send you a reset code",
|
|
15
|
+
poweredBy: poweredBy,
|
|
16
|
+
cardClassName: cardClassName,
|
|
17
|
+
backgroundClass: backgroundClass,
|
|
18
|
+
footer: /*#__PURE__*/ _jsxs("a", {
|
|
19
|
+
href: loginUrl,
|
|
20
|
+
className: "text-sm text-gray-600 hover:text-gray-900 inline-flex items-center gap-1",
|
|
21
|
+
children: [
|
|
22
|
+
/*#__PURE__*/ _jsx(Icon, {
|
|
23
|
+
icon: "lucide:arrow-left",
|
|
24
|
+
width: 16
|
|
25
|
+
}),
|
|
26
|
+
"Back to Login"
|
|
27
|
+
]
|
|
28
|
+
}),
|
|
29
|
+
children: /*#__PURE__*/ _jsxs("form", {
|
|
30
|
+
onSubmit: handleSubmit,
|
|
31
|
+
className: "space-y-4",
|
|
32
|
+
children: [
|
|
33
|
+
error && /*#__PURE__*/ _jsx(motion.div, {
|
|
34
|
+
className: "bg-red-50 text-red-600 border border-red-200 rounded-lg p-3 text-sm",
|
|
35
|
+
initial: {
|
|
36
|
+
opacity: 0
|
|
37
|
+
},
|
|
38
|
+
animate: {
|
|
39
|
+
opacity: 1
|
|
40
|
+
},
|
|
41
|
+
children: error
|
|
42
|
+
}),
|
|
43
|
+
/*#__PURE__*/ _jsx(Input, {
|
|
44
|
+
type: "email",
|
|
45
|
+
label: "Email",
|
|
46
|
+
value: email,
|
|
47
|
+
onChange: (e)=>setEmail(e.target.value),
|
|
48
|
+
variant: "bordered",
|
|
49
|
+
size: "lg",
|
|
50
|
+
isRequired: true,
|
|
51
|
+
classNames: {
|
|
52
|
+
input: 'text-gray-900',
|
|
53
|
+
label: 'text-gray-600',
|
|
54
|
+
inputWrapper: 'border-gray-300 bg-white'
|
|
55
|
+
}
|
|
56
|
+
}),
|
|
57
|
+
/*#__PURE__*/ _jsx(Button, {
|
|
58
|
+
type: "submit",
|
|
59
|
+
fullWidth: true,
|
|
60
|
+
size: "lg",
|
|
61
|
+
color: "primary",
|
|
62
|
+
isLoading: isLoading,
|
|
63
|
+
className: "h-12 font-semibold",
|
|
64
|
+
children: "Send Reset Code"
|
|
65
|
+
})
|
|
66
|
+
]
|
|
67
|
+
})
|
|
68
|
+
});
|
|
69
|
+
}
|
|
@@ -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
|
+
}
|