'use client'; import { useState, useEffect, useRef } from 'react'; import TrajetMap from './TrajetMap'; import AddressAutocomplete from './AddressAutocomplete'; import { useNotification } from './NotificationProvider'; interface Adherent { id: string; nom: string; prenom: string; adresse: string; telephone: string; email: string; } interface Chauffeur { id: string; nom: string; prenom: string; telephone: string; email: string; } interface TrajetFormProps { onClose: () => void; onSuccess: () => void; trajetToEdit?: { id: string; date: string; adresseDepart: string; adresseArrivee: string; commentaire?: string | null; statut: string; adherentId: string; chauffeurId?: string | null; }; } export default function TrajetForm({ onClose, onSuccess, trajetToEdit }: TrajetFormProps) { const { showNotification } = useNotification(); const [loading, setLoading] = useState(false); const [adherents, setAdherents] = useState([]); const [chauffeurs, setChauffeurs] = useState([]); const [searchAdherent, setSearchAdherent] = useState(''); const [searchChauffeur, setSearchChauffeur] = useState(''); const [showAdherentDropdown, setShowAdherentDropdown] = useState(false); const [showChauffeurDropdown, setShowChauffeurDropdown] = useState(false); const adherentDropdownRef = useRef(null); const chauffeurDropdownRef = useRef(null); const [formData, setFormData] = useState({ adherentId: trajetToEdit?.adherentId || '', adherentNom: '', adherentPrenom: '', adherentAdresse: '', adherentTelephone: '', chauffeurId: trajetToEdit?.chauffeurId || '', chauffeurNom: '', chauffeurPrenom: '', chauffeurTelephone: '', date: trajetToEdit ? new Date(trajetToEdit.date).toISOString().split('T')[0] : '', heure: trajetToEdit ? new Date(trajetToEdit.date).toTimeString().slice(0, 5) : '', adresseDepart: trajetToEdit?.adresseDepart || '', adresseArrivee: trajetToEdit?.adresseArrivee || '', commentaire: trajetToEdit?.commentaire || '', }); useEffect(() => { fetchAdherents(); fetchChauffeurs(); }, []); useEffect(() => { // Si on modifie un trajet, charger les données de l'adhérent et du chauffeur if (trajetToEdit) { if (trajetToEdit.adherentId) { fetch(`/api/adherents/${trajetToEdit.adherentId}`) .then(res => res.json()) .then(data => { if (data) { setFormData(prev => ({ ...prev, adherentId: data.id, adherentNom: data.nom, adherentPrenom: data.prenom, adherentAdresse: data.adresse, adherentTelephone: data.telephone, adresseDepart: data.adresse, })); setSearchAdherent(`${data.prenom} ${data.nom}`); } }) .catch(console.error); } if (trajetToEdit.chauffeurId) { fetch(`/api/chauffeurs/${trajetToEdit.chauffeurId}`) .then(res => res.json()) .then(data => { if (data) { setFormData(prev => ({ ...prev, chauffeurId: data.id, chauffeurNom: data.nom, chauffeurPrenom: data.prenom, chauffeurTelephone: data.telephone, })); setSearchChauffeur(`${data.prenom} ${data.nom}`); } }) .catch(console.error); } } }, [trajetToEdit]); // Fermer les dropdowns quand on clique en dehors useEffect(() => { const handleClickOutside = (event: MouseEvent) => { if ( adherentDropdownRef.current && !adherentDropdownRef.current.contains(event.target as Node) ) { setShowAdherentDropdown(false); } if ( chauffeurDropdownRef.current && !chauffeurDropdownRef.current.contains(event.target as Node) ) { setShowChauffeurDropdown(false); } }; document.addEventListener('mousedown', handleClickOutside); return () => { document.removeEventListener('mousedown', handleClickOutside); }; }, []); const fetchAdherents = async () => { try { const response = await fetch('/api/adherents'); if (response.ok) { const data = await response.json(); setAdherents(data); } } catch (error) { console.error('Erreur lors du chargement des adhérents:', error); } }; const fetchChauffeurs = async () => { try { const response = await fetch('/api/chauffeurs'); if (response.ok) { const data = await response.json(); setChauffeurs(data); } } catch (error) { console.error('Erreur lors du chargement des chauffeurs:', error); } }; const handleSelectAdherent = (adherent: Adherent) => { setFormData({ ...formData, adherentId: adherent.id, adherentNom: adherent.nom, adherentPrenom: adherent.prenom, adherentAdresse: adherent.adresse, adherentTelephone: adherent.telephone, adresseDepart: adherent.adresse, // Remplir automatiquement l'adresse de départ }); setSearchAdherent(`${adherent.prenom} ${adherent.nom}`); setShowAdherentDropdown(false); }; const handleSelectChauffeur = (chauffeur: Chauffeur) => { setFormData({ ...formData, chauffeurId: chauffeur.id, chauffeurNom: chauffeur.nom, chauffeurPrenom: chauffeur.prenom, chauffeurTelephone: chauffeur.telephone, }); setSearchChauffeur(`${chauffeur.prenom} ${chauffeur.nom}`); setShowChauffeurDropdown(false); }; const filteredAdherents = adherents.filter( (a) => !searchAdherent || `${a.prenom} ${a.nom}`.toLowerCase().includes(searchAdherent.toLowerCase()) || a.email.toLowerCase().includes(searchAdherent.toLowerCase()) || a.telephone.includes(searchAdherent) ); const filteredChauffeurs = chauffeurs.filter( (c) => !searchChauffeur || `${c.prenom} ${c.nom}`.toLowerCase().includes(searchChauffeur.toLowerCase()) || c.email.toLowerCase().includes(searchChauffeur.toLowerCase()) || c.telephone.includes(searchChauffeur) ); const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); setLoading(true); try { // Combiner date et heure const dateTime = formData.date && formData.heure ? new Date(`${formData.date}T${formData.heure}`).toISOString() : formData.date ? new Date(`${formData.date}T09:00`).toISOString() : new Date().toISOString(); const url = trajetToEdit ? `/api/trajets/${trajetToEdit.id}` : '/api/trajets'; const method = trajetToEdit ? 'PUT' : 'POST'; const response = await fetch(url, { method, headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ date: dateTime, adresseDepart: formData.adresseDepart, adresseArrivee: formData.adresseArrivee, commentaire: formData.commentaire || null, statut: trajetToEdit?.statut || 'Planifié', adherentId: formData.adherentId, chauffeurId: formData.chauffeurId || null, }), }); if (response.ok) { showNotification( 'success', trajetToEdit ? 'Trajet modifié avec succès' : 'Trajet créé avec succès' ); onSuccess(); onClose(); } else { const error = await response.json(); showNotification('error', error.error || `Erreur lors de la ${trajetToEdit ? 'modification' : 'création'} du trajet`); } } catch (error) { console.error(`Erreur lors de la ${trajetToEdit ? 'modification' : 'création'} du trajet:`, error); showNotification('error', `Erreur lors de la ${trajetToEdit ? 'modification' : 'création'} du trajet`); } finally { setLoading(false); } }; const getInitials = (nom: string, prenom: string) => { return `${prenom.charAt(0)}${nom.charAt(0)}`.toUpperCase(); }; return (
{/* Header */}

{trajetToEdit ? 'Modifier le trajet' : 'Nouveau trajet'}

{trajetToEdit ? 'Modifiez les informations du trajet' : 'Créez un nouveau trajet pour un adhérent'}

{/* Content */}
{/* Colonne gauche - Formulaire */}
{/* Sélection adhérent */}
{ setSearchAdherent(e.target.value); setShowAdherentDropdown(true); }} onFocus={() => setShowAdherentDropdown(true)} className="w-full px-4 py-2.5 border border-gray-300 rounded-lg text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-lblue focus:border-transparent" /> {showAdherentDropdown && filteredAdherents.length > 0 && (
{filteredAdherents.map((adherent) => ( ))}
)}
{formData.adherentId && (
{getInitials(formData.adherentNom, formData.adherentPrenom)}
{formData.adherentPrenom} {formData.adherentNom}
{formData.adherentTelephone}
{formData.adherentAdresse}
)}
{/* Sélection chauffeur */}
{ setSearchChauffeur(e.target.value); setShowChauffeurDropdown(true); }} onFocus={() => setShowChauffeurDropdown(true)} className="w-full px-4 py-2.5 border border-gray-300 rounded-lg text-gray-900 placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-lblue focus:border-transparent" /> {showChauffeurDropdown && filteredChauffeurs.length > 0 && (
{filteredChauffeurs.map((chauffeur) => ( ))}
)}
{formData.chauffeurId && (
{getInitials(formData.chauffeurNom, formData.chauffeurPrenom)}
{formData.chauffeurPrenom} {formData.chauffeurNom}
{formData.chauffeurTelephone}
)}
{/* Date et heure */}
setFormData({ ...formData, date: e.target.value })} className="w-full px-4 py-2.5 border border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-lblue focus:border-transparent" />
setFormData({ ...formData, heure: e.target.value })} className="w-full px-4 py-2.5 border border-gray-300 rounded-lg text-gray-900 focus:outline-none focus:ring-2 focus:ring-lblue focus:border-transparent" />
{/* Adresse de départ */}
setFormData({ ...formData, adresseDepart: address })} placeholder="Rechercher une adresse de départ..." required />
{/* Adresse d'arrivée */}
setFormData({ ...formData, adresseArrivee: address })} placeholder="Rechercher une adresse d'arrivée..." required />
{/* Commentaire */}