All files / hooks useEmployesManagement.ts

100% Statements 55/55
86.36% Branches 19/22
100% Functions 11/11
100% Lines 55/55

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 1502x   2x         2x 35x 35x 35x 35x 35x 35x         35x 15x 15x 15x 15x 14x   1x 1x 1x   15x             35x 3x 3x 3x   3x       2x   2x   1x 1x 1x 1x   3x             35x 2x 2x     2x 2x 4x                         2x       1x 1x 1x 1x             35x 3x           35x 3x           35x   44x 6x 6x                   44x       44x       35x 12x     35x                            
import { useState, useEffect } from 'react';
import { Employe, CreateEmployeRequest } from '@/types/employe/employe';
import { employeService } from '@/lib/api/services/employeService';
 
/**
 * Hook personnalisé pour la gestion des employés
 */
export function useEmployesManagement() {
  const [employes, setEmployes] = useState<Employe[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [searchTerm, setSearchTerm] = useState('');
  const [statusFilter, setStatusFilter] = useState<'all' | 'active' | 'inactive'>('all');
  const [isCreating, setIsCreating] = useState(false);
 
  /**
   * Charge la liste des employés
   */
  const loadEmployes = async () => {
    try {
      setLoading(true);
      setError(null);
      const data = await employeService.getEmployes();
      setEmployes(data);
    } catch (err: Error | unknown) {
      const errorMessage = err instanceof Error ? err.message : 'Erreur lors du chargement des employés';
      setError(errorMessage);
      console.error('Erreur chargement employés:', err);
    } finally {
      setLoading(false);
    }
  };
 
  /**
   * Crée un nouvel employé
   */
  const createEmploye = async (employeData: CreateEmployeRequest): Promise<boolean> => {
    try {
      setIsCreating(true);
      setError(null);
 
      await employeService.createEmploye(employeData);
 
      // Recharger la liste complète pour s'assurer d'avoir les vraies données de l'API
      // (y compris le statut is_active correct)
      await loadEmployes();
 
      return true;
    } catch (err: Error | unknown) {
      const errorMessage = err instanceof Error ? err.message : 'Erreur lors de la création de l\'employé';
      setError(errorMessage);
      console.error('Erreur création employé:', err);
      return false;
    } finally {
      setIsCreating(false);
    }
  };
 
  /**
   * Change l'état actif/inactif d'un employé
   */
  const toggleEmployeActive = async (employeId: number) => {
    try {
      setError(null);
 
      // Mise à jour optimiste : on met à jour l'état local immédiatement
      setEmployes(prevEmployes =>
        prevEmployes.map(employe =>
          employe.id === employeId
            ? {
                ...employe,
                user: {
                  ...employe.user,
                  is_active: !employe.user.is_active
                }
              }
            : employe
        )
      );
 
      // Appel API
      await employeService.setUnsetEmployeActive(employeId);
 
    } catch (err: Error | unknown) {
      // En cas d'erreur, on recharge la liste pour récupérer l'état correct
      await loadEmployes();
      const errorMessage = err instanceof Error ? err.message : 'Erreur lors de la modification du statut de l\'employé';
      setError(errorMessage);
      console.error('Erreur modification statut employé:', err);
    }
  };
 
  /**
   * Gère la recherche d'employés
   */
  const handleSearch = (term: string) => {
    setSearchTerm(term);
  };
 
  /**
   * Gère le filtre par statut
   */
  const handleStatusFilter = (status: 'all' | 'active' | 'inactive') => {
    setStatusFilter(status);
  };
 
  /**
   * Filtre les employés selon le terme de recherche et le statut
   */
  const filteredEmployes = employes.filter(employe => {
    // Filtre par terme de recherche
    const matchesSearch = !searchTerm || (() => {
      const searchLower = searchTerm.toLowerCase();
      return (
        employe.nom.toLowerCase().includes(searchLower) ||
        employe.prenom.toLowerCase().includes(searchLower) ||
        employe.matricule.toLowerCase().includes(searchLower) ||
        employe.identifiant_telephone.includes(searchTerm) ||
        employe.user.email.toLowerCase().includes(searchLower)
      );
    })();
 
    // Filtre par statut
    const matchesStatus = statusFilter === 'all' ||
      (statusFilter === 'active' && employe.user.is_active) ||
      (statusFilter === 'inactive' && !employe.user.is_active);
 
    return matchesSearch && matchesStatus;
  });
 
  // Chargement initial
  useEffect(() => {
    loadEmployes();
  }, []);
 
  return {
    employes: filteredEmployes,
    loading,
    error,
    searchTerm,
    statusFilter,
    isCreating,
    loadEmployes,
    createEmploye,
    handleSearch,
    handleStatusFilter,
    toggleEmployeActive
  };
}