veza/apps/web/src/pages/auth/Login.tsx

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>
);
}