feat(users): enhance table responsiveness and replace action buttons with dropdown menu

- Improved table layout by hiding specific columns on smaller screens.
- Replaced action buttons with `DropdownMenu` for a cleaner and more accessible UI.
- Updated skeleton loaders to align with the revised table structure.
This commit is contained in:
Mathis HERRIOT
2026-01-21 15:43:19 +01:00
parent c3f57db1e5
commit 029bbe9bb9

View File

@@ -2,10 +2,18 @@
import { format } from "date-fns"; import { format } from "date-fns";
import { fr } from "date-fns/locale"; import { fr } from "date-fns/locale";
import { Edit, Trash2 } from "lucide-react"; import { Edit, MoreHorizontal, Trash2 } from "lucide-react";
import { useCallback, useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { Badge } from "@/components/ui/badge"; import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu";
import { Skeleton } from "@/components/ui/skeleton"; import { Skeleton } from "@/components/ui/skeleton";
import { import {
Table, Table,
@@ -77,10 +85,12 @@ export default function AdminUsersPage() {
<TableHeader> <TableHeader>
<TableRow> <TableRow>
<TableHead>Utilisateur</TableHead> <TableHead>Utilisateur</TableHead>
<TableHead>Email</TableHead> <TableHead className="hidden md:table-cell">Email</TableHead>
<TableHead>Rôle</TableHead> <TableHead>Rôle</TableHead>
<TableHead>Status</TableHead> <TableHead className="hidden sm:table-cell">Status</TableHead>
<TableHead>Date d'inscription</TableHead> <TableHead className="hidden lg:table-cell">
Date d'inscription
</TableHead>
<TableHead className="w-[100px]"></TableHead> <TableHead className="w-[100px]"></TableHead>
</TableRow> </TableRow>
</TableHeader> </TableHeader>
@@ -92,16 +102,16 @@ export default function AdminUsersPage() {
<TableCell> <TableCell>
<Skeleton className="h-4 w-[150px]" /> <Skeleton className="h-4 w-[150px]" />
</TableCell> </TableCell>
<TableCell> <TableCell className="hidden md:table-cell">
<Skeleton className="h-4 w-[200px]" /> <Skeleton className="h-4 w-[200px]" />
</TableCell> </TableCell>
<TableCell> <TableCell>
<Skeleton className="h-4 w-[50px]" /> <Skeleton className="h-4 w-[50px]" />
</TableCell> </TableCell>
<TableCell> <TableCell className="hidden sm:table-cell">
<Skeleton className="h-4 w-[80px]" /> <Skeleton className="h-4 w-[80px]" />
</TableCell> </TableCell>
<TableCell> <TableCell className="hidden lg:table-cell">
<Skeleton className="h-4 w-[100px]" /> <Skeleton className="h-4 w-[100px]" />
</TableCell> </TableCell>
<TableCell> <TableCell>
@@ -122,13 +132,13 @@ export default function AdminUsersPage() {
{user.displayName || user.username} {user.displayName || user.username}
<div className="text-xs text-muted-foreground">@{user.username}</div> <div className="text-xs text-muted-foreground">@{user.username}</div>
</TableCell> </TableCell>
<TableCell>{user.email}</TableCell> <TableCell className="hidden md:table-cell">{user.email}</TableCell>
<TableCell> <TableCell>
<Badge variant={user.role === "admin" ? "default" : "secondary"}> <Badge variant={user.role === "admin" ? "default" : "secondary"}>
{user.role} {user.role}
</Badge> </Badge>
</TableCell> </TableCell>
<TableCell> <TableCell className="hidden sm:table-cell">
<Badge <Badge
variant={ variant={
user.status === "active" user.status === "active"
@@ -141,23 +151,31 @@ export default function AdminUsersPage() {
{user.status} {user.status}
</Badge> </Badge>
</TableCell> </TableCell>
<TableCell className="whitespace-nowrap"> <TableCell className="hidden lg:table-cell whitespace-nowrap">
{format(new Date(user.createdAt), "PPP", { locale: fr })} {format(new Date(user.createdAt), "PPP", { locale: fr })}
</TableCell> </TableCell>
<TableCell> <TableCell>
<div className="flex items-center gap-2"> <DropdownMenu>
<Button variant="ghost" size="icon" onClick={() => handleEdit(user)}> <DropdownMenuTrigger asChild>
<Edit className="h-4 w-4" /> <Button variant="ghost" size="icon">
</Button> <MoreHorizontal className="h-4 w-4" />
<Button <span className="sr-only">Actions</span>
variant="ghost" </Button>
size="icon" </DropdownMenuTrigger>
onClick={() => handleDelete(user.uuid)} <DropdownMenuContent align="end">
className="text-destructive hover:text-destructive hover:bg-destructive/10" <DropdownMenuLabel>Actions</DropdownMenuLabel>
> <DropdownMenuSeparator />
<Trash2 className="h-4 w-4" /> <DropdownMenuItem onClick={() => handleEdit(user)}>
</Button> <Edit className="mr-2 h-4 w-4" /> Modifier
</div> </DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleDelete(user.uuid)}
className="text-destructive focus:text-destructive"
>
<Trash2 className="mr-2 h-4 w-4" /> Supprimer
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</TableCell> </TableCell>
</TableRow> </TableRow>
)) ))