Skip to main content

useAdminUsers

Location: src/hooks/useAdminUsers.js

Overview

Provides three hooks for admin user management: useAdminUsers for searching users, useUserDetail for viewing a user's full profile with actions/reports/posts, and useUserActions for issuing warnings, suspensions, bans, and revoking previous actions.

These hooks are intended for use in admin panel components only.

Exported Hooks

useAdminUsers

Searches users via the admin_search_users RPC function.

function useAdminUsers(): {
users: User[],
isLoading: boolean,
error: string | null,
searchUsers: (term: string, statusFilter?: string | null) => Promise<void>,
clearSearch: () => void
}
PropertyTypeDescription
usersUser[]Array of matching user objects
isLoadingbooleanWhether a search is in progress
errorstring | nullError message if search failed
searchUsers(term, statusFilter?) => Promise<void>Search users by term (min 2 chars). Optional status filter. Returns up to 50 results.
clearSearch() => voidClear search results and errors

useUserDetail

Fetches detailed information about a specific user.

function useUserDetail(userId: string): {
user: object | null,
actions: Action[],
reports: Report[],
posts: Post[],
isLoading: boolean,
error: string | null,
refetch: () => void
}
ParameterTypeRequiredDescription
userIdstringYesThe target user's ID
PropertyTypeDescription
userobject | nullUser profile data from admin_view_user RPC
actionsAction[]Admin actions (warnings, suspensions, bans) with admin info. Up to 20 most recent.
reportsReport[]Reports filed against this user with reporter info. Up to 10 most recent.
postsPost[]The user's recent posts (id, content, intent, created_at, is_hidden). Up to 10.
isLoadingbooleanWhether data is being fetched
errorstring | nullError message if fetch failed
refetch() => voidRe-fetch all user detail data

useUserActions

Provides admin moderation actions.

function useUserActions(): {
isSubmitting: boolean,
error: string | null,
warnUser: (userId: string, reason: string, notes?: string | null) => Promise<Result>,
suspendUser: (userId: string, reason: string, duration: number, notes?: string | null) => Promise<Result>,
banUser: (userId: string, reason: string, notes?: string | null) => Promise<Result>,
revokeAction: (actionId: string, reason: string) => Promise<Result>,
clearError: () => void
}
PropertyTypeDescription
isSubmittingbooleanWhether an action is being submitted
errorstring | nullError message if action failed
warnUser(userId, reason, notes?) => Promise<Result>Issue a warning via admin_warn_user RPC
suspendUser(userId, reason, duration, notes?) => Promise<Result>Suspend for duration days via admin_suspend_user RPC
banUser(userId, reason, notes?) => Promise<Result>Permanently ban via admin_ban_user RPC
revokeAction(actionId, reason) => Promise<Result>Revoke a previous action via admin_revoke_action RPC
clearError() => voidClear the error state

Usage

import { useAdminUsers, useUserDetail, useUserActions } from '../hooks/useAdminUsers';

function AdminUserSearch() {
const { users, isLoading, searchUsers, clearSearch } = useAdminUsers();

return (
<div>
<input onChange={(e) => searchUsers(e.target.value)} />
{users.map(u => <UserRow key={u.id} user={u} />)}
</div>
);
}

function AdminUserPanel({ userId }) {
const { user, actions, reports, posts, isLoading } = useUserDetail(userId);
const { warnUser, suspendUser, banUser } = useUserActions();

if (isLoading) return <Skeleton />;

return (
<div>
<h2>{user?.display_name}</h2>
<button onClick={() => warnUser(userId, 'Policy violation')}>Warn</button>
<button onClick={() => suspendUser(userId, 'Repeated violations', 7)}>Suspend 7 days</button>
</div>
);
}

Notes

  • All admin RPC functions require admin role authorization on the server side.
  • useUserDetail does not auto-fetch on mount. You must call refetch() to load data, or pass the userId and trigger loading from your component.
  • warnUser, suspendUser, banUser, and revokeAction all return { success: true } or { success: false, error: string }.
  • The notes parameter on moderation actions is for internal admin notes, not visible to the user.

Last updated: 2026-02-07