diff --git a/src/hooks/companies/useCompanyStatistics.ts b/src/hooks/companies/useCompanyStatistics.ts index d262e2b7..007b3aa2 100644 --- a/src/hooks/companies/useCompanyStatistics.ts +++ b/src/hooks/companies/useCompanyStatistics.ts @@ -40,32 +40,21 @@ export function useCompanyStatistics(companyId: string | undefined, companyType: photosCount: photosRes.count || 0, }; } else { - // operator or property_owner + // operator or property_owner - optimized single query const parkField = companyType === 'operator' ? 'operator_id' : 'property_owner_id'; - const filterField = `parks.${parkField}`; const [parksRes, ridesRes, photosRes] = await Promise.all([ supabase.from('parks').select('id', { count: 'exact', head: true }).eq(parkField, companyId), - supabase.from('rides').select('id').eq('status', 'operating'), + supabase.from('rides') + .select('id, parks!inner(operator_id, property_owner_id)', { count: 'exact', head: true }) + .eq('status', 'operating') + .eq(`parks.${parkField}`, companyId), supabase.from('photos').select('id', { count: 'exact', head: true }).eq('entity_type', companyType).eq('entity_id', companyId) ]); - // Filter rides data manually to avoid deep type instantiation - const allRidesIds = ridesRes.data?.map(r => r.id) || []; - const { data: ridesWithPark } = await supabase - .from('rides') - .select('id, park_id, parks!inner(operator_id, property_owner_id)') - .in('id', allRidesIds); - - const operatingRides = ridesWithPark?.filter((r: any) => { - return companyType === 'operator' - ? r.parks?.operator_id === companyId - : r.parks?.property_owner_id === companyId; - }) || []; - return { parksCount: parksRes.count || 0, - operatingRidesCount: operatingRides.length, + operatingRidesCount: ridesRes.count || 0, photosCount: photosRes.count || 0, }; } diff --git a/src/hooks/homepage/useHomepageRecentChanges.ts b/src/hooks/homepage/useHomepageRecentChanges.ts index 37e673d7..aacfd0e3 100644 --- a/src/hooks/homepage/useHomepageRecentChanges.ts +++ b/src/hooks/homepage/useHomepageRecentChanges.ts @@ -28,7 +28,7 @@ export function useHomepageRecentChanges(enabled = true) { if (error) throw error; // Transform the database response to match our interface - return (data || []).map((item: any) => ({ + return (data || []).map((item: any): RecentChange => ({ id: item.entity_id, name: item.entity_name, type: item.entity_type as 'park' | 'ride' | 'company', @@ -42,7 +42,7 @@ export function useHomepageRecentChanges(enabled = true) { avatarUrl: item.changed_by_avatar || undefined } : undefined, changeReason: item.change_reason || undefined - })) as RecentChange[]; + })); }, enabled, staleTime: 5 * 60 * 1000, diff --git a/src/hooks/profile/useProfileActivity.ts b/src/hooks/profile/useProfileActivity.ts index 8968a22e..98b7ea4c 100644 --- a/src/hooks/profile/useProfileActivity.ts +++ b/src/hooks/profile/useProfileActivity.ts @@ -33,42 +33,39 @@ export function useProfileActivity( return []; } + // Build queries with conditional filters + const reviewsQuery = supabase.from('reviews') + .select('id, rating, title, created_at, moderation_status, park_id, ride_id, parks(name, slug), rides(name, slug, parks(name, slug))') + .eq('user_id', userId); + if (!isOwnProfile && !isModerator) { + reviewsQuery.eq('moderation_status', 'approved'); + } + + const submissionsQuery = supabase.from('content_submissions') + .select('id, submission_type, content, status, created_at') + .eq('user_id', userId); + if (!isOwnProfile && !isModerator) { + submissionsQuery.eq('status', 'approved'); + } + + const rankingsQuery = supabase.from('user_top_lists') + .select('id, title, description, list_type, created_at') + .eq('user_id', userId); + if (!isOwnProfile) { + rankingsQuery.eq('is_public', true); + } + // Fetch all activity types in parallel const [reviews, credits, submissions, rankings] = await Promise.all([ - // Reviews query - supabase.from('reviews') - .select('id, rating, title, created_at, moderation_status, park_id, ride_id, parks(name, slug), rides(name, slug, parks(name, slug))') - .eq('user_id', userId) - .eq('moderation_status', isOwnProfile || isModerator ? undefined : 'approved') - .order('created_at', { ascending: false }) - .limit(10) - .then(res => res.data || []), - - // Credits query + reviewsQuery.order('created_at', { ascending: false }).limit(10).then(res => res.data || []), supabase.from('user_ride_credits') .select('id, ride_count, first_ride_date, created_at, rides(name, slug, parks(name, slug))') .eq('user_id', userId) .order('created_at', { ascending: false }) .limit(10) .then(res => res.data || []), - - // Submissions query - supabase.from('content_submissions') - .select('id, submission_type, content, status, created_at') - .eq('user_id', userId) - .eq('status', isOwnProfile || isModerator ? undefined : 'approved') - .order('created_at', { ascending: false }) - .limit(10) - .then(res => res.data || []), - - // Rankings query - supabase.from('user_top_lists') - .select('id, title, description, list_type, created_at') - .eq('user_id', userId) - .eq('is_public', isOwnProfile ? undefined : true) - .order('created_at', { ascending: false }) - .limit(10) - .then(res => res.data || []) + submissionsQuery.order('created_at', { ascending: false }).limit(10).then(res => res.data || []), + rankingsQuery.order('created_at', { ascending: false }).limit(10).then(res => res.data || []) ]); // Enrich photo submissions in batch