Added few functions
This commit is contained in:
@@ -4,6 +4,8 @@ import { useState, useEffect, useRef } from 'react';
|
||||
import TrajetMap from './TrajetMap';
|
||||
import AddressAutocomplete from './AddressAutocomplete';
|
||||
import { useNotification } from './NotificationProvider';
|
||||
import { calculerDureeTrajet } from '@/lib/trajet-duree';
|
||||
import { useBodyScrollLock } from '@/lib/body-scroll-lock';
|
||||
|
||||
interface Adherent {
|
||||
id: string;
|
||||
@@ -27,6 +29,8 @@ interface Chauffeur {
|
||||
prenom: string;
|
||||
telephone: string;
|
||||
email: string;
|
||||
heuresRestantes?: number;
|
||||
heuresContrat?: number;
|
||||
}
|
||||
|
||||
interface TrajetFormProps {
|
||||
@@ -47,6 +51,7 @@ interface TrajetFormProps {
|
||||
|
||||
export default function TrajetForm({ onClose, onSuccess, trajetToEdit }: TrajetFormProps) {
|
||||
const { showNotification } = useNotification();
|
||||
useBodyScrollLock(true); // TrajetForm est toujours affiché en modal quand monté
|
||||
const [loading, setLoading] = useState(false);
|
||||
const [adherents, setAdherents] = useState<Adherent[]>([]);
|
||||
const [chauffeurs, setChauffeurs] = useState<Chauffeur[]>([]);
|
||||
@@ -56,6 +61,7 @@ export default function TrajetForm({ onClose, onSuccess, trajetToEdit }: TrajetF
|
||||
const [showChauffeurDropdown, setShowChauffeurDropdown] = useState(false);
|
||||
const adherentDropdownRef = useRef<HTMLDivElement>(null);
|
||||
const chauffeurDropdownRef = useRef<HTMLDivElement>(null);
|
||||
const [dureeEstimee, setDureeEstimee] = useState<number | null>(null);
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
adherentId: trajetToEdit?.adherentId || '',
|
||||
@@ -83,6 +89,50 @@ export default function TrajetForm({ onClose, onSuccess, trajetToEdit }: TrajetF
|
||||
fetchChauffeurs();
|
||||
}, []);
|
||||
|
||||
// Heures minimales requises pour ce trajet (arrondi au supérieur pour être conservateur)
|
||||
const heuresRequerues = dureeEstimee != null ? Math.ceil(dureeEstimee) : 0;
|
||||
|
||||
// Calculer la durée du trajet quand les adresses sont remplies (pour filtrer les chauffeurs)
|
||||
useEffect(() => {
|
||||
if (!formData.adresseDepart?.trim() || !formData.adresseArrivee?.trim()) {
|
||||
setDureeEstimee(null);
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
calculerDureeTrajet(formData.adresseDepart, formData.adresseArrivee).then((duree) => {
|
||||
if (!cancelled && duree != null) {
|
||||
setDureeEstimee(duree);
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [formData.adresseDepart, formData.adresseArrivee]);
|
||||
|
||||
// Si la durée estimée exclut le chauffeur sélectionné, le désélectionner
|
||||
useEffect(() => {
|
||||
if (heuresRequerues > 0 && formData.chauffeurId) {
|
||||
const selectedChauffeur = chauffeurs.find((c) => c.id === formData.chauffeurId);
|
||||
if (selectedChauffeur) {
|
||||
const heuresDispo = selectedChauffeur.heuresRestantes ?? selectedChauffeur.heuresContrat ?? 35;
|
||||
if (heuresDispo < heuresRequerues) {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
chauffeurId: '',
|
||||
chauffeurNom: '',
|
||||
chauffeurPrenom: '',
|
||||
chauffeurTelephone: '',
|
||||
}));
|
||||
setSearchChauffeur('');
|
||||
showNotification(
|
||||
'warning',
|
||||
`${selectedChauffeur.prenom} ${selectedChauffeur.nom} n'a que ${heuresDispo}h disponibles (trajet estimé ~${dureeEstimee}h)`
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, [heuresRequerues, dureeEstimee, formData.chauffeurId, chauffeurs]);
|
||||
|
||||
useEffect(() => {
|
||||
// Si on modifie un trajet, charger les données de l'adhérent et du chauffeur
|
||||
if (trajetToEdit) {
|
||||
@@ -276,13 +326,20 @@ export default function TrajetForm({ onClose, onSuccess, trajetToEdit }: TrajetF
|
||||
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 filteredChauffeurs = chauffeurs
|
||||
.filter((c) => {
|
||||
// Exclure les chauffeurs qui n'ont pas assez d'heures restantes
|
||||
if (heuresRequerues > 0) {
|
||||
const heuresDispo = c.heuresRestantes ?? c.heuresContrat ?? 35;
|
||||
if (heuresDispo < heuresRequerues) return false;
|
||||
}
|
||||
return (
|
||||
!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();
|
||||
@@ -460,6 +517,11 @@ export default function TrajetForm({ onClose, onSuccess, trajetToEdit }: TrajetF
|
||||
<div>
|
||||
<label className="block text-sm font-semibold text-gray-900 mb-2">
|
||||
Chauffeur
|
||||
{dureeEstimee != null && (
|
||||
<span className="ml-2 text-xs font-normal text-gray-500">
|
||||
(trajet ~{dureeEstimee}h — chauffeurs avec <{heuresRequerues}h restantes masqués)
|
||||
</span>
|
||||
)}
|
||||
</label>
|
||||
<div className="relative" ref={chauffeurDropdownRef}>
|
||||
<input
|
||||
|
||||
Reference in New Issue
Block a user