mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-23 14:11:13 -05:00
Refactor homepage content fetching
This commit is contained in:
55
src/hooks/homepage/useHomepageClosed.ts
Normal file
55
src/hooks/homepage/useHomepageClosed.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useHomepageRecentlyClosedParks(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.recentlyClosedParks(),
|
||||
queryFn: async () => {
|
||||
const oneYearAgo = new Date();
|
||||
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
||||
const today = new Date();
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`)
|
||||
.gte('closed_date', oneYearAgo.toISOString())
|
||||
.lte('closed_date', today.toISOString())
|
||||
.order('closed_date', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useHomepageRecentlyClosedRides(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.recentlyClosedRides(),
|
||||
queryFn: async () => {
|
||||
const oneYearAgo = new Date();
|
||||
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
||||
const today = new Date();
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks(*), location:locations(*)`)
|
||||
.gte('closed_date', oneYearAgo.toISOString())
|
||||
.lte('closed_date', today.toISOString())
|
||||
.order('closed_date', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
55
src/hooks/homepage/useHomepageClosing.ts
Normal file
55
src/hooks/homepage/useHomepageClosing.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useHomepageClosingSoonParks(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.closingSoonParks(),
|
||||
queryFn: async () => {
|
||||
const today = new Date();
|
||||
const sixMonthsFromNow = new Date();
|
||||
sixMonthsFromNow.setMonth(sixMonthsFromNow.getMonth() + 6);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`)
|
||||
.gte('closed_date', today.toISOString())
|
||||
.lte('closed_date', sixMonthsFromNow.toISOString())
|
||||
.order('closed_date', { ascending: true })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useHomepageClosingSoonRides(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.closingSoonRides(),
|
||||
queryFn: async () => {
|
||||
const today = new Date();
|
||||
const sixMonthsFromNow = new Date();
|
||||
sixMonthsFromNow.setMonth(sixMonthsFromNow.getMonth() + 6);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks(*), location:locations(*)`)
|
||||
.gte('closed_date', today.toISOString())
|
||||
.lte('closed_date', sixMonthsFromNow.toISOString())
|
||||
.order('closed_date', { ascending: true })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
51
src/hooks/homepage/useHomepageOpened.ts
Normal file
51
src/hooks/homepage/useHomepageOpened.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useHomepageRecentlyOpenedParks(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.recentlyOpenedParks(),
|
||||
queryFn: async () => {
|
||||
const oneYearAgo = new Date();
|
||||
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`)
|
||||
.gte('opened_date', oneYearAgo.toISOString())
|
||||
.order('opened_date', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useHomepageRecentlyOpenedRides(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.recentlyOpenedRides(),
|
||||
queryFn: async () => {
|
||||
const oneYearAgo = new Date();
|
||||
oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks(*), location:locations(*)`)
|
||||
.gte('opened_date', oneYearAgo.toISOString())
|
||||
.order('opened_date', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
55
src/hooks/homepage/useHomepageOpeningSoon.ts
Normal file
55
src/hooks/homepage/useHomepageOpeningSoon.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useHomepageOpeningSoonParks(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.openingSoonParks(),
|
||||
queryFn: async () => {
|
||||
const today = new Date();
|
||||
const sixMonthsFromNow = new Date();
|
||||
sixMonthsFromNow.setMonth(sixMonthsFromNow.getMonth() + 6);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`)
|
||||
.gte('opened_date', today.toISOString())
|
||||
.lte('opened_date', sixMonthsFromNow.toISOString())
|
||||
.order('opened_date', { ascending: true })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useHomepageOpeningSoonRides(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.openingSoonRides(),
|
||||
queryFn: async () => {
|
||||
const today = new Date();
|
||||
const sixMonthsFromNow = new Date();
|
||||
sixMonthsFromNow.setMonth(sixMonthsFromNow.getMonth() + 6);
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks(*), location:locations(*)`)
|
||||
.gte('opened_date', today.toISOString())
|
||||
.lte('opened_date', sixMonthsFromNow.toISOString())
|
||||
.order('opened_date', { ascending: true })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
45
src/hooks/homepage/useHomepageRated.ts
Normal file
45
src/hooks/homepage/useHomepageRated.ts
Normal file
@@ -0,0 +1,45 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useHomepageHighestRatedParks(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.highestRatedParks(),
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`)
|
||||
.not('average_rating', 'is', null)
|
||||
.order('average_rating', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useHomepageHighestRatedRides(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.highestRatedRides(),
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks(*), location:locations(*)`)
|
||||
.not('average_rating', 'is', null)
|
||||
.order('average_rating', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
43
src/hooks/homepage/useHomepageRecent.ts
Normal file
43
src/hooks/homepage/useHomepageRecent.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useHomepageRecentParks(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.recentParks(),
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useHomepageRecentRides(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.recentRides(),
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks(*), location:locations(*)`)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
149
src/hooks/homepage/useHomepageRecentChanges.ts
Normal file
149
src/hooks/homepage/useHomepageRecentChanges.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
interface RecentChange {
|
||||
id: string;
|
||||
name: string;
|
||||
type: 'park' | 'ride' | 'company';
|
||||
slug: string;
|
||||
parkSlug?: string;
|
||||
imageUrl?: string;
|
||||
changeType: string;
|
||||
changedAt: string;
|
||||
changedBy?: {
|
||||
username: string;
|
||||
avatarUrl?: string;
|
||||
};
|
||||
changeReason?: string;
|
||||
}
|
||||
|
||||
export function useHomepageRecentChanges(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.recentChanges(),
|
||||
queryFn: async () => {
|
||||
// Fetch recent park versions
|
||||
const { data: parkVersions } = await supabase
|
||||
.from('park_versions')
|
||||
.select(`
|
||||
park_id,
|
||||
name,
|
||||
slug,
|
||||
card_image_url,
|
||||
change_type,
|
||||
created_at,
|
||||
created_by,
|
||||
change_reason,
|
||||
profiles:created_by(username, avatar_url)
|
||||
`)
|
||||
.eq('is_current', true)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(8);
|
||||
|
||||
// Fetch recent ride versions
|
||||
const { data: rideVersions } = await supabase
|
||||
.from('ride_versions')
|
||||
.select(`
|
||||
ride_id,
|
||||
name,
|
||||
slug,
|
||||
card_image_url,
|
||||
change_type,
|
||||
created_at,
|
||||
created_by,
|
||||
change_reason,
|
||||
park_id,
|
||||
profiles:created_by(username, avatar_url)
|
||||
`)
|
||||
.eq('is_current', true)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(8);
|
||||
|
||||
// Fetch park slugs for rides
|
||||
const parkIds = rideVersions?.map(rv => rv.park_id).filter(Boolean) || [];
|
||||
const { data: parks } = parkIds.length > 0
|
||||
? await supabase
|
||||
.from('parks')
|
||||
.select('id, slug')
|
||||
.in('id', parkIds)
|
||||
: { data: [] };
|
||||
|
||||
const parkSlugMap = new Map<string, string>(
|
||||
(parks || []).map(p => [p.id, p.slug])
|
||||
);
|
||||
|
||||
// Fetch recent company versions
|
||||
const { data: companyVersions } = await supabase
|
||||
.from('company_versions')
|
||||
.select(`
|
||||
company_id,
|
||||
name,
|
||||
slug,
|
||||
card_image_url,
|
||||
change_type,
|
||||
created_at,
|
||||
created_by,
|
||||
change_reason,
|
||||
profiles:created_by(username, avatar_url)
|
||||
`)
|
||||
.eq('is_current', true)
|
||||
.order('created_at', { ascending: false })
|
||||
.limit(8);
|
||||
|
||||
// Combine and sort all changes
|
||||
const changes: RecentChange[] = [
|
||||
...(parkVersions || []).map(pv => ({
|
||||
id: pv.park_id,
|
||||
name: pv.name,
|
||||
type: 'park' as const,
|
||||
slug: pv.slug,
|
||||
imageUrl: pv.card_image_url,
|
||||
changeType: pv.change_type,
|
||||
changedAt: pv.created_at,
|
||||
changedBy: pv.profiles ? {
|
||||
username: pv.profiles.username,
|
||||
avatarUrl: pv.profiles.avatar_url
|
||||
} : undefined,
|
||||
changeReason: pv.change_reason
|
||||
})),
|
||||
...(rideVersions || []).map(rv => ({
|
||||
id: rv.ride_id,
|
||||
name: rv.name,
|
||||
type: 'ride' as const,
|
||||
slug: rv.slug,
|
||||
parkSlug: rv.park_id ? (parkSlugMap.get(rv.park_id) || undefined) : undefined,
|
||||
imageUrl: rv.card_image_url,
|
||||
changeType: rv.change_type,
|
||||
changedAt: rv.created_at,
|
||||
changedBy: rv.profiles ? {
|
||||
username: rv.profiles.username,
|
||||
avatarUrl: rv.profiles.avatar_url
|
||||
} : undefined,
|
||||
changeReason: rv.change_reason
|
||||
})),
|
||||
...(companyVersions || []).map(cv => ({
|
||||
id: cv.company_id,
|
||||
name: cv.name,
|
||||
type: 'company' as const,
|
||||
slug: cv.slug,
|
||||
imageUrl: cv.card_image_url,
|
||||
changeType: cv.change_type,
|
||||
changedAt: cv.created_at,
|
||||
changedBy: cv.profiles ? {
|
||||
username: cv.profiles.username,
|
||||
avatarUrl: cv.profiles.avatar_url
|
||||
} : undefined,
|
||||
changeReason: cv.change_reason
|
||||
}))
|
||||
];
|
||||
|
||||
return changes
|
||||
.sort((a, b) => new Date(b.changedAt).getTime() - new Date(a.changedAt).getTime())
|
||||
.slice(0, 24);
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
43
src/hooks/homepage/useHomepageTrending.ts
Normal file
43
src/hooks/homepage/useHomepageTrending.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { supabase } from '@/integrations/supabase/client';
|
||||
import { queryKeys } from '@/lib/queryKeys';
|
||||
|
||||
export function useHomepageTrendingParks(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.trendingParks(),
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
.from('parks')
|
||||
.select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`)
|
||||
.order('view_count_30d', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
|
||||
export function useHomepageTrendingRides(enabled = true) {
|
||||
return useQuery({
|
||||
queryKey: queryKeys.homepage.trendingRides(),
|
||||
queryFn: async () => {
|
||||
const { data, error } = await supabase
|
||||
.from('rides')
|
||||
.select(`*, park:parks(*), location:locations(*)`)
|
||||
.order('view_count_30d', { ascending: false })
|
||||
.limit(12);
|
||||
|
||||
if (error) throw error;
|
||||
return data || [];
|
||||
},
|
||||
enabled,
|
||||
staleTime: 5 * 60 * 1000,
|
||||
gcTime: 15 * 60 * 1000,
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user