Skip to main content

useAdminItems

Overview

useAdminItems is a comprehensive React hook for managing items in the admin panel. It provides full CRUD operations, item review workflows (approve/reject), bulk actions, paginated listing with filtering and sorting, and real-time statistics. Built on top of TanStack React Query and the internal serverClient API layer.

Source: template/hooks/use-admin-items.ts

Signature / Parameters

function useAdminItems(params?: ItemsListParams): UseAdminItemsReturn

ItemsListParams

ParameterTypeDefaultDescription
pagenumberundefinedCurrent page number for pagination
limitnumberundefinedNumber of items per page
statusstringundefinedFilter by item status
categoriesstring[]undefinedFilter by category IDs
tagsstring[]undefinedFilter by tag IDs
searchstringundefinedSearch term for text matching
sortBy'name' | 'updated_at' | 'status' | 'submitted_at'undefinedField to sort results by
sortOrder'asc' | 'desc'undefinedSort direction

Return Values

The hook returns an object with the following shape:

Data

PropertyTypeDescription
itemsItemData[]Array of items for the current page
totalnumberTotal number of items matching current filters
pagenumberCurrent page number (defaults to 1)
totalPagesnumberTotal number of pages (defaults to 1)
statsItemStatsResponseAggregate counts by status

ItemStatsResponse

interface ItemStatsResponse {
total: number;
draft: number;
pending: number;
approved: number;
rejected: number;
}

Loading States

PropertyTypeDescription
isLoadingbooleantrue only on initial load (no cached data)
isFetchingbooleantrue when fetching, including background refetch
isStatsLoadingbooleantrue while stats are being fetched
isSubmittingbooleantrue when any mutation is pending
isApprovingbooleantrue when a review-approve mutation is in flight
isRejectingbooleantrue when a review-reject mutation is in flight
isDeletingbooleantrue when a delete mutation is in flight
pendingItemIdstring | nullID of the item currently being mutated
isBulkProcessingbooleantrue when a bulk action is in progress
bulkActionType'approve' | 'reject' | 'delete' | nullType of bulk action currently processing

Actions

MethodSignatureDescription
createItem(data: CreateItemRequest) => Promise<boolean>Create a new item. Returns true on success.
updateItem(id: string, data: UpdateItemRequest) => Promise<boolean>Update an existing item by ID.
deleteItem(id: string) => Promise<boolean>Delete an item by ID.
reviewItem(id: string, status: 'approved' | 'rejected', notes?: string) => Promise<boolean>Approve or reject an item with optional notes.

Bulk Actions

MethodSignatureDescription
bulkApprove(ids: string[]) => Promise<BulkActionResponse | null>Approve multiple items at once.
bulkReject(ids: string[], reason: string) => Promise<BulkActionResponse | null>Reject multiple items with a reason.
bulkDelete(ids: string[]) => Promise<BulkActionResponse | null>Delete multiple items at once.

BulkActionResponse

interface BulkActionResponse {
success: boolean;
message: string;
results: { id: string; success: boolean; error?: string }[];
summary: { total: number; successful: number; failed: number };
}

Utility

MethodSignatureDescription
refetch() => voidRe-execute the items list query
refreshData() => voidClear server cache and refetch both items and stats

Implementation Details

  • Query caching: Uses TanStack React Query with a 5-minute staleTime and 10-minute gcTime. Background refetch interval is set to 5 minutes.
  • Placeholder data: Uses keepPreviousData so that paginated transitions do not flash empty states.
  • Stats filtering: The stats query receives the same search, categories, and tags filters as the items list, so status counters update in sync with the active filter set.
  • Toast notifications: All mutation success and error states trigger sonner toast notifications automatically.
  • Cache invalidation: After every successful mutation, refreshData is called, which clears the serverClient cache and refetches both items and stats queries.
  • Error handling: All action handlers return boolean -- true on success, false on failure. Errors are caught internally and surfaced via toast.
  • Bulk action feedback: Bulk handlers provide granular feedback: full success shows a success toast, partial success shows a warning, and complete failure shows an error toast.

Query Keys

const QUERY_KEYS = {
items: ['admin', 'items'],
itemsList: (params) => ['admin', 'items', 'list', params],
itemStats: (params) => ['admin', 'items', 'stats', params],
};

Usage Examples

Basic item listing with pagination

import { useAdminItems } from '@/hooks/use-admin-items';

function ItemsPage() {
const [page, setPage] = useState(1);

const {
items,
total,
totalPages,
isLoading,
stats,
} = useAdminItems({ page, limit: 20 });

if (isLoading) return <Spinner />;

return (
<div>
<StatsBar stats={stats} />
<ItemsTable items={items} />
<Pagination
current={page}
total={totalPages}
onChange={setPage}
/>
</div>
);
}

Filtering and searching

const { items, isLoading } = useAdminItems({
page: 1,
limit: 10,
status: 'pending',
search: 'react',
categories: ['cat-1', 'cat-2'],
sortBy: 'submitted_at',
sortOrder: 'desc',
});

Reviewing an item

const { reviewItem, isApproving, isRejecting, pendingItemId } = useAdminItems();

const handleApprove = async (itemId: string) => {
const success = await reviewItem(itemId, 'approved', 'Looks great!');
if (success) {
// Item was approved, data auto-refreshes
}
};

const handleReject = async (itemId: string) => {
const success = await reviewItem(itemId, 'rejected', 'Does not meet guidelines');
};

Bulk operations

const { bulkApprove, bulkDelete, isBulkProcessing, bulkActionType } = useAdminItems();

const handleBulkApprove = async (selectedIds: string[]) => {
const result = await bulkApprove(selectedIds);
if (result) {
console.log(`${result.summary.successful} of ${result.summary.total} approved`);
}
};