/** * useCrawledPages Hook * * TanStack Query hook for fetching discovered pages (crawled pages) for a tenant. * Provides automatic caching, request deduplication, and background refetching. * * @layer Presentation */ import { useQuery } from '@tanstack/react-query'; import { queryKeys } from '@/lib/query-keys'; import { infoCenterApi } from '@/infrastructure/http/api/info-center'; import type { DiscoveredPage } from '@/domain/entities/DiscoveredPage'; /** * useCrawledPages Hook Options */ export interface UseCrawledPagesOptions { /** * Tenant ID to fetch pages for */ tenantId?: string; /** * Page number (1-indexed) * @default 1 */ page?: number; /** * Number of items per page * @default 50 */ limit?: number; /** * Enable/disable the query * @default true (when tenantId is provided) */ enabled?: boolean; } /** * useCrawledPages Hook Return Type */ export interface UseCrawledPagesReturn { /** * Discovered pages array */ pages: DiscoveredPage[]; /** * Loading state */ isLoading: boolean; /** * Error state */ error: Error | null; /** * Total count of pages */ total: number; /** * Total number of pages */ totalPages: number; /** * Current page number */ page: number; /** * Items per page */ limit: number; /** * Has next page */ hasNext: boolean; /** * Has previous page */ hasPrevious: boolean; /** * Refetch function */ refetch: () => void; } /** * Fetch discovered pages for a tenant * * Uses TanStack Query for automatic caching, request deduplication, * and background refetching. * * @param options - Query options * @returns Discovered pages with loading/error states * * @example * ```tsx * function PagesList() { * const { pages, isLoading, error, page, totalPages } = useCrawledPages({ * tenantId: 'tenant-123', * page: 1, * limit: 50, * }); * * if (isLoading) return ; * if (error) return ; * * return ( *
*
    * {pages.map(page => ( *
  • {page.url}
  • * ))} *
* *
* ); * } * ``` */ export function useCrawledPages(options: UseCrawledPagesOptions = {}): UseCrawledPagesReturn { const { tenantId, page = 1, limit = 50, enabled } = options; // Query const query = useQuery({ queryKey: queryKeys.infoCenter.pages(tenantId ?? '', { page, limit }), queryFn: async () => { if (!tenantId) { throw new Error('tenantId is required'); } const result = await infoCenterApi.listPages(tenantId, { page, limit }); return result; }, enabled: enabled !== undefined ? enabled : !!tenantId, staleTime: 5 * 60 * 1000, // 5 minutes gcTime: 10 * 60 * 1000, // 10 minutes }); const pagination = query.data?.pagination ?? { total: 0, page: 1, limit: 50, totalPages: 0 }; return { pages: query.data?.pages ?? [], isLoading: query.isLoading, error: query.error as Error | null, total: pagination.total, totalPages: pagination.totalPages, page: pagination.page, limit: pagination.limit, hasNext: pagination.page < pagination.totalPages, hasPrevious: pagination.page > 1, refetch: query.refetch, }; }