"use client"; import { useState, useEffect } from "react"; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Plus, MoreHorizontal, Trash, Edit, Users } from "lucide-react"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuTrigger, } from "@/components/ui/dropdown-menu"; import { Label } from "@/components/ui/label"; import { toast } from "@/components/ui/use-toast"; interface Group { id: string; name: string; path: string; membersCount: number; } interface User { id: string; username: string; email: string; lastName: string; firstName: string; } interface ApiError { message: string; } interface GroupsTableProps { userRole?: string[]; } export function GroupsTable({ userRole = [] }: GroupsTableProps) { const [groups, setGroups] = useState([]); const [loading, setLoading] = useState(true); const [searchTerm, setSearchTerm] = useState(""); const [newGroupDialog, setNewGroupDialog] = useState(false); const [newGroupName, setNewGroupName] = useState(""); const [modifyGroupDialog, setModifyGroupDialog] = useState(false); const [selectedGroup, setSelectedGroup] = useState(null); const [modifiedGroupName, setModifiedGroupName] = useState(""); const [manageMembersDialog, setManageMembersDialog] = useState(false); const [groupMembers, setGroupMembers] = useState([]); const [availableUsers, setAvailableUsers] = useState([]); useEffect(() => { fetchGroups(); }, []); const fetchGroups = async () => { try { setLoading(true); const response = await fetch("/api/groups"); const data = await response.json(); if (!response.ok) { throw new Error(data.message || "Erreur lors de la récupération des groupes"); } const groupsWithCounts = await Promise.all( (Array.isArray(data) ? data : []).map(async (group) => { try { const membersResponse = await fetch(`/api/groups/${group.id}/members`); if (membersResponse.ok) { const members = await membersResponse.json(); return { ...group, membersCount: Array.isArray(members) ? members.length : 0 }; } return group; } catch (error) { console.error(`Error fetching members for group ${group.id}:`, error); return group; } }) ); setGroups(groupsWithCounts); } catch (error) { toast({ title: "Erreur", description: error instanceof Error ? error.message : "Une erreur est survenue", variant: "destructive", }); } finally { setLoading(false); } }; const handleCreateGroup = async () => { try { if (!newGroupName.trim()) { throw new Error("Le nom du groupe est requis"); } const response = await fetch("/api/groups", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: newGroupName }), }); const data = await response.json(); if (!response.ok) { throw new Error(data.message || "Erreur lors de la création du groupe"); } setGroups(prev => [...prev, data]); setNewGroupDialog(false); setNewGroupName(""); toast({ title: "Succès", description: "Le groupe a été créé avec succès", }); } catch (error) { toast({ title: "Erreur", description: error instanceof Error ? error.message : "Une erreur est survenue", variant: "destructive", }); } }; const handleDeleteGroup = async (groupId: string) => { try { const response = await fetch(`/api/groups/${groupId}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Erreur lors de la suppression du groupe"); } setGroups(prev => prev.filter(group => group.id !== groupId)); toast({ title: "Succès", description: "Le groupe a été supprimé avec succès", }); } catch (error) { toast({ title: "Erreur", description: error instanceof Error ? error.message : "Une erreur est survenue", variant: "destructive", }); } }; const handleModifyGroup = async (groupId: string) => { try { const group = groups.find(g => g.id === groupId); if (!group) return; setSelectedGroup(group); setModifiedGroupName(group.name); setModifyGroupDialog(true); } catch (error) { toast({ title: "Erreur", description: error instanceof Error ? error.message : "Une erreur est survenue", variant: "destructive", }); } }; const handleUpdateGroup = async () => { try { if (!selectedGroup || !modifiedGroupName.trim()) { throw new Error("Le nom du groupe est requis"); } const response = await fetch(`/api/groups/${selectedGroup.id}`, { method: "PUT", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ name: modifiedGroupName }), }); if (!response.ok) { throw new Error("Erreur lors de la modification du groupe"); } setGroups(prev => prev.map(group => group.id === selectedGroup.id ? { ...group, name: modifiedGroupName } : group )); setModifyGroupDialog(false); setSelectedGroup(null); setModifiedGroupName(""); toast({ title: "Succès", description: "Le groupe a été modifié avec succès", }); } catch (error) { toast({ title: "Erreur", description: error instanceof Error ? error.message : "Une erreur est survenue", variant: "destructive", }); } }; const handleManageMembers = async (groupId: string) => { const group = groups.find(g => g.id === groupId); if (!group) return; setSelectedGroup(group); try { const membersResponse = await fetch(`/api/groups/${groupId}/members`); if (!membersResponse.ok) throw new Error("Failed to fetch group members"); const members = await membersResponse.json(); setGroupMembers(members); setGroups(prev => prev.map(g => g.id === groupId ? { ...g, membersCount: members.length } : g )); const usersResponse = await fetch("/api/users"); if (!usersResponse.ok) throw new Error("Failed to fetch users"); const users = await usersResponse.json(); setAvailableUsers(users.filter((user: User) => !members.some((m: User) => m.id === user.id))); setManageMembersDialog(true); } catch (error) { toast({ title: "Erreur", description: "Erreur lors de la récupération des membres", variant: "destructive", }); } }; const handleAddMember = async (userId: string) => { if (!selectedGroup) return; try { const response = await fetch(`/api/groups/${selectedGroup.id}/members`, { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ userId }), }); if (!response.ok) { throw new Error("Failed to add member"); } const updatedMember = availableUsers.find(u => u.id === userId); if (updatedMember) { setGroupMembers(prev => [...prev, updatedMember]); setAvailableUsers(prev => prev.filter(u => u.id !== userId)); } setGroups(prev => prev.map(group => group.id === selectedGroup.id ? { ...group, membersCount: group.membersCount + 1 } : group )); toast({ title: "Success", description: "Member added successfully", }); } catch (error) { toast({ title: "Error", description: error instanceof Error ? error.message : "An error occurred", variant: "destructive", }); } }; const handleRemoveMember = async (userId: string) => { if (!selectedGroup) return; try { const response = await fetch(`/api/groups/${selectedGroup.id}/members/${userId}`, { method: "DELETE", }); if (!response.ok) { throw new Error("Failed to remove member"); } const removedMember = groupMembers.find(u => u.id === userId); if (removedMember) { setGroupMembers(prev => prev.filter(u => u.id !== userId)); setAvailableUsers(prev => [...prev, removedMember]); } setGroups(prev => prev.map(group => group.id === selectedGroup.id ? { ...group, membersCount: Math.max(0, group.membersCount - 1) } : group )); toast({ title: "Success", description: "Member removed successfully", }); } catch (error) { toast({ title: "Error", description: error instanceof Error ? error.message : "An error occurred", variant: "destructive", }); } }; const filteredGroups = groups.filter(group => group.name.toLowerCase().includes(searchTerm.toLowerCase()) ); return (

Gestion des groupes

setSearchTerm(e.target.value)} className="w-full bg-black/20 border-0 text-white placeholder:text-gray-400" />
Créer un nouveau groupe
setNewGroupName(e.target.value)} placeholder="Entrez le nom du groupe" />
Nom du groupe Chemin Nombre de membres Actions {filteredGroups.map((group) => ( {group.name} {group.path} {group.membersCount} Actions handleModifyGroup(group.id)} className="text-white hover:bg-black/50" > Modifier handleManageMembers(group.id)} className="text-white hover:bg-black/50" > Gérer les membres handleDeleteGroup(group.id)} > Supprimer ))}
Modifier le groupe
setModifiedGroupName(e.target.value)} placeholder="Entrez le nouveau nom du groupe" />
Gérer les membres du groupe {selectedGroup?.name}
{groupMembers.length === 0 ? (

No members

) : (
{groupMembers.map((member) => (

{member.lastName} {member.firstName}

{member.email}

))}
)}
{availableUsers.length === 0 ? (

No users available

) : (
{availableUsers .sort((a, b) => (a.lastName + a.firstName).localeCompare(b.lastName + b.firstName)) .map((user) => (

{user.lastName} {user.firstName}

{user.email}

))}
)}
); }