dolibarr user
This commit is contained in:
parent
8596cddffe
commit
1e5df56832
@ -340,101 +340,101 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
|
||||
}
|
||||
};
|
||||
|
||||
const filteredGroups = groups.filter(group =>
|
||||
group.name.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
);
|
||||
if (loading) return <div className="text-center p-4">Loading...</div>;
|
||||
|
||||
return (
|
||||
<div className='flex flex-col space-y-4'>
|
||||
<div className='flex justify-between items-center mb-6'>
|
||||
<h1 className='text-2xl font-semibold text-white'>Gestion des groupes</h1>
|
||||
<div className="flex items-center space-x-4">
|
||||
<div className="relative w-64">
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Rechercher un groupe..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="w-full bg-black/20 border-0 text-white placeholder:text-gray-400"
|
||||
/>
|
||||
</div>
|
||||
<Dialog open={newGroupDialog} onOpenChange={setNewGroupDialog}>
|
||||
<DialogTrigger asChild>
|
||||
<Button variant="outline" className="bg-blue-600 text-white hover:bg-blue-700 border-0">
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
Nouveau groupe
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Créer un nouveau groupe</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Nom du groupe</Label>
|
||||
<Input
|
||||
id="name"
|
||||
value={newGroupName}
|
||||
onChange={(e) => setNewGroupName(e.target.value)}
|
||||
placeholder="Entrez le nom du groupe"
|
||||
/>
|
||||
</div>
|
||||
<Button onClick={handleCreateGroup} className="w-full">
|
||||
Créer le groupe
|
||||
</Button>
|
||||
<div className="space-y-4 p-6 bg-gray-100 rounded-lg">
|
||||
<div className="flex justify-between items-center">
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Rechercher un groupe..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="max-w-xs bg-white text-gray-900 border-gray-300"
|
||||
/>
|
||||
<Dialog open={newGroupDialog} onOpenChange={setNewGroupDialog}>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="bg-blue-600 hover:bg-blue-700 text-white">
|
||||
<Plus className="mr-2 h-4 w-4" /> Ajouter un groupe
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="bg-white text-black border border-gray-300">
|
||||
<DialogHeader>
|
||||
<DialogTitle className="text-gray-900">Nouveau Groupe</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="groupName" className="text-gray-900">Nom du groupe</Label>
|
||||
<Input
|
||||
id="groupName"
|
||||
value={newGroupName}
|
||||
onChange={(e) => setNewGroupName(e.target.value)}
|
||||
placeholder="Entrez le nom du groupe"
|
||||
className="bg-white text-gray-900 border-gray-300"
|
||||
/>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
<Button
|
||||
onClick={handleCreateGroup}
|
||||
className="w-full bg-blue-600 hover:bg-blue-700 text-white"
|
||||
>
|
||||
Créer le groupe
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
|
||||
<div className="rounded-lg overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="bg-black/20 border-0">
|
||||
<TableHead className="text-gray-400">Nom du groupe</TableHead>
|
||||
<TableHead className="text-gray-400">Chemin</TableHead>
|
||||
<TableHead className="text-gray-400">Nombre de membres</TableHead>
|
||||
<TableHead className="text-gray-400 text-right">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{filteredGroups.map((group) => (
|
||||
<TableRow
|
||||
key={group.id}
|
||||
className="border-0 bg-black/10 hover:bg-black/20"
|
||||
>
|
||||
<TableCell className="text-white">{group.name}</TableCell>
|
||||
<TableCell className="text-white">{group.path}</TableCell>
|
||||
<TableCell className="text-white">{group.membersCount}</TableCell>
|
||||
<Table className="bg-white border border-gray-300 rounded-md">
|
||||
<TableHeader className="bg-gray-50">
|
||||
<TableRow>
|
||||
<TableHead className="text-gray-900">Nom</TableHead>
|
||||
<TableHead className="text-gray-900">Chemin</TableHead>
|
||||
<TableHead className="text-gray-900">Membres</TableHead>
|
||||
<TableHead className="text-right text-gray-900">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{groups
|
||||
.filter(group =>
|
||||
group.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
group.path.toLowerCase().includes(searchTerm.toLowerCase())
|
||||
)
|
||||
.map((group) => (
|
||||
<TableRow key={group.id} className="hover:bg-gray-50 border-t border-gray-200">
|
||||
<TableCell className="text-gray-900 font-medium">{group.name}</TableCell>
|
||||
<TableCell className="text-gray-900">{group.path}</TableCell>
|
||||
<TableCell className="text-gray-900">{group.membersCount}</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
<Button variant="ghost" className="h-8 w-8 p-0 text-white hover:bg-black/20">
|
||||
<Button
|
||||
variant="ghost"
|
||||
className="h-8 w-8 p-0"
|
||||
>
|
||||
<span className="sr-only">Open menu</span>
|
||||
<MoreHorizontal className="h-4 w-4" />
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="end" className="bg-black/90 border-gray-700">
|
||||
<DropdownMenuLabel className="text-gray-400">Actions</DropdownMenuLabel>
|
||||
<DropdownMenuItem
|
||||
<DropdownMenuContent align="end" className="bg-white border border-gray-300">
|
||||
<DropdownMenuLabel className="text-gray-900">Actions</DropdownMenuLabel>
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleModifyGroup(group.id)}
|
||||
className="text-white hover:bg-black/50"
|
||||
className="text-gray-900 hover:bg-gray-100"
|
||||
>
|
||||
<Edit className="mr-2 h-4 w-4" />
|
||||
Modifier
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem
|
||||
<DropdownMenuItem
|
||||
onClick={() => handleManageMembers(group.id)}
|
||||
className="text-white hover:bg-black/50"
|
||||
className="text-gray-900 hover:bg-gray-100"
|
||||
>
|
||||
<Users className="mr-2 h-4 w-4" />
|
||||
Gérer les membres
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuSeparator className="bg-gray-700" />
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem
|
||||
className="text-red-400 hover:bg-black/50"
|
||||
onClick={() => handleDeleteGroup(group.id)}
|
||||
className="text-red-600 hover:bg-red-50 hover:text-red-700"
|
||||
>
|
||||
<Trash className="mr-2 h-4 w-4" />
|
||||
Supprimer
|
||||
@ -444,93 +444,102 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
</TableBody>
|
||||
</Table>
|
||||
|
||||
<Dialog open={modifyGroupDialog} onOpenChange={setModifyGroupDialog}>
|
||||
<DialogContent>
|
||||
<DialogContent className="bg-white text-black border border-gray-300">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Modifier le groupe</DialogTitle>
|
||||
<DialogTitle className="text-gray-900">Modifier le groupe</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Nom du groupe</Label>
|
||||
<Label htmlFor="modifiedGroupName" className="text-gray-900">Nom du groupe</Label>
|
||||
<Input
|
||||
id="name"
|
||||
id="modifiedGroupName"
|
||||
value={modifiedGroupName}
|
||||
onChange={(e) => setModifiedGroupName(e.target.value)}
|
||||
placeholder="Entrez le nouveau nom du groupe"
|
||||
className="bg-white text-gray-900 border-gray-300"
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
onClick={handleUpdateGroup}
|
||||
className="w-full"
|
||||
className="w-full bg-blue-600 hover:bg-blue-700 text-white"
|
||||
>
|
||||
Modifier
|
||||
Mettre à jour
|
||||
</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
|
||||
<Dialog open={manageMembersDialog} onOpenChange={setManageMembersDialog}>
|
||||
<DialogContent className="max-h-[80vh] overflow-y-auto">
|
||||
<DialogContent className="sm:max-w-[600px] max-h-[90vh] overflow-y-auto bg-white text-black border border-gray-300">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Gérer les membres du groupe {selectedGroup?.name}</DialogTitle>
|
||||
<DialogTitle className="text-gray-900">
|
||||
Gérer les membres - {selectedGroup?.name}
|
||||
</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>Current Members</Label>
|
||||
<div className="max-h-[200px] overflow-y-auto border rounded-md p-2">
|
||||
{groupMembers.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground">No members</p>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{groupMembers.map((member) => (
|
||||
<div key={member.id} className="flex items-center justify-between p-2 hover:bg-muted rounded-md">
|
||||
<div>
|
||||
<p className="font-medium">{member.lastName} {member.firstName}</p>
|
||||
<p className="text-sm text-muted-foreground">{member.email}</p>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleRemoveMember(member.id)}
|
||||
>
|
||||
<Trash className="h-4 w-4" />
|
||||
</Button>
|
||||
<div>
|
||||
<h3 className="text-lg font-medium mb-2 text-gray-900">Membres actuels</h3>
|
||||
{groupMembers.length === 0 ? (
|
||||
<p className="text-gray-600">Ce groupe n'a pas de membres.</p>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{groupMembers.map((member) => (
|
||||
<div key={member.id} className="flex items-center justify-between p-2 bg-gray-50 rounded-md border border-gray-200">
|
||||
<div className="text-gray-900">
|
||||
<div className="font-medium">{member.username}</div>
|
||||
<div className="text-sm text-gray-600">{member.firstName} {member.lastName} ({member.email})</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleRemoveMember(member.id)}
|
||||
className="text-red-600 hover:bg-red-50 hover:text-red-700 border-red-200"
|
||||
>
|
||||
<Trash className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>Add Member</Label>
|
||||
<div className="max-h-[200px] overflow-y-auto border rounded-md p-2">
|
||||
{availableUsers.length === 0 ? (
|
||||
<p className="text-sm text-muted-foreground">No users available</p>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{availableUsers
|
||||
.sort((a, b) => (a.lastName + a.firstName).localeCompare(b.lastName + b.firstName))
|
||||
.map((user) => (
|
||||
<div key={user.id} className="flex items-center justify-between p-2 hover:bg-muted rounded-md">
|
||||
<div>
|
||||
<p className="font-medium">{user.lastName} {user.firstName}</p>
|
||||
<p className="text-sm text-muted-foreground">{user.email}</p>
|
||||
</div>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleAddMember(user.id)}
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div>
|
||||
<h3 className="text-lg font-medium mb-2 text-gray-900">Ajouter des membres</h3>
|
||||
<Input
|
||||
type="text"
|
||||
placeholder="Rechercher un utilisateur..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
className="mb-2 bg-white text-gray-900 border-gray-300"
|
||||
/>
|
||||
<div className="space-y-2 max-h-[250px] overflow-y-auto">
|
||||
{availableUsers
|
||||
.filter(user =>
|
||||
!groupMembers.some(member => member.id === user.id) &&
|
||||
(user.username.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
user.email.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
user.firstName.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||
user.lastName.toLowerCase().includes(searchTerm.toLowerCase()))
|
||||
)
|
||||
.map((user) => (
|
||||
<div key={user.id} className="flex items-center justify-between p-2 bg-gray-50 rounded-md border border-gray-200">
|
||||
<div className="text-gray-900">
|
||||
<div className="font-medium">{user.username}</div>
|
||||
<div className="text-sm text-gray-600">{user.firstName} {user.lastName} ({user.email})</div>
|
||||
</div>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => handleAddMember(user.id)}
|
||||
className="text-green-600 hover:bg-green-50 hover:text-green-700 border-green-200"
|
||||
>
|
||||
<Plus className="h-4 w-4" />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user