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