user-auth-form.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { z } from 'zod'
  2. import { useForm } from 'react-hook-form'
  3. import { zodResolver } from '@hookform/resolvers/zod'
  4. import { useNavigate } from '@tanstack/react-router'
  5. import { Loader2, LogIn } from 'lucide-react'
  6. import { toast } from 'sonner'
  7. import { useLogin } from '@/hooks/auth/useAuth'
  8. import { cn } from '@/lib/utils'
  9. import { Button } from '@/components/ui/button'
  10. import {
  11. Form,
  12. FormControl,
  13. FormField,
  14. FormItem,
  15. FormLabel,
  16. FormMessage,
  17. } from '@/components/ui/form'
  18. import { Input } from '@/components/ui/input'
  19. import { PasswordInput } from '@/components/password-input'
  20. const formSchema = z.object({
  21. username: z
  22. .string()
  23. .min(1, 'نام کاربری الزامی است')
  24. .min(3, 'نام کاربری باید حداقل ۳ کاراکتر باشد'),
  25. password: z
  26. .string()
  27. .min(1, 'رمز عبور الزامی است')
  28. .min(6, 'رمز عبور باید حداقل ۶ کاراکتر باشد'),
  29. })
  30. interface UserAuthFormProps extends React.HTMLAttributes<HTMLFormElement> {
  31. redirectTo?: string
  32. }
  33. export function UserAuthForm({
  34. className,
  35. redirectTo,
  36. ...props
  37. }: UserAuthFormProps) {
  38. const navigate = useNavigate()
  39. const { mutateAsync: login, isPending } = useLogin()
  40. const form = useForm<z.infer<typeof formSchema>>({
  41. resolver: zodResolver(formSchema),
  42. defaultValues: {
  43. username: '',
  44. password: '',
  45. },
  46. })
  47. const onSubmit = async (data: z.infer<typeof formSchema>) => {
  48. try {
  49. await login(data)
  50. toast.success('ورود با موفقیت انجام شد')
  51. navigate({
  52. to: redirectTo || '/',
  53. replace: true,
  54. })
  55. } catch {
  56. toast.error('نام کاربری یا رمز عبور اشتباه است')
  57. }
  58. }
  59. return (
  60. <Form {...form}>
  61. <form
  62. onSubmit={form.handleSubmit(onSubmit)}
  63. className={cn('grid gap-3', className)}
  64. {...props}
  65. >
  66. <FormField
  67. control={form.control}
  68. name='username'
  69. render={({ field }) => (
  70. <FormItem>
  71. <FormLabel>نام کاربری</FormLabel>
  72. <FormControl>
  73. <Input
  74. placeholder='نام کاربری یا شماره موبایل'
  75. autoComplete='username'
  76. {...field}
  77. />
  78. </FormControl>
  79. <FormMessage />
  80. </FormItem>
  81. )}
  82. />
  83. <FormField
  84. control={form.control}
  85. name='password'
  86. render={({ field }) => (
  87. <FormItem>
  88. <FormLabel>رمز عبور</FormLabel>
  89. <FormControl>
  90. <PasswordInput
  91. placeholder='********'
  92. autoComplete='current-password'
  93. {...field}
  94. />
  95. </FormControl>
  96. <FormMessage />
  97. </FormItem>
  98. )}
  99. />
  100. <Button className='mt-2' disabled={isPending}>
  101. {isPending ? (
  102. <Loader2 className='mr-2 h-4 w-4 animate-spin' />
  103. ) : (
  104. <LogIn className='mr-2 h-4 w-4' />
  105. )}
  106. ورود
  107. </Button>
  108. </form>
  109. </Form>
  110. )
  111. }