Skip to main content

useAdminFeaturedItems

Overview

useAdminFeaturedItems is a React hook for managing featured items in the admin panel. It provides CRUD operations, ordering control, client-side search filtering, pagination, and access to the full items catalog for cross-referencing. Built on top of TanStack React Query and the internal serverClient API layer.

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

Signature / Parameters

function useAdminFeaturedItems(
options?: UseAdminFeaturedItemsOptions
): UseAdminFeaturedItemsReturn

UseAdminFeaturedItemsOptions

ParameterTypeDefaultDescription
pagenumber1Initial page number for pagination
limitnumber10Number of featured items per page
showActiveOnlybooleantrueWhether to show only active featured items
searchTermstring""Initial search term for client-side filtering

Return Values

The hook returns an object implementing UseAdminFeaturedItemsReturn:

Data

PropertyTypeDescription
featuredItemsFeaturedItem[]Array of featured items from the current server page
allItemsItemData[]Full catalog of all items (up to 1000), for cross-referencing
filteredItemsFeaturedItem[]Featured items filtered by the current searchTerm (client-side)

FeaturedItem

interface FeaturedItem {
id: string;
itemSlug: string;
itemName: string;
itemIconUrl?: string;
itemCategory?: string;
itemDescription?: string;
featuredOrder: number;
featuredUntil?: string;
isActive: boolean;
featuredBy: string;
featuredAt: string;
createdAt: string;
updatedAt: string;
}

Loading States

PropertyTypeDescription
isLoadingbooleantrue when either featured items or all items are loading
isSubmittingbooleantrue when any create/update/delete mutation is pending

Pagination

PropertyTypeDescription
currentPagenumberCurrent page number
totalPagesnumberTotal number of pages (defaults to 1)
totalItemsnumberTotal number of featured items

Filters

PropertyTypeDescription
searchTermstringCurrent client-side search filter value
showActiveOnlybooleanCurrent active-only filter state

Actions

MethodSignatureDescription
createFeaturedItem(data: Partial<FeaturedItem>) => Promise<boolean>Feature a new item. Returns true on success.
updateFeaturedItem(id: string, data: Partial<FeaturedItem>) => Promise<boolean>Update a featured item by ID.
deleteFeaturedItem(id: string) => Promise<boolean>Remove an item from featured.
updateOrder(id: string, newOrder: number) => Promise<boolean>Change the display order of a featured item.

Filter Actions

MethodSignatureDescription
setSearchTerm(term: string) => voidUpdate the client-side search term
setShowActiveOnly(active: boolean) => voidToggle active-only filter
setCurrentPage(page: number) => voidNavigate to a specific page

Utility

MethodSignatureDescription
getItemBySlug(slug: string) => ItemData | undefinedLook up a full item record by slug from the all-items cache
refreshData() => voidInvalidate all featured items and all-items queries

Implementation Details

  • Dual queries: The hook runs two parallel queries -- one for paginated featured items (5-minute staleTime, 10-minute gcTime, 5-minute refetch interval, 3 retries) and one for the full items catalog (10-minute staleTime, 30-minute gcTime).
  • Client-side filtering: The filteredItems property applies searchTerm locally against itemName and itemSlug, providing instant search without additional server requests.
  • Toast notifications: All mutation success and error states trigger sonner toast notifications automatically.
  • Cache invalidation: On mutation success, both the featured-items and all-items query families are invalidated.
  • Error handling: All action handlers return boolean -- true on success, false on failure.
  • Memoization: The allItems array and getItemBySlug callback are memoized to prevent unnecessary re-renders.

Query Keys

const featuredItemsQueryKeys = {
all: ['featured-items'],
lists: () => ['featured-items', 'list'],
list: (filters) => ['featured-items', 'list', filters],
details: () => ['featured-items', 'detail'],
detail: (id) => ['featured-items', 'detail', id],
};

const allItemsQueryKeys = {
all: ['all-items'],
lists: () => ['all-items', 'list'],
};

API Endpoints

OperationMethodEndpoint
ListGET/api/admin/featured-items
CreatePOST/api/admin/featured-items
UpdatePUT/api/admin/featured-items/:id
DeleteDELETE/api/admin/featured-items/:id
All itemsGET/api/admin/items?page=1&limit=1000

Usage Examples

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

function FeaturedItemsPage() {
const {
featuredItems,
totalItems,
totalPages,
currentPage,
setCurrentPage,
isLoading,
} = useAdminFeaturedItems({ limit: 20 });

if (isLoading) return <Spinner />;

return (
<div>
<p>{totalItems} featured items</p>
<FeaturedItemsTable items={featuredItems} />
<Pagination
current={currentPage}
total={totalPages}
onChange={setCurrentPage}
/>
</div>
);
}

Client-side search filtering

const {
filteredItems,
searchTerm,
setSearchTerm,
} = useAdminFeaturedItems();

return (
<div>
<SearchInput value={searchTerm} onChange={setSearchTerm} />
<FeaturedItemsList items={filteredItems} />
</div>
);

Featuring an item and reordering

const {
createFeaturedItem,
updateOrder,
isSubmitting,
} = useAdminFeaturedItems();

// Feature a new item
const handleFeature = async (itemSlug: string) => {
const success = await createFeaturedItem({
itemSlug,
featuredOrder: 1,
isActive: true,
});
};

// Change display order
const handleReorder = async (id: string, newPosition: number) => {
await updateOrder(id, newPosition);
};

Cross-referencing items

const { featuredItems, getItemBySlug } = useAdminFeaturedItems();

// Look up full item data for a featured item
const fullItem = getItemBySlug(featuredItems[0]?.itemSlug);
console.log(fullItem?.name, fullItem?.description);