/** * Component: Admin Users Management Page * Documentation: documentation/admin-dashboard.md */ 'use client'; import { useState, useEffect } from 'react'; import useSWR from 'swr'; import Link from 'next/link'; import { authenticatedFetcher, fetchJSON } from '@/lib/utils/api'; import { ToastProvider, useToast } from '@/components/ui/Toast'; import { ConfirmModal } from '@/components/ui/ConfirmModal'; import { GlobalUserSettingsModal } from '@/components/admin/users/GlobalUserSettingsModal'; import { UserPermissionsModal } from '@/components/admin/users/UserPermissionsModal'; interface User { id: string; plexId: string; plexUsername: string; plexEmail: string; role: 'user' | 'admin'; isSetupAdmin: boolean; authProvider: string | null; avatarUrl: string | null; createdAt: string; updatedAt: string; lastLoginAt: string | null; autoApproveRequests: boolean | null; interactiveSearchAccess: boolean | null; downloadAccess: boolean | null; hasLoginToken: boolean; _count: { requests: number; }; } interface PendingUser { id: string; plexUsername: string; plexEmail: string | null; authProvider: string; createdAt: string; } // Tinted-dot status badge following admin design system function RoleBadge({ role, isSetupAdmin }: { role: 'user' | 'admin'; isSetupAdmin: boolean }) { if (isSetupAdmin) { return ( Setup Admin ); } if (role === 'admin') { return ( Admin ); } return ( User ); } function PermissionBadge({ user, globalAutoApprove, onClick, }: { user: User; globalAutoApprove: boolean; onClick: () => void; }) { let badge: React.ReactNode; if (user.role === 'admin') { badge = ( Full Access ); } else if (globalAutoApprove) { badge = ( Global Default ); } else if (user.autoApproveRequests ?? false) { badge = ( Auto-Approve ); } else { badge = ( Manual ); } return ( ); } function UserActionsCell({ user, onEdit, onDelete }: { user: User; onEdit: (u: User) => void; onDelete: (u: User) => void }) { if (user.isSetupAdmin) { return ( Protected ); } if (user.authProvider === 'oidc') { return ( OIDC Managed ); } if (user.authProvider === 'local') { return (
{error?.message || 'Failed to load users'}
Manage user roles and permissions
The following users are awaiting approval to access the system.
No users found
| User | Role | Permissions | Requests | Last Login | Actions | |
|---|---|---|---|---|---|---|
|
{user.avatarUrl ? (
{user.plexUsername}
copyToClipboard(user.plexId, 'User ID')}
>
ID: {user.plexId.length > 12 ? `${user.plexId.substring(0, 12)}...` : user.plexId}
|
{user.plexEmail || 'N/A'}
|
|
|
{user._count.requests} | {user.lastLoginAt ? new Date(user.lastLoginAt).toLocaleDateString() : 'Never'} |
|
No users found