import { useState, useCallback, useRef } from 'react'; import { PhaseChantier, PhaseFormData } from '../types/btp-extended'; import phaseService from '../services/phaseService'; import { Toast } from 'primereact/toast'; interface UsePhasesManagerProps { chantierId?: string; onPhasesChange?: () => void; } export const usePhasesManager = ({ chantierId, onPhasesChange }: UsePhasesManagerProps = {}) => { const [phases, setPhases] = useState([]); const [loading, setLoading] = useState(false); const [selectedPhase, setSelectedPhase] = useState(null); const toast = useRef(null); // Chargement des phases const loadPhases = useCallback(async () => { setLoading(true); try { let phasesData: PhaseChantier[]; if (chantierId) { console.log('Chargement des phases pour le chantier:', chantierId); phasesData = await phaseService.getByChantier(chantierId); } else { console.log('Chargement de toutes les phases'); phasesData = await phaseService.getAll(); } console.log('Phases récupérées:', phasesData); setPhases(phasesData); if (onPhasesChange) { onPhasesChange(); } } catch (error) { console.error('Erreur lors du chargement des phases:', error); showError('Impossible de charger les phases'); } finally { setLoading(false); } }, [chantierId, onPhasesChange]); // Création d'une phase const createPhase = useCallback(async (phaseData: PhaseFormData) => { try { setLoading(true); const newPhase = await phaseService.create({ ...phaseData, chantierId: chantierId || phaseData.chantierId, statut: 'PLANIFIEE' }); await loadPhases(); showSuccess(`La phase "${phaseData.nom}" a été créée`); return newPhase; } catch (error) { console.error('Erreur lors de la création de la phase:', error); showError('Impossible de créer la phase'); throw error; } finally { setLoading(false); } }, [chantierId, loadPhases]); // Mise à jour d'une phase const updatePhase = useCallback(async (phaseId: string, phaseData: Partial) => { try { setLoading(true); const updatedPhase = await phaseService.update(phaseId, phaseData); await loadPhases(); showSuccess(`La phase a été mise à jour`); return updatedPhase; } catch (error) { console.error('Erreur lors de la mise à jour de la phase:', error); showError('Impossible de mettre à jour la phase'); throw error; } finally { setLoading(false); } }, [loadPhases]); // Suppression d'une phase const deletePhase = useCallback(async (phaseId: string) => { try { setLoading(true); await phaseService.delete(phaseId); await loadPhases(); showSuccess('La phase a été supprimée'); } catch (error) { console.error('Erreur lors de la suppression de la phase:', error); showError('Impossible de supprimer la phase'); throw error; } finally { setLoading(false); } }, [loadPhases]); // Démarrage d'une phase const startPhase = useCallback(async (phaseId: string) => { try { setLoading(true); await phaseService.demarrer(phaseId); await loadPhases(); showSuccess('La phase a été démarrée'); } catch (error) { console.error('Erreur lors du démarrage de la phase:', error); showError('Impossible de démarrer la phase'); throw error; } finally { setLoading(false); } }, [loadPhases]); // Mise à jour de l'avancement const updateProgress = useCallback(async (phaseId: string, pourcentage: number) => { try { setLoading(true); await phaseService.updateAvancement(phaseId, pourcentage); await loadPhases(); showSuccess('L\'avancement a été mis à jour'); } catch (error) { console.error('Erreur lors de la mise à jour de l\'avancement:', error); showError('Impossible de mettre à jour l\'avancement'); throw error; } finally { setLoading(false); } }, [loadPhases]); // Terminer une phase const completePhase = useCallback(async (phaseId: string) => { try { setLoading(true); await phaseService.terminer(phaseId); await loadPhases(); showSuccess('La phase a été terminée'); } catch (error) { console.error('Erreur lors de la terminaison de la phase:', error); showError('Impossible de terminer la phase'); throw error; } finally { setLoading(false); } }, [loadPhases]); // Suspendre une phase const suspendPhase = useCallback(async (phaseId: string, motif: string) => { try { setLoading(true); await phaseService.suspendre(phaseId, motif); await loadPhases(); showSuccess('La phase a été suspendue'); } catch (error) { console.error('Erreur lors de la suspension de la phase:', error); showError('Impossible de suspendre la phase'); throw error; } finally { setLoading(false); } }, [loadPhases]); // Reprendre une phase const resumePhase = useCallback(async (phaseId: string) => { try { setLoading(true); await phaseService.reprendre(phaseId); await loadPhases(); showSuccess('La phase a été reprise'); } catch (error) { console.error('Erreur lors de la reprise de la phase:', error); showError('Impossible de reprendre la phase'); throw error; } finally { setLoading(false); } }, [loadPhases]); // Créer une sous-phase const createSubPhase = useCallback(async (parentPhaseId: string, subPhaseData: PhaseFormData) => { try { setLoading(true); const parentPhase = phases.find(p => p.id === parentPhaseId); if (!parentPhase) { throw new Error('Phase parente non trouvée'); } const newSubPhase = await phaseService.create({ ...subPhaseData, chantierId: parentPhase.chantierId || chantierId, phaseParent: parentPhaseId, statut: 'PLANIFIEE' }); await loadPhases(); showSuccess(`La sous-phase "${subPhaseData.nom}" a été créée`); return newSubPhase; } catch (error) { console.error('Erreur lors de la création de la sous-phase:', error); showError('Impossible de créer la sous-phase'); throw error; } finally { setLoading(false); } }, [phases, chantierId, loadPhases]); // Statistiques const getStatistics = useCallback(() => { const stats = { total: phases.length, planifiees: phases.filter(p => p.statut === 'PLANIFIEE').length, enCours: phases.filter(p => p.statut === 'EN_COURS').length, terminees: phases.filter(p => p.statut === 'TERMINEE').length, enRetard: phases.filter(p => { if (!p.dateFinPrevue || p.statut === 'TERMINEE') return false; return new Date(p.dateFinPrevue) < new Date(); }).length, critiques: phases.filter(p => p.priorite === 'CRITIQUE' || p.priorite === 'HAUTE').length, avancementMoyen: phases.length > 0 ? Math.round(phases.reduce((sum, p) => sum + (p.pourcentageAvancement || 0), 0) / phases.length) : 0 }; return stats; }, [phases]); // Helpers pour les notifications const showSuccess = (message: string) => { if (toast.current) { toast.current.show({ severity: 'success', summary: 'Succès', detail: message, life: 3000 }); } }; const showError = (message: string) => { if (toast.current) { toast.current.show({ severity: 'error', summary: 'Erreur', detail: message, life: 5000 }); } }; // Attacher la ref toast const setToastRef = (ref: any) => { toast.current = ref; }; return { // État phases, loading, selectedPhase, setSelectedPhase, // Actions CRUD loadPhases, createPhase, updatePhase, deletePhase, createSubPhase, // Actions métier startPhase, completePhase, suspendPhase, resumePhase, updateProgress, // Statistiques getStatistics, // Helpers setToastRef, showSuccess, showError }; }; export default usePhasesManager;