mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-25 09:51:12 -05:00
feat: Implement Phase 4 cleanup and polish
This commit is contained in:
39
src/hooks/rideModels/useModelRides.ts
Normal file
39
src/hooks/rideModels/useModelRides.ts
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
* Model Rides Hook
|
||||
*
|
||||
* Fetches rides using a specific ride model with caching.
|
||||
*/
|
||||
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useModelRides(modelId: string | undefined, limit?: number) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.rideModels.rides(modelId || '', limit),
|
||||
queryFn: async () => {
|
||||
if (!modelId) return [];
|
||||
|
||||
let query = supabase
|
||||
.from('rides')
|
||||
.select(`
|
||||
*,
|
||||
park:parks!inner(name, slug, location:locations(*)),
|
||||
manufacturer:companies!rides_manufacturer_id_fkey(*),
|
||||
ride_model:ride_models(id, name, slug, manufacturer_id, category)
|
||||
`)
|
||||
.eq('ride_model_id', modelId)
|
||||
.order('name');
|
||||
|
||||
if (limit) query = query.limit(limit);
|
||||
|
||||
const { data, error } = await query;
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled: !!modelId,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
32
src/hooks/rideModels/useModelStatistics.ts
Normal file
32
src/hooks/rideModels/useModelStatistics.ts
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
* Model Statistics Hook
|
||||
*
|
||||
* Fetches ride model statistics (ride count, photo count) with parallel queries.
|
||||
*/
|
||||
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useModelStatistics(modelId: string | undefined) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.rideModels.statistics(modelId || ''),
|
||||
queryFn: async () => {
|
||||
if (!modelId) return { rideCount: 0, photoCount: 0 };
|
||||
|
||||
const [ridesResult, photosResult] = await Promise.all([
|
||||
supabase.from('rides').select('id', { count: 'exact', head: true }).eq('ride_model_id', modelId),
|
||||
supabase.from('photos').select('id', { count: 'exact', head: true }).eq('entity_type', 'ride_model').eq('entity_id', modelId)
|
||||
]);
|
||||
|
||||
return {
|
||||
rideCount: ridesResult.count || 0,
|
||||
photoCount: photosResult.count || 0
|
||||
};
|
||||
},
|
||||
enabled: !!modelId,
|
||||
staleTime: 10 * 60 * 1000,
|
||||
gcTime: 20 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
48
src/hooks/rideModels/useRideModelDetail.ts
Normal file
48
src/hooks/rideModels/useRideModelDetail.ts
Normal file
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Ride Model Detail Hook
|
||||
*
|
||||
* Fetches ride model and manufacturer data with caching.
|
||||
*/
|
||||
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useRideModelDetail(
|
||||
manufacturerSlug: string | undefined,
|
||||
modelSlug: string | undefined
|
||||
) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.rideModels.detail(manufacturerSlug || '', modelSlug || ''),
|
||||
queryFn: async () => {
|
||||
if (!manufacturerSlug || !modelSlug) return null;
|
||||
|
||||
// Fetch manufacturer first
|
||||
const { data: manufacturer, error: mfgError } = await supabase
|
||||
.from('companies')
|
||||
.select('*')
|
||||
.eq('slug', manufacturerSlug)
|
||||
.eq('company_type', 'manufacturer')
|
||||
.maybeSingle();
|
||||
|
||||
if (mfgError) throw mfgError;
|
||||
if (!manufacturer) return null;
|
||||
|
||||
// Fetch ride model
|
||||
const { data: model, error: modelError } = await supabase
|
||||
.from('ride_models')
|
||||
.select('*')
|
||||
.eq('slug', modelSlug)
|
||||
.eq('manufacturer_id', manufacturer.id)
|
||||
.maybeSingle();
|
||||
|
||||
if (modelError) throw modelError;
|
||||
|
||||
return model ? { model, manufacturer } : null;
|
||||
},
|
||||
enabled: !!manufacturerSlug && !!modelSlug,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user