|
|
@@ -1,4 +1,4 @@
|
|
|
-import { HTMLAttributes } from 'react'
|
|
|
+import { HTMLAttributes, useState } from 'react'
|
|
|
import { cn } from '@/lib/utils'
|
|
|
import { zodResolver } from '@hookform/resolvers/zod'
|
|
|
import { useForm } from 'react-hook-form'
|
|
|
@@ -13,6 +13,12 @@ import {
|
|
|
FormMessage,
|
|
|
} from '@/components/ui/form'
|
|
|
import { Input } from '@/components/ui/input'
|
|
|
+import { Link } from 'react-router-dom'
|
|
|
+import {
|
|
|
+ IconBrandFacebook,
|
|
|
+ IconBrandGithub,
|
|
|
+ IconLoader2,
|
|
|
+} from '@tabler/icons-react'
|
|
|
|
|
|
interface UserAuthFormProps extends HTMLAttributes<HTMLDivElement> {}
|
|
|
|
|
|
@@ -32,6 +38,8 @@ const formSchema = z.object({
|
|
|
})
|
|
|
|
|
|
export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
|
|
|
+ const [isLoading, setIsLoading] = useState(false)
|
|
|
+
|
|
|
const form = useForm<z.infer<typeof formSchema>>({
|
|
|
resolver: zodResolver(formSchema),
|
|
|
defaultValues: {
|
|
|
@@ -40,8 +48,13 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
|
|
|
},
|
|
|
})
|
|
|
|
|
|
- function onSubmit(variables: z.infer<typeof formSchema>) {
|
|
|
- console.log(variables)
|
|
|
+ function onSubmit(data: z.infer<typeof formSchema>) {
|
|
|
+ setIsLoading(true)
|
|
|
+ console.log(data)
|
|
|
+
|
|
|
+ setTimeout(() => {
|
|
|
+ setIsLoading(false)
|
|
|
+ }, 3000)
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
@@ -67,7 +80,15 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
|
|
|
name='password'
|
|
|
render={({ field }) => (
|
|
|
<FormItem className='space-y-1'>
|
|
|
- <FormLabel>Password</FormLabel>
|
|
|
+ <div className='flex items-center justify-between'>
|
|
|
+ <FormLabel>Password</FormLabel>
|
|
|
+ <Link
|
|
|
+ to='/forgot-password'
|
|
|
+ className='text-sm font-medium text-muted-foreground hover:opacity-75'
|
|
|
+ >
|
|
|
+ Forgot password?
|
|
|
+ </Link>
|
|
|
+ </div>
|
|
|
<FormControl>
|
|
|
<Input placeholder='********' {...field} type='password' />
|
|
|
</FormControl>
|
|
|
@@ -75,7 +96,52 @@ export function UserAuthForm({ className, ...props }: UserAuthFormProps) {
|
|
|
</FormItem>
|
|
|
)}
|
|
|
/>
|
|
|
- <Button className='mt-2'>Login</Button>
|
|
|
+ <Button className='mt-2' disabled={isLoading}>
|
|
|
+ {isLoading && (
|
|
|
+ <IconLoader2 className='mr-2 h-4 w-4 animate-spin' />
|
|
|
+ )}
|
|
|
+ Login
|
|
|
+ </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='flex items-center gap-2'>
|
|
|
+ <Button
|
|
|
+ variant='outline'
|
|
|
+ className='w-full'
|
|
|
+ type='button'
|
|
|
+ disabled={isLoading}
|
|
|
+ >
|
|
|
+ {isLoading ? (
|
|
|
+ <IconLoader2 className='mr-2 h-4 w-4 animate-spin' />
|
|
|
+ ) : (
|
|
|
+ <IconBrandGithub className='mr-2 h-4 w-4' />
|
|
|
+ )}{' '}
|
|
|
+ GitHub
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ variant='outline'
|
|
|
+ className='w-full'
|
|
|
+ type='button'
|
|
|
+ disabled={isLoading}
|
|
|
+ >
|
|
|
+ {isLoading ? (
|
|
|
+ <IconLoader2 className='mr-2 h-4 w-4 animate-spin' />
|
|
|
+ ) : (
|
|
|
+ <IconBrandFacebook className='mr-2 h-4 w-4' />
|
|
|
+ )}{' '}
|
|
|
+ Facebook
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</form>
|
|
|
</Form>
|