mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-26 19:46:59 -05:00
feat: Implement Modern React Patterns
This commit is contained in:
141
src/hooks/moderation/useQueueQuery.ts
Normal file
141
src/hooks/moderation/useQueueQuery.ts
Normal file
@@ -0,0 +1,141 @@
|
||||
/**
|
||||
* TanStack Query hook for moderation queue data fetching
|
||||
*
|
||||
* Wraps the existing fetchSubmissions query builder with React Query
|
||||
* to provide automatic caching, deduplication, and background refetching.
|
||||
*/
|
||||
|
||||
import { useQuery, useQueryClient } from '@tanstack/react-query';
|
||||
import { fetchSubmissions, type QueryConfig } from '@/lib/moderation/queries';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import type { ModerationItem } from '@/types/moderation';
|
||||
|
||||
/**
|
||||
* Configuration for queue query
|
||||
*/
|
||||
export interface UseQueueQueryConfig {
|
||||
/** User making the query */
|
||||
userId: string | undefined;
|
||||
|
||||
/** Whether user is admin */
|
||||
isAdmin: boolean;
|
||||
|
||||
/** Whether user is superuser */
|
||||
isSuperuser: boolean;
|
||||
|
||||
/** Entity filter */
|
||||
entityFilter: string;
|
||||
|
||||
/** Status filter */
|
||||
statusFilter: string;
|
||||
|
||||
/** Active tab */
|
||||
tab: 'mainQueue' | 'archive';
|
||||
|
||||
/** Current page */
|
||||
currentPage: number;
|
||||
|
||||
/** Page size */
|
||||
pageSize: number;
|
||||
|
||||
/** Sort configuration */
|
||||
sortConfig: {
|
||||
field: string;
|
||||
direction: 'asc' | 'desc';
|
||||
};
|
||||
|
||||
/** Whether query is enabled (defaults to true) */
|
||||
enabled?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return type for useQueueQuery
|
||||
*/
|
||||
export interface UseQueueQueryReturn {
|
||||
/** Queue items */
|
||||
items: ModerationItem[];
|
||||
|
||||
/** Total count of items matching filters */
|
||||
totalCount: number;
|
||||
|
||||
/** Initial loading state (no data yet) */
|
||||
isLoading: boolean;
|
||||
|
||||
/** Background refresh in progress (has data already) */
|
||||
isRefreshing: boolean;
|
||||
|
||||
/** Any error that occurred */
|
||||
error: Error | null;
|
||||
|
||||
/** Manually trigger a refetch */
|
||||
refetch: () => Promise<any>;
|
||||
|
||||
/** Invalidate this query (triggers background refetch) */
|
||||
invalidate: () => Promise<void>;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to fetch moderation queue data using TanStack Query
|
||||
*/
|
||||
export function useQueueQuery(config: UseQueueQueryConfig): UseQueueQueryReturn {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
// Build query config for fetchSubmissions
|
||||
const queryConfig: QueryConfig = {
|
||||
userId: config.userId || '',
|
||||
isAdmin: config.isAdmin,
|
||||
isSuperuser: config.isSuperuser,
|
||||
entityFilter: config.entityFilter as any,
|
||||
statusFilter: config.statusFilter as any,
|
||||
tab: config.tab,
|
||||
currentPage: config.currentPage,
|
||||
pageSize: config.pageSize,
|
||||
sortConfig: config.sortConfig as any,
|
||||
};
|
||||
|
||||
// Create stable query key (TanStack Query uses this for caching/deduplication)
|
||||
const queryKey = [
|
||||
'moderation-queue',
|
||||
config.entityFilter,
|
||||
config.statusFilter,
|
||||
config.tab,
|
||||
config.currentPage,
|
||||
config.pageSize,
|
||||
config.sortConfig.field,
|
||||
config.sortConfig.direction,
|
||||
];
|
||||
|
||||
// Execute query
|
||||
const query = useQuery({
|
||||
queryKey,
|
||||
queryFn: async () => {
|
||||
console.log('🔍 [TanStack Query] Fetching queue data:', queryKey);
|
||||
const result = await fetchSubmissions(supabase, queryConfig);
|
||||
|
||||
if (result.error) {
|
||||
throw result.error;
|
||||
}
|
||||
|
||||
console.log('✅ [TanStack Query] Fetched', result.submissions.length, 'items');
|
||||
return result;
|
||||
},
|
||||
enabled: config.enabled !== false && !!config.userId,
|
||||
staleTime: 30000, // 30 seconds
|
||||
gcTime: 5 * 60 * 1000, // 5 minutes
|
||||
});
|
||||
|
||||
// Invalidate helper
|
||||
const invalidate = async () => {
|
||||
await queryClient.invalidateQueries({ queryKey: ['moderation-queue'] });
|
||||
};
|
||||
|
||||
return {
|
||||
items: query.data?.submissions || [],
|
||||
totalCount: query.data?.totalCount || 0,
|
||||
isLoading: query.isLoading,
|
||||
isRefreshing: query.isFetching && !query.isLoading,
|
||||
error: query.error as Error | null,
|
||||
refetch: query.refetch,
|
||||
invalidate,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user