useAuditLog
Location: src/hooks/useAuditLog.js
Overview
Provides a full-featured interface for viewing admin audit logs. Supports filtering by admin, action type, action category, target, date range, and free-text search. Includes pagination and CSV export. This is an admin-only hook used in the admin panel.
The file also exports several constants and utilities:
ACTION_CATEGORIES-- groups of action types organized by category (user, content, report, admin, system)ACTION_LABELS-- human-readable labels for each action typegetActionSeverity-- returns a severity level ("danger","warning","success","default") for color-coding actions
Exported Constants
ACTION_CATEGORIES
const ACTION_CATEGORIES: Record<string, {
label: string,
actions: string[]
}>
Categories: user (User Management), content (Content Moderation), report (Reports), admin (Admin Management), system (System).
ACTION_LABELS
const ACTION_LABELS: Record<string, string>
Maps action type keys to display labels (e.g. user_ban -> "Banned User", report_resolve -> "Resolved Report").
getActionSeverity
function getActionSeverity(actionType: string): "danger" | "warning" | "success" | "default"
Returns a severity classification for styling purposes.
Signature
function useAuditLog(): {
logs: AuditLogRow[],
admins: AdminProfile[],
isLoading: boolean,
error: string | null,
hasMore: boolean,
totalCount: number,
fetchLogs: (filters?: FilterOptions) => Promise<void>,
fetchAdmins: () => Promise<void>,
loadMore: (filters: FilterOptions, currentOffset: number) => Promise<void>,
exportCSV: (filters: FilterOptions) => Promise<{ success: boolean, error?: string }>
}
Parameters
None.
Return Value
| Property | Type | Description |
|---|---|---|
logs | AuditLogRow[] | Array of audit log entries, each with joined admin profile data. Ordered newest first. |
admins | AdminProfile[] | List of all admin users for filter dropdowns. Populated by calling fetchAdmins. |
isLoading | boolean | true while a fetch is in progress. |
error | string | null | Error message from the most recent failed operation. |
hasMore | boolean | true if more pages of logs are available. |
totalCount | number | Total number of matching log entries (from Supabase count). |
fetchLogs | (filters?) => Promise<void> | Fetch logs with optional filters (see below). Replaces the current list unless append: true is set. |
fetchAdmins | () => Promise<void> | Fetch the list of admin users for the filter dropdown. |
loadMore | (filters, currentOffset) => Promise<void> | Load the next page of logs, appending to the existing list. |
exportCSV | (filters) => Promise | Export matching logs as a CSV file (up to 1000 rows). Triggers a browser download. Returns { success } or { success: false, error }. |
FilterOptions
interface FilterOptions {
adminId?: string | null,
actionType?: string | null,
actionCategory?: string | null,
targetType?: string | null,
targetId?: string | null,
dateRange?: "24h" | "7d" | "30d" | "all",
searchTerm?: string | null,
limit?: number, // default 50
offset?: number, // default 0
append?: boolean // default false
}
Usage
function AuditLogViewer() {
const { logs, isLoading, fetchLogs, fetchAdmins, hasMore, loadMore, exportCSV } = useAuditLog();
const [filters, setFilters] = useState({ dateRange: '7d' });
useEffect(() => {
fetchAdmins();
fetchLogs(filters);
}, []);
const handleFilterChange = (newFilters) => {
setFilters(newFilters);
fetchLogs(newFilters);
};
return (
<div>
<button onClick={() => exportCSV(filters)}>Export CSV</button>
{logs.map(log => (
<div key={log.id}>
<span>{ACTION_LABELS[log.action_type]}</span>
<span className={getActionSeverity(log.action_type)}>
{log.admin?.display_name}
</span>
<span>{new Date(log.created_at).toLocaleString()}</span>
</div>
))}
{hasMore && (
<button onClick={() => loadMore(filters, logs.length)}>
Load More
</button>
)}
</div>
);
}
Last updated: 2026-02-07