diff --git a/src/components/homepage/ContentTabs.tsx b/src/components/homepage/ContentTabs.tsx new file mode 100644 index 00000000..9188e775 --- /dev/null +++ b/src/components/homepage/ContentTabs.tsx @@ -0,0 +1,252 @@ +import { useState, useEffect } from 'react'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; +import { ParkCard } from '@/components/parks/ParkCard'; +import { Card, CardContent } from '@/components/ui/card'; +import { Star, TrendingUp, Plus, MapPin } from 'lucide-react'; +import { Park, Ride } from '@/types/database'; +import { supabase } from '@/integrations/supabase/client'; + +export function ContentTabs() { + const [popularParks, setPopularParks] = useState([]); + const [trendingParks, setTrendingParks] = useState([]); + const [popularRides, setPopularRides] = useState([]); + const [trendingRides, setTrendingRides] = useState([]); + const [recentParks, setRecentParks] = useState([]); + const [recentRides, setRecentRides] = useState([]); + const [loading, setLoading] = useState(true); + + useEffect(() => { + fetchContent(); + }, []); + + const fetchContent = async () => { + try { + // Most Popular Parks (by rating) + const { data: popular } = await supabase + .from('parks') + .select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`) + .order('average_rating', { ascending: false }) + .limit(6); + + // Trending Parks (by review count) + const { data: trending } = await supabase + .from('parks') + .select(`*, location:locations(*), operator:companies!parks_operator_id_fkey(*)`) + .order('review_count', { ascending: false }) + .limit(6); + + // 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(6); + + // Popular Rides (by rating) + const { data: popularRidesData } = await supabase + .from('rides') + .select(`*, park:parks!inner(name, slug, location:locations(*))`) + .order('average_rating', { ascending: false }) + .limit(8); + + // Trending Rides (by review count) + const { data: trendingRidesData } = await supabase + .from('rides') + .select(`*, park:parks!inner(name, slug, location:locations(*))`) + .order('review_count', { ascending: false }) + .limit(8); + + // Recently Added Rides + const { data: recentRidesData } = await supabase + .from('rides') + .select(`*, park:parks!inner(name, slug, location:locations(*))`) + .order('created_at', { ascending: false }) + .limit(8); + + setPopularParks(popular || []); + setTrendingParks(trending || []); + setRecentParks(recent || []); + setPopularRides(popularRidesData || []); + setTrendingRides(trendingRidesData || []); + setRecentRides(recentRidesData || []); + } catch (error) { + console.error('Error fetching content:', error); + } finally { + setLoading(false); + } + }; + + const RideCard = ({ ride }: { ride: Ride }) => ( + + +
+
+
+

+ {ride.name} +

+

+ at {ride.park?.name} +

+
+
+ {ride.category === 'roller_coaster' ? '🎢' : + ride.category === 'water_ride' ? '🌊' : + ride.category === 'dark_ride' ? '🎭' : '🎡'} +
+
+ + {ride.description && ( +

+ {ride.description} +

+ )} + +
+
+ {ride.max_speed_kmh && ( + {ride.max_speed_kmh} km/h + )} + {ride.max_height_meters && ( + {ride.max_height_meters}m + )} +
+ + {ride.average_rating > 0 && ( +
+ + {ride.average_rating.toFixed(1)} +
+ )} +
+
+
+
+ ); + + if (loading) { + return ( +
+
+
+
+
+ {[...Array(6)].map((_, i) => ( +
+ ))} +
+
+
+
+ ); + } + + return ( +
+
+ +
+ + + + Popular Parks + + + + Trending Parks + + + + Popular Rides + + + + Trending Rides + + + + New Parks + + + + New Rides + + +
+ + +
+

Most Popular Parks

+

Highest rated theme parks worldwide

+
+
+ {popularParks.map((park) => ( + + ))} +
+
+ + +
+

Trending Parks

+

Most reviewed parks this month

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

Most Popular Rides

+

Highest rated attractions worldwide

+
+
+ {popularRides.map((ride) => ( + + ))} +
+
+ + +
+

Trending Rides

+

Most talked about attractions

+
+
+ {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) => ( + + ))} +
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/components/homepage/SimpleHeroSearch.tsx b/src/components/homepage/SimpleHeroSearch.tsx new file mode 100644 index 00000000..4e0d9835 --- /dev/null +++ b/src/components/homepage/SimpleHeroSearch.tsx @@ -0,0 +1,50 @@ +import { useState } from 'react'; +import { Search } from 'lucide-react'; +import { Input } from '@/components/ui/input'; +import { Button } from '@/components/ui/button'; + +export function SimpleHeroSearch() { + const [searchTerm, setSearchTerm] = useState(''); + + const handleSearch = () => { + console.log('Searching for:', searchTerm); + }; + + return ( +
+
+
+

+ + ThrillWiki + +

+ +

+ The ultimate theme park database. Discover parks, track rides, and connect with enthusiasts. +

+ + {/* Simple Search */} +
+
+ + setSearchTerm(e.target.value)} + className="pl-12 pr-24 h-14 text-lg bg-background border-border rounded-full shadow-lg" + onKeyDown={(e) => e.key === 'Enter' && handleSearch()} + /> + +
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index f99ded6a..278f66d8 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,206 +1,13 @@ import { Header } from '@/components/layout/Header'; -import { ParkGrid } from '@/components/parks/ParkGrid'; -import { FeaturedParks } from '@/components/homepage/FeaturedParks'; -import { QuickActions } from '@/components/homepage/QuickActions'; -import { HeroSearch } from '@/components/homepage/HeroSearch'; -import { Button } from '@/components/ui/button'; -import { Badge } from '@/components/ui/badge'; -import { Zap, MapPin, Star, TrendingUp, Users, Globe, Award } from 'lucide-react'; +import { SimpleHeroSearch } from '@/components/homepage/SimpleHeroSearch'; +import { ContentTabs } from '@/components/homepage/ContentTabs'; const Index = () => { return (
- - {/* Enhanced Hero Section */} -
- {/* Animated Background */} -
-
- {/* Floating Elements */} -
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
- - - Beta Version - - - - Community Driven - - - - Worldwide - -
- -

- Discover -
- - Epic Thrills - -

- -

- The ultimate theme park database. Discover amazing parks, track your ride credits, - share reviews, and connect with fellow thrill seekers worldwide. -

- - {/* Enhanced Search Component */} -
- -
- - {/* Quick CTA Buttons */} -
- - -
-
-
-
- - {/* Quick Actions */} - - - {/* Featured Parks */} - - - {/* Features Section */} -
-
-
-

- Everything for Your - Thrill Journey -

-

- From park discovery to ride tracking, ThrillWiki has all the tools enthusiasts need. -

-
- -
-
-
- -
-

Discover Parks

-

- Explore thousands of theme parks worldwide with detailed information, photos, and authentic reviews from fellow enthusiasts. -

- -
- -
-
- -
-

Track Credits

-

- Keep track of every ride you've experienced and build your personal coaster portfolio with detailed statistics. -

- -
- -
-
- -
-

Join Community

-

- Share reviews, create top lists, and connect with thousands of passionate theme park enthusiasts. -

- -
-
-
-
- - {/* All Parks Section */} -
-
-
-

- Browse All - Parks -

-

- Discover every park in our comprehensive database -

-
-
- -
- - {/* Final CTA Section */} -
-
-
-
- - - Free Forever - - - - No Ads - -
- -

- Ready for Your Next -
- - Thrill Adventure? - -

- -

- Join thousands of theme park enthusiasts and start tracking your rides today! - Completely free, no ads, just pure passion for thrills. -

- -
- - -
-
-
-
+ +
); }; diff --git a/src/types/database.ts b/src/types/database.ts index b6478741..f33fe4d3 100644 --- a/src/types/database.ts +++ b/src/types/database.ts @@ -63,12 +63,12 @@ export interface Ride { name: string; slug: string; description?: string; - park?: Park; + park?: Park | { name: string; slug: string; location?: Location }; // Allow partial park data ride_model?: RideModel; manufacturer?: Company; designer?: Company; - category: 'roller_coaster' | 'flat_ride' | 'water_ride' | 'dark_ride' | 'kiddie_ride' | 'transportation'; - status: 'operating' | 'closed' | 'under_construction' | 'maintenance' | 'sbno'; + category: string; // Allow any string from database + status: string; // Allow any string from database opening_date?: string; closing_date?: string; height_requirement?: number;