mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 23:11:12 -05:00
60 lines
2.3 KiB
TypeScript
60 lines
2.3 KiB
TypeScript
import { useQuery } from '@tanstack/react-query';
|
|
import { supabase } from '@/lib/supabaseClient';
|
|
import { queryKeys } from '@/lib/queryKeys';
|
|
|
|
/**
|
|
* Hook to fetch list items with entities (batch fetching to avoid N+1)
|
|
*/
|
|
export function useListItems(listId: string | undefined, enabled = true) {
|
|
return useQuery({
|
|
queryKey: queryKeys.lists.items(listId || ''),
|
|
queryFn: async () => {
|
|
if (!listId) return [];
|
|
|
|
// Get items
|
|
const { data: items, error: itemsError } = await supabase
|
|
.from('user_top_list_items')
|
|
.select('*')
|
|
.eq('list_id', listId)
|
|
.order('position', { ascending: true });
|
|
|
|
if (itemsError) throw itemsError;
|
|
if (!items || items.length === 0) return [];
|
|
|
|
// Group by entity type for batch fetching
|
|
const parkIds = items.filter(i => i.entity_type === 'park').map(i => i.entity_id);
|
|
const rideIds = items.filter(i => i.entity_type === 'ride').map(i => i.entity_id);
|
|
const companyIds = items.filter(i => i.entity_type === 'company').map(i => i.entity_id);
|
|
|
|
// Batch fetch all entities in parallel
|
|
const [parksResult, ridesResult, companiesResult] = await Promise.all([
|
|
parkIds.length > 0
|
|
? supabase.from('parks').select('id, name, slug, park_type, location_id').in('id', parkIds)
|
|
: Promise.resolve({ data: [] }),
|
|
rideIds.length > 0
|
|
? supabase.from('rides').select('id, name, slug, category, park_id').in('id', rideIds)
|
|
: Promise.resolve({ data: [] }),
|
|
companyIds.length > 0
|
|
? supabase.from('companies').select('id, name, slug, company_type').in('id', companyIds)
|
|
: Promise.resolve({ data: [] }),
|
|
]);
|
|
|
|
// Create entities map for quick lookup
|
|
const entitiesMap = new Map<string, any>();
|
|
(parksResult.data || []).forEach(p => entitiesMap.set(p.id, p));
|
|
(ridesResult.data || []).forEach(r => entitiesMap.set(r.id, r));
|
|
(companiesResult.data || []).forEach(c => entitiesMap.set(c.id, c));
|
|
|
|
// Map entities to items
|
|
return items.map(item => ({
|
|
...item,
|
|
entity: entitiesMap.get(item.entity_id),
|
|
}));
|
|
},
|
|
enabled: enabled && !!listId,
|
|
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
gcTime: 15 * 60 * 1000,
|
|
refetchOnWindowFocus: false,
|
|
});
|
|
}
|