update api users and groups and users 15
This commit is contained in:
parent
d1780b748b
commit
a7c9651690
@ -75,11 +75,11 @@ export async function GET() {
|
||||
|
||||
console.log("Filtered users count:", filteredUsers.length);
|
||||
|
||||
// Fetch groups for each user
|
||||
const usersWithGroups = await Promise.all(filteredUsers.map(async (user: any) => {
|
||||
// Fetch roles for each user
|
||||
const usersWithRoles = await Promise.all(filteredUsers.map(async (user: any) => {
|
||||
try {
|
||||
const groupsResponse = await fetch(
|
||||
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${user.id}/groups`,
|
||||
const rolesResponse = await fetch(
|
||||
`${process.env.KEYCLOAK_BASE_URL}/admin/realms/${process.env.KEYCLOAK_REALM}/users/${user.id}/role-mappings/realm`,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${tokenData.access_token}`,
|
||||
@ -88,11 +88,16 @@ export async function GET() {
|
||||
}
|
||||
);
|
||||
|
||||
let groups = [];
|
||||
if (groupsResponse.ok) {
|
||||
const groupsData = await groupsResponse.json();
|
||||
groups = groupsData.map((group: any) => group.name);
|
||||
console.log(`Groups for user ${user.username}:`, groups);
|
||||
let roles = [];
|
||||
if (rolesResponse.ok) {
|
||||
const rolesData = await rolesResponse.json();
|
||||
roles = rolesData
|
||||
.filter((role: any) =>
|
||||
!role.name.startsWith('default-roles-') &&
|
||||
!['offline_access', 'uma_authorization'].includes(role.name)
|
||||
)
|
||||
.map((role: any) => role.name);
|
||||
console.log(`Roles for user ${user.username}:`, roles);
|
||||
}
|
||||
|
||||
return {
|
||||
@ -102,10 +107,11 @@ export async function GET() {
|
||||
lastName: user.lastName || '',
|
||||
email: user.email,
|
||||
createdTimestamp: user.createdTimestamp,
|
||||
roles: groups,
|
||||
enabled: user.enabled,
|
||||
roles: roles,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error(`Error fetching groups for user ${user.id}:`, error);
|
||||
console.error(`Error fetching roles for user ${user.id}:`, error);
|
||||
return {
|
||||
id: user.id,
|
||||
username: user.username,
|
||||
@ -113,17 +119,18 @@ export async function GET() {
|
||||
lastName: user.lastName || '',
|
||||
email: user.email,
|
||||
createdTimestamp: user.createdTimestamp,
|
||||
enabled: user.enabled,
|
||||
roles: [],
|
||||
};
|
||||
}
|
||||
}));
|
||||
|
||||
console.log("Final users data:", usersWithGroups.map(u => ({
|
||||
console.log("Final users data:", usersWithRoles.map(u => ({
|
||||
username: u.username,
|
||||
roles: u.roles,
|
||||
})));
|
||||
|
||||
return NextResponse.json(usersWithGroups);
|
||||
return NextResponse.json(usersWithRoles);
|
||||
|
||||
} catch (error) {
|
||||
console.error("Error:", error);
|
||||
|
||||
@ -41,6 +41,8 @@ interface User {
|
||||
id: string;
|
||||
username: string;
|
||||
email: string;
|
||||
lastName: string;
|
||||
firstName: string;
|
||||
}
|
||||
|
||||
interface ApiError {
|
||||
@ -249,22 +251,32 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
|
||||
body: JSON.stringify({ userId }),
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error("Failed to add member");
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to add member");
|
||||
}
|
||||
|
||||
const user = availableUsers.find(u => u.id === userId);
|
||||
if (user) {
|
||||
setGroupMembers(prev => [...prev, user]);
|
||||
// Update the members list
|
||||
const updatedMember = availableUsers.find(u => u.id === userId);
|
||||
if (updatedMember) {
|
||||
setGroupMembers(prev => [...prev, updatedMember]);
|
||||
setAvailableUsers(prev => prev.filter(u => u.id !== userId));
|
||||
}
|
||||
|
||||
// Update the group's member count in the table
|
||||
setGroups(prev => prev.map(group =>
|
||||
group.id === selectedGroup.id
|
||||
? { ...group, membersCount: group.membersCount + 1 }
|
||||
: group
|
||||
));
|
||||
|
||||
toast({
|
||||
title: "Succès",
|
||||
description: "Membre ajouté avec succès",
|
||||
title: "Success",
|
||||
description: "Member added successfully",
|
||||
});
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: "Erreur",
|
||||
description: "Erreur lors de l'ajout du membre",
|
||||
title: "Error",
|
||||
description: error instanceof Error ? error.message : "An error occurred",
|
||||
variant: "destructive",
|
||||
});
|
||||
}
|
||||
@ -278,22 +290,32 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
|
||||
method: "DELETE",
|
||||
});
|
||||
|
||||
if (!response.ok) throw new Error("Failed to remove member");
|
||||
|
||||
const user = groupMembers.find(u => u.id === userId);
|
||||
if (user) {
|
||||
setAvailableUsers(prev => [...prev, user]);
|
||||
setGroupMembers(prev => prev.filter(u => u.id !== userId));
|
||||
if (!response.ok) {
|
||||
throw new Error("Failed to remove member");
|
||||
}
|
||||
|
||||
// Update the members list
|
||||
const removedMember = groupMembers.find(u => u.id === userId);
|
||||
if (removedMember) {
|
||||
setGroupMembers(prev => prev.filter(u => u.id !== userId));
|
||||
setAvailableUsers(prev => [...prev, removedMember]);
|
||||
}
|
||||
|
||||
// Update the group's member count in the table
|
||||
setGroups(prev => prev.map(group =>
|
||||
group.id === selectedGroup.id
|
||||
? { ...group, membersCount: Math.max(0, group.membersCount - 1) }
|
||||
: group
|
||||
));
|
||||
|
||||
toast({
|
||||
title: "Succès",
|
||||
description: "Membre retiré avec succès",
|
||||
title: "Success",
|
||||
description: "Member removed successfully",
|
||||
});
|
||||
} catch (error) {
|
||||
toast({
|
||||
title: "Erreur",
|
||||
description: "Erreur lors du retrait du membre",
|
||||
title: "Error",
|
||||
description: error instanceof Error ? error.message : "An error occurred",
|
||||
variant: "destructive",
|
||||
});
|
||||
}
|
||||
@ -439,16 +461,16 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>Membres actuels</Label>
|
||||
<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">Aucun membre</p>
|
||||
<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.username}</p>
|
||||
<p className="font-medium">{member.lastName} {member.firstName}</p>
|
||||
<p className="text-sm text-muted-foreground">{member.email}</p>
|
||||
</div>
|
||||
<Button
|
||||
@ -465,16 +487,18 @@ export function GroupsTable({ userRole = [] }: GroupsTableProps) {
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label>Ajouter un membre</Label>
|
||||
<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">Aucun utilisateur disponible</p>
|
||||
<p className="text-sm text-muted-foreground">No users available</p>
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
{availableUsers.map((user) => (
|
||||
{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.username}</p>
|
||||
<p className="font-medium">{user.lastName} {user.firstName}</p>
|
||||
<p className="text-sm text-muted-foreground">{user.email}</p>
|
||||
</div>
|
||||
<Button
|
||||
|
||||
@ -507,12 +507,12 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead>Nom d'utilisateur</TableHead>
|
||||
<TableHead>Prénom</TableHead>
|
||||
<TableHead>Nom</TableHead>
|
||||
<TableHead>Username</TableHead>
|
||||
<TableHead>First Name</TableHead>
|
||||
<TableHead>Last Name</TableHead>
|
||||
<TableHead>Email</TableHead>
|
||||
<TableHead>Date d'inscription</TableHead>
|
||||
<TableHead>Rôles</TableHead>
|
||||
<TableHead>Created At</TableHead>
|
||||
<TableHead>Roles</TableHead>
|
||||
<TableHead className="text-right">Actions</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
@ -526,7 +526,15 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
||||
<TableCell>
|
||||
{new Date(user.createdTimestamp).toLocaleDateString()}
|
||||
</TableCell>
|
||||
<TableCell>{(user.roles || []).join(", ") || "-"}</TableCell>
|
||||
<TableCell>
|
||||
<div className="flex flex-wrap gap-1">
|
||||
{(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">
|
||||
{role}
|
||||
</span>
|
||||
))}
|
||||
</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-right">
|
||||
<DropdownMenu>
|
||||
<DropdownMenuTrigger asChild>
|
||||
@ -695,34 +703,32 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
||||
}}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Gérer les rôles de {selectedUser?.username}</DialogTitle>
|
||||
<DialogTitle>Manage roles for {selectedUser?.username}</DialogTitle>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label>Rôles</Label>
|
||||
<div className="grid grid-cols-2 gap-2">
|
||||
<Label>Available Roles</Label>
|
||||
<div className="grid grid-cols-2 gap-2 max-h-[200px] overflow-y-auto border rounded-md p-2">
|
||||
{roles.map((role) => (
|
||||
<div key={role.id} className="flex items-center space-x-2 p-2 rounded-md hover:bg-gray-100">
|
||||
<input
|
||||
type="checkbox"
|
||||
<Checkbox
|
||||
id={`manage-role-${role.id}`}
|
||||
checked={formData.roles.includes(role.name)}
|
||||
onChange={(e) => {
|
||||
onCheckedChange={(checked) => {
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
roles: e.target.checked
|
||||
roles: checked
|
||||
? [...prev.roles, role.name]
|
||||
: prev.roles.filter(r => r !== role.name)
|
||||
}));
|
||||
}}
|
||||
className="h-4 w-4 text-primary focus:ring-primary"
|
||||
/>
|
||||
<label
|
||||
<Label
|
||||
htmlFor={`manage-role-${role.id}`}
|
||||
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
className="text-sm"
|
||||
>
|
||||
{role.name}
|
||||
</label>
|
||||
</Label>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
@ -736,10 +742,10 @@ export function UsersTable({ userRole = [] }: UsersTableProps) {
|
||||
setFormData(prev => ({ ...prev, roles: [] }));
|
||||
}}
|
||||
>
|
||||
Annuler
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleUpdateRoles}>
|
||||
Mettre à jour les rôles
|
||||
Update Roles
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user