dolibarr user
This commit is contained in:
parent
e9f246deb1
commit
be309e0c68
@ -407,78 +407,85 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
if (loading) return <div className="text-center p-4">Loading...</div>;
|
if (loading) return <div className="text-center p-4">Loading...</div>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-4">
|
<div className="space-y-4 p-6 bg-gray-100 rounded-lg">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<Input
|
<Input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="Rechercher un utilisateur..."
|
placeholder="Rechercher un utilisateur..."
|
||||||
value={searchTerm}
|
value={searchTerm}
|
||||||
onChange={(e) => setSearchTerm(e.target.value)}
|
onChange={(e) => setSearchTerm(e.target.value)}
|
||||||
className="max-w-sm"
|
className="max-w-sm bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
<Dialog open={newUserDialog} onOpenChange={setNewUserDialog}>
|
<Dialog open={newUserDialog} onOpenChange={setNewUserDialog}>
|
||||||
<DialogTrigger asChild>
|
<DialogTrigger asChild>
|
||||||
<Button>Ajouter un utilisateur</Button>
|
<Button className="bg-blue-600 hover:bg-blue-700 text-white">
|
||||||
|
Ajouter un utilisateur
|
||||||
|
</Button>
|
||||||
</DialogTrigger>
|
</DialogTrigger>
|
||||||
<DialogContent className="max-h-[85vh] overflow-y-auto">
|
<DialogContent className="max-h-[85vh] overflow-y-auto bg-white text-black border border-gray-300">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>New User</DialogTitle>
|
<DialogTitle className="text-gray-900">Nouvel Utilisateur</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<form onSubmit={handleAddUser} className="space-y-3">
|
<form onSubmit={handleAddUser} className="space-y-3">
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="username">Username</Label>
|
<Label htmlFor="username" className="text-gray-900">Nom d'utilisateur</Label>
|
||||||
<Input
|
<Input
|
||||||
id="username"
|
id="username"
|
||||||
value={formData.username}
|
value={formData.username}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, username: e.target.value.trim() }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, username: e.target.value.trim() }))}
|
||||||
required
|
required
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="email">Email</Label>
|
<Label htmlFor="email" className="text-gray-900">Email</Label>
|
||||||
<Input
|
<Input
|
||||||
id="email"
|
id="email"
|
||||||
type="email"
|
type="email"
|
||||||
value={formData.email}
|
value={formData.email}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value.trim() }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value.trim() }))}
|
||||||
required
|
required
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="firstName">First Name</Label>
|
<Label htmlFor="firstName" className="text-gray-900">Prénom</Label>
|
||||||
<Input
|
<Input
|
||||||
id="firstName"
|
id="firstName"
|
||||||
value={formData.firstName}
|
value={formData.firstName}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value.trim() }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value.trim() }))}
|
||||||
required
|
required
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="lastName">Last Name</Label>
|
<Label htmlFor="lastName" className="text-gray-900">Nom</Label>
|
||||||
<Input
|
<Input
|
||||||
id="lastName"
|
id="lastName"
|
||||||
value={formData.lastName}
|
value={formData.lastName}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value.trim() }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value.trim() }))}
|
||||||
required
|
required
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="password">Password</Label>
|
<Label htmlFor="password" className="text-gray-900">Mot de passe</Label>
|
||||||
<Input
|
<Input
|
||||||
id="password"
|
id="password"
|
||||||
type="password"
|
type="password"
|
||||||
value={formData.password}
|
value={formData.password}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, password: e.target.value }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, password: e.target.value }))}
|
||||||
required
|
required
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Roles</Label>
|
<Label className="text-gray-900">Rôles</Label>
|
||||||
<div className="grid grid-cols-2 gap-2 max-h-[120px] overflow-y-auto border rounded-md p-2">
|
<div className="grid grid-cols-2 gap-2 max-h-[120px] overflow-y-auto border border-gray-300 rounded-md p-2 bg-white">
|
||||||
{roles.map((role) => (
|
{roles.map((role) => (
|
||||||
<div key={role.id} className="flex items-center space-x-2">
|
<div key={role.id} className="flex items-center space-x-2">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@ -492,41 +499,42 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
: prev.roles.filter(r => r !== role.name)
|
: prev.roles.filter(r => r !== role.name)
|
||||||
}));
|
}));
|
||||||
}}
|
}}
|
||||||
|
className="border-gray-500"
|
||||||
/>
|
/>
|
||||||
<Label htmlFor={`role-${role.id}`} className="text-sm">{role.name}</Label>
|
<Label htmlFor={`role-${role.id}`} className="text-sm text-gray-900">{role.name}</Label>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Button type="submit" className="w-full">Create User</Button>
|
<Button type="submit" className="w-full bg-blue-600 hover:bg-blue-700 text-white">Créer Utilisateur</Button>
|
||||||
</form>
|
</form>
|
||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Table>
|
<Table className="bg-white border border-gray-300 rounded-md">
|
||||||
<TableHeader>
|
<TableHeader className="bg-gray-50">
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Username</TableHead>
|
<TableHead className="text-gray-900">Username</TableHead>
|
||||||
<TableHead>First Name</TableHead>
|
<TableHead className="text-gray-900">First Name</TableHead>
|
||||||
<TableHead>Last Name</TableHead>
|
<TableHead className="text-gray-900">Last Name</TableHead>
|
||||||
<TableHead>Email</TableHead>
|
<TableHead className="text-gray-900">Email</TableHead>
|
||||||
<TableHead>Created At</TableHead>
|
<TableHead className="text-gray-900">Created At</TableHead>
|
||||||
<TableHead>Roles</TableHead>
|
<TableHead className="text-gray-900">Roles</TableHead>
|
||||||
<TableHead className="text-right">Actions</TableHead>
|
<TableHead className="text-gray-900 text-right">Actions</TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{paginatedUsers.map((user) => (
|
{paginatedUsers.map((user) => (
|
||||||
<TableRow key={user.id}>
|
<TableRow key={user.id} className="hover:bg-gray-50 border-t border-gray-200">
|
||||||
<TableCell>{user.username}</TableCell>
|
<TableCell className="text-gray-900">{user.username}</TableCell>
|
||||||
<TableCell>{user.firstName || "-"}</TableCell>
|
<TableCell className="text-gray-900">{user.firstName || "-"}</TableCell>
|
||||||
<TableCell>{user.lastName || "-"}</TableCell>
|
<TableCell className="text-gray-900">{user.lastName || "-"}</TableCell>
|
||||||
<TableCell>{user.email || "-"}</TableCell>
|
<TableCell className="text-gray-900">{user.email || "-"}</TableCell>
|
||||||
<TableCell>
|
<TableCell className="text-gray-900">
|
||||||
{new Date(user.createdTimestamp).toLocaleDateString()}
|
{new Date(user.createdTimestamp).toLocaleDateString()}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell>
|
<TableCell className="text-gray-900">
|
||||||
<div className="flex flex-wrap gap-1">
|
<div className="flex flex-wrap gap-1">
|
||||||
{(user.roles || []).map((role) => (
|
{(user.roles || []).map((role) => (
|
||||||
<span key={role} className="inline-flex items-center rounded-full bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">
|
<span key={role} className="inline-flex items-center rounded-full bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10">
|
||||||
@ -535,7 +543,7 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
<TableCell className="text-right">
|
<TableCell className="text-gray-900 text-right">
|
||||||
<DropdownMenu>
|
<DropdownMenu>
|
||||||
<DropdownMenuTrigger asChild>
|
<DropdownMenuTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
@ -550,14 +558,15 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
<MoreHorizontal className="h-4 w-4" />
|
<MoreHorizontal className="h-4 w-4" />
|
||||||
</Button>
|
</Button>
|
||||||
</DropdownMenuTrigger>
|
</DropdownMenuTrigger>
|
||||||
<DropdownMenuContent align="end">
|
<DropdownMenuContent align="end" className="bg-white border border-gray-300">
|
||||||
<DropdownMenuLabel>Actions</DropdownMenuLabel>
|
<DropdownMenuLabel className="text-gray-900">Actions</DropdownMenuLabel>
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleEdit(user.id);
|
handleEdit(user.id);
|
||||||
}}
|
}}
|
||||||
|
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
|
||||||
@ -568,6 +577,7 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleManageRoles(user.id);
|
handleManageRoles(user.id);
|
||||||
}}
|
}}
|
||||||
|
className="text-gray-900 hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
<UserPlus className="mr-2 h-4 w-4" />
|
<UserPlus className="mr-2 h-4 w-4" />
|
||||||
Gérer les rôles
|
Gérer les rôles
|
||||||
@ -578,6 +588,7 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleChangePassword(user.id);
|
handleChangePassword(user.id);
|
||||||
}}
|
}}
|
||||||
|
className="text-gray-900 hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
<Key className="mr-2 h-4 w-4" />
|
<Key className="mr-2 h-4 w-4" />
|
||||||
Changer le mot de passe
|
Changer le mot de passe
|
||||||
@ -588,6 +599,7 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
handleToggleUserStatus(user.id, user.enabled);
|
handleToggleUserStatus(user.id, user.enabled);
|
||||||
}}
|
}}
|
||||||
|
className="text-gray-900 hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
{user.enabled ? (
|
{user.enabled ? (
|
||||||
<>
|
<>
|
||||||
@ -603,7 +615,7 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
</DropdownMenuItem>
|
</DropdownMenuItem>
|
||||||
<DropdownMenuSeparator />
|
<DropdownMenuSeparator />
|
||||||
<DropdownMenuItem
|
<DropdownMenuItem
|
||||||
className="text-red-600"
|
className="text-red-600 hover:bg-red-50 hover:text-red-700"
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@ -636,34 +648,37 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
}
|
}
|
||||||
setEditUserDialog(open);
|
setEditUserDialog(open);
|
||||||
}}>
|
}}>
|
||||||
<DialogContent>
|
<DialogContent className="bg-white text-black border border-gray-300">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Modifier l'utilisateur</DialogTitle>
|
<DialogTitle className="text-gray-900">Modifier l'utilisateur</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<form onSubmit={handleUpdateUser} className="space-y-4">
|
<form onSubmit={handleUpdateUser} className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-firstName">Prénom</Label>
|
<Label htmlFor="edit-firstName" className="text-gray-900">Prénom</Label>
|
||||||
<Input
|
<Input
|
||||||
id="edit-firstName"
|
id="edit-firstName"
|
||||||
value={formData.firstName}
|
value={formData.firstName}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, firstName: e.target.value }))}
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-lastName">Nom</Label>
|
<Label htmlFor="edit-lastName" className="text-gray-900">Nom</Label>
|
||||||
<Input
|
<Input
|
||||||
id="edit-lastName"
|
id="edit-lastName"
|
||||||
value={formData.lastName}
|
value={formData.lastName}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, lastName: e.target.value }))}
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label htmlFor="edit-email">Email</Label>
|
<Label htmlFor="edit-email" className="text-gray-900">Email</Label>
|
||||||
<Input
|
<Input
|
||||||
id="edit-email"
|
id="edit-email"
|
||||||
type="email"
|
type="email"
|
||||||
value={formData.email}
|
value={formData.email}
|
||||||
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
|
onChange={(e) => setFormData(prev => ({ ...prev, email: e.target.value }))}
|
||||||
|
className="bg-white text-gray-900 border-gray-300"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex justify-end space-x-2">
|
<div className="flex justify-end space-x-2">
|
||||||
@ -683,10 +698,11 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
enabled: true,
|
enabled: true,
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
|
className="border-gray-300 text-gray-800 hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
Annuler
|
Annuler
|
||||||
</Button>
|
</Button>
|
||||||
<Button type="submit">
|
<Button type="submit" className="bg-blue-600 hover:bg-blue-700 text-white">
|
||||||
Modifier
|
Modifier
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
@ -701,14 +717,14 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
}
|
}
|
||||||
setManageRolesDialog(open);
|
setManageRolesDialog(open);
|
||||||
}}>
|
}}>
|
||||||
<DialogContent>
|
<DialogContent className="bg-white text-black border border-gray-300">
|
||||||
<DialogHeader>
|
<DialogHeader>
|
||||||
<DialogTitle>Manage roles for {selectedUser?.username}</DialogTitle>
|
<DialogTitle className="text-gray-900">Gérer les rôles pour {selectedUser?.username}</DialogTitle>
|
||||||
</DialogHeader>
|
</DialogHeader>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
<div className="space-y-2">
|
<div className="space-y-2">
|
||||||
<Label>Available Roles</Label>
|
<Label className="text-gray-900">Rôles disponibles</Label>
|
||||||
<div className="grid grid-cols-2 gap-2 max-h-[200px] overflow-y-auto border rounded-md p-2">
|
<div className="grid grid-cols-2 gap-2 max-h-[200px] overflow-y-auto border border-gray-300 rounded-md p-2 bg-white">
|
||||||
{roles.map((role) => (
|
{roles.map((role) => (
|
||||||
<div key={role.id} className="flex items-center space-x-2 p-2 rounded-md hover:bg-gray-100">
|
<div key={role.id} className="flex items-center space-x-2 p-2 rounded-md hover:bg-gray-100">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
@ -722,10 +738,11 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
: prev.roles.filter(r => r !== role.name)
|
: prev.roles.filter(r => r !== role.name)
|
||||||
}));
|
}));
|
||||||
}}
|
}}
|
||||||
|
className="border-gray-500"
|
||||||
/>
|
/>
|
||||||
<Label
|
<Label
|
||||||
htmlFor={`manage-role-${role.id}`}
|
htmlFor={`manage-role-${role.id}`}
|
||||||
className="text-sm"
|
className="text-sm text-gray-900"
|
||||||
>
|
>
|
||||||
{role.name}
|
{role.name}
|
||||||
</Label>
|
</Label>
|
||||||
@ -741,11 +758,12 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
|||||||
setSelectedUser(null);
|
setSelectedUser(null);
|
||||||
setFormData(prev => ({ ...prev, roles: [] }));
|
setFormData(prev => ({ ...prev, roles: [] }));
|
||||||
}}
|
}}
|
||||||
|
className="border-gray-300 text-gray-800 hover:bg-gray-100"
|
||||||
>
|
>
|
||||||
Cancel
|
Annuler
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={handleUpdateRoles}>
|
<Button onClick={handleUpdateRoles} className="bg-blue-600 hover:bg-blue-700 text-white">
|
||||||
Update Roles
|
Mettre à jour les rôles
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user