'use client'; import { useState, useEffect, useCallback, useMemo } from 'react'; import { useRouter } from 'next/navigation'; import { adminService } from '@/services/admin.service'; import { User, CreateEmployeeData, UpdateUserData, PaginatedResponse } from '@/types'; import { Pagination } from '@/components/ui'; import { Search, UserPlus, X, Filter, RefreshCw, Users, Shield, Briefcase, UserCheck } from 'lucide-react'; export default function UserManagement() { const router = useRouter(); const [users, setUsers] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [page, setPage] = useState(1); const [totalPages, setTotalPages] = useState(1); const [filterRole, setFilterRole] = useState(''); const [filterStatus, setFilterStatus] = useState(''); const [searchQuery, setSearchQuery] = useState(''); // Filtrage côté client par nom/email const filteredUsers = useMemo(() => { if (!searchQuery.trim()) return users; const query = searchQuery.toLowerCase().trim(); return users.filter(user => user.firstName?.toLowerCase().includes(query) || user.lastName?.toLowerCase().includes(query) || user.email?.toLowerCase().includes(query) || `${user.firstName} ${user.lastName}`.toLowerCase().includes(query) ); }, [users, searchQuery]); // Modals const [isCreateEmployeeModalOpen, setIsCreateEmployeeModalOpen] = useState(false); const [isEditUserModalOpen, setIsEditUserModalOpen] = useState(false); const [editingUser, setEditingUser] = useState(null); // Form data const [employeeFormData, setEmployeeFormData] = useState({ email: '', password: '', firstName: '', lastName: '', }); const [userFormData, setUserFormData] = useState({}); const loadUsers = useCallback(async () => { try { setLoading(true); setError(null); const filters: any = {}; if (filterRole) filters.role = filterRole; if (filterStatus) filters.isActive = filterStatus === 'active'; const response: PaginatedResponse = await adminService.getAllUsers( page, 100, // Charger plus pour le filtrage côté client Object.keys(filters).length > 0 ? filters : undefined ); setUsers(response.data || []); setTotalPages(response.totalPages || 1); } catch (err: any) { setError(err.message || 'Erreur lors du chargement des utilisateurs'); setUsers([]); } finally { setLoading(false); } }, [page, filterRole, filterStatus]); useEffect(() => { loadUsers(); }, [loadUsers]); const handleCreateEmployee = async (e: React.FormEvent) => { e.preventDefault(); try { await adminService.createEmployee(employeeFormData); setIsCreateEmployeeModalOpen(false); setEmployeeFormData({ email: '', password: '', firstName: '', lastName: '' }); loadUsers(); } catch (err: any) { alert(err.message || 'Erreur lors de la création de l\'employé'); } }; const handleEditUser = (user: User) => { setEditingUser(user); setUserFormData({ role: user.role, firstName: user.firstName, lastName: user.lastName, }); setIsEditUserModalOpen(true); }; const handleUpdateUser = async (e: React.FormEvent) => { e.preventDefault(); if (!editingUser) return; try { await adminService.updateUser(editingUser.id, userFormData); setIsEditUserModalOpen(false); setEditingUser(null); loadUsers(); } catch (err: any) { alert(err.message || 'Erreur lors de la modification de l\'utilisateur'); } }; const handleToggleUserStatus = async (user: User) => { const action = user.isActive ? 'désactiver' : 'réactiver'; if (!confirm(`Êtes-vous sûr de vouloir ${action} cet utilisateur ?`)) return; try { await adminService.updateUser(user.id, { isActive: !user.isActive }); loadUsers(); } catch (err: any) { alert(err.message || `Erreur lors de la ${action}ation`); } }; const getRoleBadgeColor = (role: string) => { switch (role) { case 'ADMIN': return 'bg-red-100 text-red-800'; case 'EMPLOYEE': return 'bg-blue-100 text-blue-800'; case 'CLIENT': return 'bg-green-100 text-green-800'; default: return 'bg-gray-100 text-gray-800'; } }; // Fonction pour obtenir les initiales const getInitials = (firstName?: string, lastName?: string) => { const f = firstName?.charAt(0) || ''; const l = lastName?.charAt(0) || ''; return (f + l).toUpperCase() || '?'; }; // Fonction pour obtenir la couleur de l'avatar selon le rôle const getAvatarColor = (role: string) => { switch (role) { case 'ADMIN': return 'bg-gradient-to-br from-red-500 to-red-600'; case 'EMPLOYEE': return 'bg-gradient-to-br from-blue-500 to-blue-600'; case 'CLIENT': return 'bg-gradient-to-br from-green-500 to-green-600'; default: return 'bg-gradient-to-br from-gray-500 to-gray-600'; } }; // Compter les utilisateurs par rôle const roleStats = useMemo(() => { const stats = { ADMIN: 0, EMPLOYEE: 0, CLIENT: 0 }; filteredUsers.forEach(user => { if (user.role in stats) { stats[user.role as keyof typeof stats]++; } }); return stats; }, [filteredUsers]); if (loading && users.length === 0) { return (

Chargement des utilisateurs...

); } return (
{/* Section recherche */}
setSearchQuery(e.target.value)} className="w-full pl-12 pr-4 py-3 rounded-xl bg-white text-gray-900 placeholder-gray-400 border border-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" />
{error && (
{error}
)} {/* Stats rapides */}

{filteredUsers.length}

Total

{roleStats.CLIENT}

Clients

{roleStats.EMPLOYEE}

Employés

{roleStats.ADMIN}

Admins

{/* Table des utilisateurs */}
{filteredUsers.length === 0 ? ( ) : ( filteredUsers.map((user) => ( )) )}
Utilisateur Rôle Statut Date création Actions

{searchQuery ? 'Aucun résultat pour cette recherche' : 'Aucun utilisateur trouvé'}

{getInitials(user.firstName, user.lastName)}
{user.firstName} {user.lastName}
{user.email}
{user.role === 'ADMIN' ? 'Admin' : user.role === 'EMPLOYEE' ? 'Employé' : 'Client'}
{user.isActive !== false ? 'Actif' : 'Inactif'}
{new Date(user.createdAt).toLocaleDateString('fr-FR')}
{/* Pagination */} {/* Modal créer employé */} {isCreateEmployeeModalOpen && (

Créer un employé

setEmployeeFormData({ ...employeeFormData, email: e.target.value })} className="w-full border border-gray-200 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="email@exemple.com" required />
setEmployeeFormData({ ...employeeFormData, password: e.target.value })} className="w-full border border-gray-200 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="••••••••" required />
setEmployeeFormData({ ...employeeFormData, firstName: e.target.value })} className="w-full border border-gray-200 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Jean" required />
setEmployeeFormData({ ...employeeFormData, lastName: e.target.value })} className="w-full border border-gray-200 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent" placeholder="Dupont" required />
)} {/* Modal modifier utilisateur */} {isEditUserModalOpen && editingUser && (

Modifier l'utilisateur

{getInitials(editingUser.firstName, editingUser.lastName)}

{editingUser.firstName} {editingUser.lastName}

{editingUser.email}

)}
); }