122 lines
3.3 KiB
TypeScript
122 lines
3.3 KiB
TypeScript
'use client'
|
|
|
|
import React, { useCallback, useRef, useState } from 'react'
|
|
import { useForm } from 'react-hook-form'
|
|
import Link from 'next/link'
|
|
import { useRouter, useSearchParams } from 'next/navigation'
|
|
|
|
import { Button } from '../../_components/Button'
|
|
import { Input } from '../../_components/Input'
|
|
import { Message } from '../../_components/Message'
|
|
import { useAuth } from '../../_providers/Auth'
|
|
|
|
import classes from './index.module.scss'
|
|
|
|
type FormData = {
|
|
email: string
|
|
password: string
|
|
passwordConfirm: string
|
|
}
|
|
|
|
export const CreateAccountForm: React.FC = () => {
|
|
const searchParams = useSearchParams()
|
|
const allParams = searchParams.toString() ? `?${searchParams.toString()}` : ''
|
|
const { login } = useAuth()
|
|
const router = useRouter()
|
|
const [loading, setLoading] = useState(false)
|
|
const [error, setError] = useState<string | null>(null)
|
|
|
|
const {
|
|
register,
|
|
handleSubmit,
|
|
formState: { errors },
|
|
watch,
|
|
} = useForm<FormData>()
|
|
|
|
const password = useRef({})
|
|
password.current = watch('password', '')
|
|
|
|
const onSubmit = useCallback(
|
|
async (data: FormData) => {
|
|
const response = await fetch(`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/api/users`, {
|
|
method: 'POST',
|
|
body: JSON.stringify(data),
|
|
headers: {
|
|
'Content-Type': 'application/json',
|
|
},
|
|
})
|
|
|
|
if (!response.ok) {
|
|
const message = response.statusText || 'There was an error creating the account.'
|
|
setError(message)
|
|
return
|
|
}
|
|
|
|
const redirect = searchParams.get('redirect')
|
|
|
|
const timer = setTimeout(() => {
|
|
setLoading(true)
|
|
}, 1000)
|
|
|
|
try {
|
|
await login(data)
|
|
clearTimeout(timer)
|
|
if (redirect) router.push(redirect as string)
|
|
else router.push(`/account?success=${encodeURIComponent('Account created successfully')}`)
|
|
} catch (_) {
|
|
clearTimeout(timer)
|
|
setError('There was an error with the credentials provided. Please try again.')
|
|
}
|
|
},
|
|
[login, router, searchParams],
|
|
)
|
|
|
|
return (
|
|
<form onSubmit={handleSubmit(onSubmit)} className={classes.form}>
|
|
<p>
|
|
{`This is where new customers can signup and create a new account. To manage all users, `}
|
|
<Link href={`${process.env.NEXT_PUBLIC_PAYLOAD_URL}/admin/collections/users`}>
|
|
login to the admin dashboard
|
|
</Link>
|
|
{'.'}
|
|
</p>
|
|
<Message error={error} className={classes.message} />
|
|
<Input
|
|
name="email"
|
|
label="Email Address"
|
|
required
|
|
register={register}
|
|
error={errors.email}
|
|
type="email"
|
|
/>
|
|
<Input
|
|
name="password"
|
|
type="password"
|
|
label="Password"
|
|
required
|
|
register={register}
|
|
error={errors.password}
|
|
/>
|
|
<Input
|
|
name="passwordConfirm"
|
|
type="password"
|
|
label="Confirm Password"
|
|
required
|
|
register={register}
|
|
validate={value => value === password.current || 'The passwords do not match'}
|
|
error={errors.passwordConfirm}
|
|
/>
|
|
<Button
|
|
type="submit"
|
|
className={classes.submit}
|
|
label={loading ? 'Processing' : 'Create Account'}
|
|
appearance="primary"
|
|
/>
|
|
<div>
|
|
{'Already have an account? '}
|
|
<Link href={`/login${allParams}`}>Login</Link>
|
|
</div>
|
|
</form>
|
|
)
|
|
}
|