Add admin UX improvements, constants refactor, and comprehensive tests

- Introduced constants for admin hooks: `STATS_FETCH_LIMIT`, `DEFAULT_PAGE_LIMIT`, and `STATS_REFETCH_INTERVAL` to enhance readability and maintainability.
- Updated query guards to ensure data fetching is restricted to superusers.
- Enhanced accessibility across admin components by adding `aria-hidden` attributes and improving focus-visible styles.
- Simplified `useAdminStats`, `useAdminUsers`, and `useAdminOrganizations` with shared constants.
- Added 403 Forbidden page with proper structure, styling, and tests.
- Implemented new tests for admin hooks, DashboardStats, AdminLayout, and ForbiddenPage for better coverage.
This commit is contained in:
Felipe Cardoso
2025-11-06 10:08:43 +01:00
parent abce06ad67
commit 9c72fe87f9
14 changed files with 852 additions and 40 deletions

View File

@@ -69,14 +69,14 @@ export function AdminSidebar() {
)}
<button
onClick={() => setCollapsed(!collapsed)}
className="rounded-md p-2 hover:bg-accent"
className="rounded-md p-2 hover:bg-accent focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2"
aria-label={collapsed ? 'Expand sidebar' : 'Collapse sidebar'}
data-testid="sidebar-toggle"
>
{collapsed ? (
<ChevronRight className="h-4 w-4" />
<ChevronRight className="h-4 w-4" aria-hidden="true" />
) : (
<ChevronLeft className="h-4 w-4" />
<ChevronLeft className="h-4 w-4" aria-hidden="true" />
)}
</button>
</div>
@@ -96,6 +96,7 @@ export function AdminSidebar() {
className={cn(
'flex items-center gap-3 rounded-md px-3 py-2 text-sm font-medium transition-colors',
'hover:bg-accent hover:text-accent-foreground',
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
isActive
? 'bg-accent text-accent-foreground'
: 'text-muted-foreground',
@@ -104,7 +105,7 @@ export function AdminSidebar() {
title={collapsed ? item.name : undefined}
data-testid={`nav-${item.name.toLowerCase()}`}
>
<Icon className="h-5 w-5 flex-shrink-0" />
<Icon className="h-5 w-5 flex-shrink-0" aria-hidden="true" />
{!collapsed && <span>{item.name}</span>}
</Link>
);

View File

@@ -17,7 +17,7 @@ export function DashboardStats() {
if (isError) {
return (
<Alert variant="destructive">
<AlertCircle className="h-4 w-4" />
<AlertCircle className="h-4 w-4" aria-hidden="true" />
<AlertDescription>
Failed to load dashboard statistics: {error?.message || 'Unknown error'}
</AlertDescription>

View File

@@ -90,6 +90,7 @@ export function StatCard({
'h-6 w-6',
loading ? 'text-muted-foreground' : 'text-primary'
)}
aria-hidden="true"
/>
</div>
</div>