Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 19x 19x 19x 19x 19x 19x 19x 19x 19x 19x 3x 3x 3x 3x 1x 1x 1x 2x 19x 3x 3x 1x | import { useState } from 'react';
import { Link, useNavigate, useLocation } from 'react-router-dom';
import { Input } from '../ui/Input';
import { Button } from '../ui/Button';
import { useAuth } from '../../hooks/useAuth';
import { useToast } from '../ui/Toast';
import { Eye, EyeOff } from 'lucide-react';
import { useTranslation } from 'react-i18next';
function LoginForm() {
const { login } = useAuth();
const { error: toastError } = useToast();
const navigate = useNavigate();
const location = useLocation();
const { t } = useTranslation();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [showPassword, setShowPassword] = useState(false);
const [loading, setLoading] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
try {
await login(email, password);
const from = (location.state as any)?.from || '/';
navigate(from, { replace: true });
} catch (err) {
toastError(err instanceof Error ? err.message : t('login.loginFailed'));
} finally {
setLoading(false);
}
};
return (
<form onSubmit={handleSubmit} className="space-y-4">
<Input
label={t('login.email')}
type="email"
value={email}
onChange={e => setEmail(e.target.value)}
placeholder={t('login.emailPlaceholder')}
required
autoComplete="email"
/>
<div className="relative">
<Input
label={t('login.password')}
type={showPassword ? 'text' : 'password'}
value={password}
onChange={e => setPassword(e.target.value)}
placeholder={t('login.passwordPlaceholder')}
required
autoComplete="current-password"
/>
<button
type="button"
onClick={() => setShowPassword(!showPassword)}
className="absolute right-3 top-8 text-text-tertiary hover:text-text-primary"
>
{showPassword ? <EyeOff className="w-4 h-4" /> : <Eye className="w-4 h-4" />}
</button>
</div>
<Button type="submit" variant="primary" loading={loading} className="w-full">
{t('login.submit')}
</Button>
<p className="text-center text-[13px] text-text-tertiary">
{t('login.noAccount')}{' '}
<Link to="/register" className="text-accent hover:underline">
{t('login.registerNow')}
</Link>
</p>
<p className="text-center text-[13px]">
<Link to="/forgot-password" className="text-accent hover:underline">
{t('login.forgotPassword')}
</Link>
</p>
</form>
);
}
export { LoginForm };
|