useAdminComments
Overview
useAdminComments is a React hook for managing user comments in the admin panel. It provides paginated comment listing with search, delete operations with per-item tracking, and automatic cache invalidation. Built on top of TanStack React Query with keepPreviousData for seamless pagination transitions.
Source: template/hooks/use-admin-comments.ts
Signature / Parameters
function useAdminComments(
options?: UseAdminCommentsOptions
): UseAdminCommentsReturn
UseAdminCommentsOptions
| Parameter | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Current page number for pagination |
limit | number | 10 | Number of comments per page |
search | string | undefined | Search term to filter comments |
Return Values
The hook returns an object implementing UseAdminCommentsReturn:
Data
| Property | Type | Description |
|---|---|---|
comments | AdminCommentItem[] | Array of comments for the current page |
AdminCommentItem
interface AdminCommentItem {
id: string;
content: string;
rating: number | null;
userId: string;
itemId: string;
createdAt: string | null;
updatedAt: string | null;
user: AdminCommentUser;
}
interface AdminCommentUser {
id: string;
name: string | null;
email: string | null;
image: string | null;
}
Loading States
| Property | Type | Description |
|---|---|---|
isLoading | boolean | true only on initial load (no cached data) |
isFetching | boolean | true when fetching, including background refetch |
isDeleting | string | null | ID of the comment currently being deleted, or null |
Pagination
| Property | Type | Description |
|---|---|---|
totalPages | number | Total number of pages (defaults to 1) |
totalComments | number | Total number of comments |
Actions
| Method | Signature | Description |
|---|---|---|
deleteComment | (id: string) => Promise<boolean> | Delete a comment by ID. Returns true on success. |
Utility
| Method | Signature | Description |
|---|---|---|
refetch | () => void | Re-execute the comments list query |
refreshData | () => void | Invalidate all admin-comments queries |
Implementation Details
- Query caching: Uses TanStack React Query with a 5-minute
staleTime, 10-minutegcTime, 5-minute refetch interval, and 3 retries. - Placeholder data: Uses
keepPreviousDataso that paginated transitions do not flash empty states. - Delete tracking: The
isDeletingproperty tracks which specific comment ID is being deleted, enabling per-row loading indicators in the UI. - Toast notifications: Delete success and error states trigger
sonnertoast notifications automatically. - Cache invalidation: After a successful delete, all queries under the
['admin-comments']key family are invalidated. - Error handling: The
deleteCommentaction returnsboolean--trueon success,falseon failure. TheisDeletingstate is cleaned up in afinallyblock to ensure it resets even on error. - Read-only design: This hook only supports listing and deleting comments. Comment creation and editing are handled by the client-facing
useCommentshook.
Query Keys
const commentsQueryKeys = {
all: ['admin-comments'],
lists: () => ['admin-comments', 'list'],
list: (params) => ['admin-comments', 'list', params],
details: () => ['admin-comments', 'detail'],
detail: (id) => ['admin-comments', 'detail', id],
};
API Endpoints
| Operation | Method | Endpoint |
|---|---|---|
| List | GET | /api/admin/comments |
| Delete | DELETE | /api/admin/comments/:id |
Usage Examples
Paginated comment listing with search
import { useAdminComments } from '@/hooks/use-admin-comments';
function CommentsPage() {
const [page, setPage] = useState(1);
const [search, setSearch] = useState('');
const {
comments,
totalComments,
totalPages,
isLoading,
isFetching,
} = useAdminComments({ page, limit: 20, search });
return (
<div>
<SearchInput value={search} onChange={setSearch} />
<p>{totalComments} comments found {isFetching && '(updating...)'}</p>
{isLoading ? (
<Spinner />
) : (
<CommentsTable comments={comments} />
)}
<Pagination current={page} total={totalPages} onChange={setPage} />
</div>
);
}
Deleting a comment with per-row indicator
const { comments, deleteComment, isDeleting } = useAdminComments();
function CommentRow({ comment }: { comment: AdminCommentItem }) {
const isThisDeleting = isDeleting === comment.id;
const handleDelete = async () => {
const success = await deleteComment(comment.id);
if (success) {
// Comment removed, list auto-refreshes
}
};
return (
<tr>
<td>{comment.content}</td>
<td>{comment.user.name}</td>
<td>{comment.rating}</td>
<td>
<button onClick={handleDelete} disabled={isThisDeleting}>
{isThisDeleting ? 'Deleting...' : 'Delete'}
</button>
</td>
</tr>
);
}
Related Hooks
useComments-- Client-facing hook for creating and viewing comments on items.useAdminItems-- Comments are attached to items managed by this hook.useAdminUsers-- Each comment includes user information.