import { useForm } from 'react-hook-form'; import { zodResolver } from '@hookform/resolvers/zod'; import { z } from 'zod'; import { useNavigate } from 'react-router-dom'; import { useAuthStore } from '../store/authStore'; import { formatErrorMessage } from '@/utils/apiErrorHandler'; import type { LoginRequest } from '@/services/api/auth'; import type { ApiError } from '@/schemas/apiSchemas'; import { Input, Button } from '@veza/design-system'; import { logger } from '@/utils/logger'; import { useFormValidation } from '@/hooks/useFormValidation'; import { useEffect } from 'react'; const loginSchema = z.object({ email: z.string().email('Email invalide'), password: z.string().min(1, 'Le mot de passe est requis'), remember_me: z.boolean().optional(), }); type LoginFormData = z.infer; /** * LoginForm with Kōdō Design System * MIGRATED: Now using Kōdō Input and Button components */ export const LoginForm = () => { const navigate = useNavigate(); const { login: loginStore, isLoading, error } = useAuthStore(); const { register, handleSubmit, formState: { errors }, watch, } = useForm({ resolver: zodResolver(loginSchema), defaultValues: { email: '', password: '', remember_me: false, }, }); // Action 5.2.1.2: Pre-validation with backend const formData = watch(); const { validate, errors: backendErrors } = useFormValidation({ type: 'LoginRequest', debounceMs: 300, }); // Validate on form data change (debounced) useEffect(() => { const hasData = formData.email || formData.password; if (hasData) { const loginData: LoginRequest = { email: formData.email || '', password: formData.password || '', remember_me: formData.remember_me || false, }; validate(loginData); } }, [formData.email, formData.password, formData.remember_me, validate]); const onSubmit = async (data: LoginFormData) => { try { const loginRequest: LoginRequest = { email: data.email, password: data.password, remember_me: data.remember_me || false, }; await loginStore(loginRequest); // Redirection après succès navigate('/dashboard'); } catch (err) { // L'erreur est déjà gérée par le store logger.error('Login error', { error: err instanceof Error ? err.message : String(err), stack: err instanceof Error ? err.stack : undefined, }); } }; return (

Connexion

{error && (
{formatErrorMessage(error as ApiError)}
)}
{errors.email && ( )} {backendErrors .filter((e) => e.field === 'email') .map((e, i) => ( ))}
{errors.password && ( )} {backendErrors .filter((e) => e.field === 'password') .map((e, i) => ( ))}
); };