85 lines
2.9 KiB
TypeScript
85 lines
2.9 KiB
TypeScript
import { useNavigate, Link } from 'react-router-dom';
|
|
import { useState, useEffect } from 'react';
|
|
import { LoginForm, LoginFormData } from '@/components/forms/LoginForm';
|
|
import { useAuthStore } from '@/features/auth/store/authStore';
|
|
import { formatErrorMessage } from '@/utils/apiErrorHandler';
|
|
import { useToast } from '@/hooks/useToast';
|
|
import type { ApiError } from '@/types/api';
|
|
import {
|
|
Card,
|
|
CardContent,
|
|
CardDescription,
|
|
CardHeader,
|
|
CardTitle,
|
|
} from '@/components/ui/card';
|
|
import { Alert, AlertDescription } from '@/components/ui/alert';
|
|
|
|
// T0166: Page de connexion qui utilise le composant LoginForm
|
|
// T0167: Intègre l'API de connexion avec support remember_me
|
|
// T0170: Gestion d'erreurs améliorée avec messages spécifiques
|
|
export function Login() {
|
|
const navigate = useNavigate();
|
|
const { success, error: showErrorToast } = useToast();
|
|
const { login: loginStore, isLoading, error: storeError } = useAuthStore();
|
|
const [error, setError] = useState<string | null>(null);
|
|
|
|
// T0178: Vérifier s'il y a un message d'erreur stocké (session expirée)
|
|
useEffect(() => {
|
|
const authError = sessionStorage.getItem('auth_error');
|
|
if (authError) {
|
|
setError(authError);
|
|
showErrorToast(authError);
|
|
sessionStorage.removeItem('auth_error');
|
|
}
|
|
}, [showErrorToast]);
|
|
|
|
const handleSubmit = async (data: LoginFormData) => {
|
|
try {
|
|
setError(null);
|
|
|
|
// Le store gère déjà le login et le stockage des tokens
|
|
await loginStore({
|
|
email: data.email,
|
|
password: data.password,
|
|
remember_me: data.remember_me,
|
|
});
|
|
|
|
success('Login successful! Welcome back.');
|
|
navigate('/dashboard');
|
|
} catch (err: any) {
|
|
// Gestion d'erreurs avec formatErrorMessage
|
|
const errorMessage = formatErrorMessage(err as ApiError);
|
|
setError(errorMessage);
|
|
showErrorToast(errorMessage);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="flex min-h-screen items-center justify-center bg-background p-4">
|
|
<Card className="w-full max-w-md">
|
|
<CardHeader className="space-y-1">
|
|
<CardTitle className="text-2xl text-center">Sign in</CardTitle>
|
|
<CardDescription className="text-center">
|
|
Enter your email and password to access your account
|
|
</CardDescription>
|
|
</CardHeader>
|
|
<CardContent>
|
|
{(error || storeError) && (
|
|
<Alert variant="destructive" className="mb-4">
|
|
<AlertDescription>
|
|
{error || formatErrorMessage(storeError as ApiError)}
|
|
</AlertDescription>
|
|
</Alert>
|
|
)}
|
|
<LoginForm onSubmit={handleSubmit} disabled={isLoading} />
|
|
<div className="mt-4 text-center text-sm">
|
|
Don't have an account?{' '}
|
|
<Link to="/register" className="text-primary hover:underline">
|
|
Sign up
|
|
</Link>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
);
|
|
}
|