import { useState } from 'react'
import { z } from 'zod'
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { Loader2, UserPlus } from 'lucide-react'
import { toast } from 'sonner'
import { IconFacebook, IconGithub } from '@/assets/brand-icons'
import { sleep, cn } from '@/lib/utils'
import { Button } from '@/components/ui/button'
import {
Form,
FormControl,
FormField,
FormItem,
FormLabel,
FormMessage,
} from '@/components/ui/form'
import { Input } from '@/components/ui/input'
import { PasswordInput } from '@/components/password-input'
const formSchema = z
.object({
email: z.email({
error: (iss) =>
iss.input === '' ? 'Please enter your email.' : undefined,
}),
password: z
.string()
.min(1, 'Please enter your password.')
.min(7, 'Password must be at least 7 characters long.'),
confirmPassword: z.string().min(1, 'Please confirm your password.'),
})
.refine((data) => data.password === data.confirmPassword, {
message: "Passwords don't match.",
path: ['confirmPassword'],
})
export function SignUpForm({
className,
...props
}: React.HTMLAttributes<HTMLFormElement>) {
const [isLoading, setIsLoading] = useState(false)
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
email: '',
password: '',
confirmPassword: '',
},
})
function onSubmit(data: z.infer<typeof formSchema>) {
setIsLoading(true)
toast.promise(sleep(2000), {
loading: 'Creating account...',
success: () => {
setIsLoading(false)
return `Account created for ${data.email}.`
},
error: 'Error',
})
}
return (
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className={cn('grid gap-3', className)}
{...props}
>
<FormField
control={form.control}
name='email'
render={({ field }) => (
<FormItem>
<FormLabel>Email</FormLabel>
<FormControl>
<Input placeholder='name@example.com' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='password'
render={({ field }) => (
<FormItem>
<FormLabel>Password</FormLabel>
<FormControl>
<PasswordInput placeholder='********' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<FormField
control={form.control}
name='confirmPassword'
render={({ field }) => (
<FormItem>
<FormLabel>Confirm Password</FormLabel>
<FormControl>
<PasswordInput placeholder='********' {...field} />
</FormControl>
<FormMessage />
</FormItem>
)}
/>
<Button className='mt-2' disabled={isLoading}>
{isLoading ? <Loader2 className='animate-spin' /> : <UserPlus />}
Create Account
</Button>
<div className='relative my-2'>
<div className='absolute inset-0 flex items-center'>
<span className='w-full border-t' />
</div>
<div className='relative flex justify-center text-xs uppercase'>
<span className='bg-background px-2 text-muted-foreground'>
Or continue with
</span>
</div>
</div>
<div className='grid grid-cols-2 gap-2'>
<Button
variant='outline'
className='w-full'
type='button'
disabled={isLoading}
>
<IconGithub className='h-4 w-4' /> GitHub
</Button>
<Button
variant='outline'
className='w-full'
type='button'
disabled={isLoading}
>
<IconFacebook className='h-4 w-4' /> Facebook
</Button>
</div>
</form>
</Form>
)
}