-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathindex.tsx
More file actions
125 lines (113 loc) · 3.56 KB
/
index.tsx
File metadata and controls
125 lines (113 loc) · 3.56 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
'use client'
import type { AdminViewClientProps, ValidateOptions } from 'payload'
import { MinimalTemplate } from '@payloadcms/next/templates'
import {
EmailField,
Form,
FormSubmit,
HiddenField,
Link,
TextField,
useConfig,
useTranslation,
} from '@payloadcms/ui'
import { useRouter, useSearchParams } from 'next/navigation.js'
import { email, username } from 'payload/shared'
import React from 'react'
import { getLoginOptions } from '../../utilities/getLoginOptions.js'
import { localStorageKey } from '../shared.js'
const baseClass = 'request-otp'
export const RequestOTP: React.FC<AdminViewClientProps> = () => {
const redirect = useSearchParams().get('redirect')
const { config, getEntityConfig } = useConfig()
const { t } = useTranslation()
const router = useRouter()
const {
admin: { user: userSlug },
routes: { admin, api },
} = config
const collectionConfig = getEntityConfig({ collectionSlug: userSlug })
const { auth: authOptions } = collectionConfig
const loginWithUsername = authOptions?.loginWithUsername
const { canLoginWithEmail, canLoginWithUsername } = getLoginOptions(loginWithUsername ?? false)
const [loginType] = React.useState<'email' | 'emailOrUsername' | 'username'>(() => {
if (canLoginWithEmail && canLoginWithUsername) {
return 'emailOrUsername'
}
if (canLoginWithUsername) {
return 'username'
}
return 'email'
})
const onSuccess = React.useCallback(
(args: unknown) => {
const { value } = args as { value: string }
router.push(`${admin}/otp/login${redirect ? '?redirect=' + redirect : ''}`)
window.localStorage.setItem(localStorageKey, value)
},
[router, admin, redirect],
)
return (
<MinimalTemplate className={baseClass}>
<h3>Request a one-time password</h3>
<br />
<Form
action={`${api}/${userSlug}/otp/request`}
method="POST"
onSuccess={onSuccess}
waitForAutocomplete
>
<HiddenField path="type" value={loginType} />
{loginType === 'email' && (
<EmailField
field={{
name: 'value',
admin: {
autoComplete: 'email',
placeholder: '',
},
label: t('general:email'),
required: true,
}}
path="value"
validate={email}
/>
)}
{loginType === 'username' && (
<TextField
field={{
name: 'value',
label: t('authentication:username'),
required: true,
}}
path="value"
validate={username}
/>
)}
{loginType === 'emailOrUsername' && (
<TextField
field={{
name: 'value',
label: t('authentication:emailOrUsername'),
required: true,
}}
path="value"
validate={(value, options) => {
const passesUsername = username(value, options)
const passesEmail = email(
value,
options as ValidateOptions<any, { username?: string }, any, any>,
)
if (!passesEmail && !passesUsername) {
return `${t('general:email')}: ${passesEmail} ${t('general:username')}: ${passesUsername}`
}
return true
}}
/>
)}
<FormSubmit size="large">Request one-time password</FormSubmit>
</Form>
<Link href={`${admin}/login`}>Back to login</Link>
</MinimalTemplate>
)
}