admin/src/pages/Login.tsx

126 lines
5.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { useState } from 'react';
import { Navigate, useNavigate } from 'react-router-dom';
import { Eye, EyeOff, Lock, User } from 'lucide-react';
import { useForm } from 'react-hook-form';
import { yupResolver } from '@hookform/resolvers/yup';
import { useAuth } from '../contexts/AuthContext';
import { Button } from '../components/ui/Button';
import { Input } from '../components/ui/Input';
import { loginSchema, LoginFormData } from '../utils/validationSchemas';
import { useLogin } from './auth/core/_hooks';
export const Login = () => {
const { isAuthenticated, restoreSession } = useAuth();
const navigate = useNavigate();
const [showPassword, setShowPassword] = useState(false);
const [error, setError] = useState('');
const { mutate: login, isPending: isLoading } = useLogin();
const {
register,
handleSubmit,
formState: { errors, isValid },
} = useForm<LoginFormData>({
resolver: yupResolver(loginSchema),
mode: 'onChange',
});
if (isAuthenticated) {
return <Navigate to="/" replace />;
}
const onSubmit = async (data: LoginFormData) => {
setError('');
login(data, {
onSuccess: () => {
restoreSession();
navigate('/');
},
onError: () => {
setError('نام کاربری یا رمز عبور اشتباه است');
}
});
};
return (
<div className="min-h-screen flex items-center justify-center bg-gray-50 dark:bg-gray-900 py-12 px-4 sm:px-6 lg:px-8">
<div className="max-w-md w-full space-y-8">
<div>
<div className="mx-auto h-12 w-12 bg-primary-600 rounded-lg flex items-center justify-center">
<Lock className="h-6 w-6 text-white" />
</div>
<h2 className="mt-6 text-center text-3xl font-extrabold text-gray-900 dark:text-gray-100">
ورود به پنل مدیریت
</h2>
<p className="mt-2 text-center text-sm text-gray-600 dark:text-gray-400">
لطفا اطلاعات خود را وارد کنید
</p>
</div>
<form className="mt-8 space-y-6" onSubmit={handleSubmit(onSubmit)}>
<div className="space-y-4">
<Input
label="نام کاربری"
type="text"
placeholder="نام کاربری خود را وارد کنید"
icon={User}
error={errors.username?.message}
{...register('username')}
/>
<div className="space-y-1">
<label className="block text-sm font-medium text-gray-700 dark:text-gray-300">
رمز عبور
</label>
<div className="relative">
<div className="absolute inset-y-0 right-0 pr-3 flex items-center pointer-events-none">
<Lock className="h-5 w-5 text-gray-400" />
</div>
<input
type={showPassword ? 'text' : 'password'}
placeholder="رمز عبور خود را وارد کنید"
className={`input pr-10 pl-10 ${errors.password ? 'border-red-500 dark:border-red-500 focus:ring-red-500' : ''
}`}
{...register('password')}
/>
<button
type="button"
className="absolute inset-y-0 left-0 pl-3 flex items-center"
onClick={() => setShowPassword(!showPassword)}
>
{showPassword ? (
<EyeOff className="h-5 w-5 text-gray-400 hover:text-gray-600" />
) : (
<Eye className="h-5 w-5 text-gray-400 hover:text-gray-600" />
)}
</button>
</div>
{errors.password && (
<p className="text-sm text-red-600 dark:text-red-400">
{errors.password.message}
</p>
)}
</div>
</div>
{error && (
<div className="bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 text-red-600 dark:text-red-400 px-4 py-3 rounded-lg text-sm">
{error}
</div>
)}
<Button
type="submit"
loading={isLoading}
disabled={!isValid}
className="w-full"
>
ورود
</Button>
</form>
</div>
</div>
);
};