import { useState, useEffect } from 'react'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { ParkCard } from '@/components/parks/ParkCard'; import { RideCard } from '@/components/rides/RideCard'; import { RecentChangeCard } from './RecentChangeCard'; import { Badge } from '@/components/ui/badge'; import { Park, Ride } from '@/types/database'; import { supabase } from '@/integrations/supabase/client'; import { getErrorMessage } from '@/lib/errorHandler'; import { logger } from '@/lib/logger'; interface RecentChange { entityType: 'park' | 'ride' | 'company'; entityId: string; entityName: string; entitySlug: string; parkSlug?: string; imageUrl: string | null; changeType: string; changedAt: string; changedByUsername?: string | null; changedByAvatar?: string | null; changeReason: string | null; } export function ContentTabs() { const [trendingParks, setTrendingParks] = useState([]); const [trendingRides, setTrendingRides] = useState([]); const [recentParks, setRecentParks] = useState([]); const [recentRides, setRecentRides] = useState([]); const [recentChanges, setRecentChanges] = useState([]); const [recentlyOpened, setRecentlyOpened] = useState>([]); const [loading, setLoading] = useState(true); useEffect(() => { fetchContent(); }, []); const fetchContent = async () => { try { // Trending Parks (by 30-day view count) const { data: trending } = await supabase .from('parks') .select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`) .order('view_count_30d', { ascending: false }) .limit(12); // Recently Added Parks const { data: recent } = await supabase .from('parks') .select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`) .order('created_at', { ascending: false }) .limit(12); // Trending Rides (by 30-day view count) const { data: trendingRidesData } = await supabase .from('rides') .select(`*, park:parks!inner(name, slug, location:locations(*))`) .order('view_count_30d', { ascending: false }) .limit(12); // Recently Added Rides const { data: recentRidesData } = await supabase .from('rides') .select(`*, park:parks!inner(name, slug, location:locations(*))`) .order('created_at', { ascending: false }) .limit(12); // Fetch recent park versions const { data: parkVersions } = await supabase .from('park_versions') .select(` version_id, park_id, name, slug, change_type, created_at, created_by, change_reason, card_image_url, profiles:profiles!park_versions_created_by_fkey(username, avatar_url) `) .eq('is_current', true) .order('created_at', { ascending: false }) .limit(12); // Fetch recent ride versions with park slug for proper routing const { data: rideVersions } = await supabase .from('ride_versions') .select(` version_id, ride_id, name, slug, change_type, created_at, created_by, change_reason, card_image_url, park_id, profiles:profiles!ride_versions_created_by_fkey(username, avatar_url) `) .eq('is_current', true) .order('created_at', { ascending: false }) .limit(12); // Fetch park slugs for rides that have a park_id const rideParksMap = new Map(); if (rideVersions) { const parkIds = [...new Set(rideVersions.map(v => v.park_id).filter(Boolean))]; if (parkIds.length > 0) { const { data: parks } = await supabase .from('parks') .select('id, slug') .in('id', parkIds); parks?.forEach(park => { rideParksMap.set(park.id, park.slug); }); } } // Fetch recent company versions const { data: companyVersions } = await supabase .from('company_versions') .select(` version_id, company_id, name, slug, change_type, created_at, created_by, change_reason, card_image_url, profiles:profiles!company_versions_created_by_fkey(username, avatar_url) `) .eq('is_current', true) .order('created_at', { ascending: false }) .limit(12); // Combine all changes into a unified structure const allChanges: RecentChange[] = [ ...(parkVersions || []).map(v => ({ entityType: 'park' as const, entityId: v.park_id, entityName: v.name, entitySlug: v.slug, imageUrl: v.card_image_url, changeType: v.change_type, changedAt: v.created_at, changedByUsername: v.profiles?.username, changedByAvatar: v.profiles?.avatar_url, changeReason: v.change_reason, })), ...(rideVersions || []).map(v => ({ entityType: 'ride' as const, entityId: v.ride_id, entityName: v.name, entitySlug: v.slug, parkSlug: v.park_id ? rideParksMap.get(v.park_id) : undefined, imageUrl: v.card_image_url, changeType: v.change_type, changedAt: v.created_at, changedByUsername: v.profiles?.username, changedByAvatar: v.profiles?.avatar_url, changeReason: v.change_reason, })), ...(companyVersions || []).map(v => ({ entityType: 'company' as const, entityId: v.company_id, entityName: v.name, entitySlug: v.slug, imageUrl: v.card_image_url, changeType: v.change_type, changedAt: v.created_at, changedByUsername: v.profiles?.username, changedByAvatar: v.profiles?.avatar_url, changeReason: v.change_reason, })) ] .sort((a, b) => new Date(b.changedAt).getTime() - new Date(a.changedAt).getTime()) .slice(0, 24); // Fetch recently opened parks and rides const oneYearAgo = new Date(); oneYearAgo.setFullYear(oneYearAgo.getFullYear() - 1); const dateThreshold = oneYearAgo.toISOString().split('T')[0]; const { data: openedParks } = await supabase .from('parks') .select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`) .not('opening_date', 'is', null) .gte('opening_date', dateThreshold) .order('opening_date', { ascending: false }) .limit(20); const { data: openedRides } = await supabase .from('rides') .select(`*, park:parks!inner(name, slug, location:locations(*))`) .not('opening_date', 'is', null) .gte('opening_date', dateThreshold) .order('opening_date', { ascending: false }) .limit(20); // Combine and sort by opening date const combinedOpened = [ ...(openedParks || []).map(p => ({ ...p, entityType: 'park' as const })), ...(openedRides || []).map(r => ({ ...r, entityType: 'ride' as const })) ] .sort((a, b) => new Date(b.opening_date).getTime() - new Date(a.opening_date).getTime()) .slice(0, 24); setTrendingParks(trending || []); setRecentParks(recent || []); setTrendingRides(trendingRidesData || []); setRecentRides(recentRidesData || []); setRecentChanges(allChanges); setRecentlyOpened(combinedOpened); } catch (error: unknown) { logger.error('Failed to fetch content', { error: getErrorMessage(error) }); } finally { setLoading(false); } }; if (loading) { return (
{[...Array(6)].map((_, i) => (
))}
); } return (
Trending Parks Trending Rides New Parks New Rides Recent Changes Recently Opened

Trending Parks

Most viewed parks in the last 30 days

{trendingParks.map((park) => ( ))}

Trending Rides

Most viewed rides in the last 30 days

{trendingRides.map((ride) => ( ))}

Recently Added Parks

Latest parks added to our database

{recentParks.map((park) => ( ))}

Recently Added Rides

Latest attractions added to our database

{recentRides.map((ride) => ( ))}

Recent Changes

Latest updates across all entities

{recentChanges.length > 0 ? (
{recentChanges.map((change) => ( ))}
) : (
No recent changes to display
)}

Recently Opened

Parks and rides that opened in the last year

{recentlyOpened.map((entity: any) => ( entity.entityType === 'park' ? (
{new Date(entity.opening_date).getFullYear()}
) : (
{new Date(entity.opening_date).getFullYear()}
) ))}
); }