211 lines
8.8 KiB
TypeScript
211 lines
8.8 KiB
TypeScript
'use client'
|
|
|
|
import { motion } from 'framer-motion'
|
|
import Link from 'next/link'
|
|
import Image from 'next/image'
|
|
import { ArrowRight, Star } from 'lucide-react'
|
|
import { ShimmerButton } from '@/components/magicui/shimmer-button'
|
|
import { cn } from '@/components/common/Navbar'
|
|
|
|
const EASE = [0.22, 1, 0.36, 1] as const
|
|
|
|
const fadeInUp = {
|
|
hidden: { opacity: 0, y: 40, filter: 'blur(8px)' },
|
|
show: { opacity: 1, y: 0, filter: 'blur(0px)', transition: { duration: 0.8, ease: EASE } }
|
|
}
|
|
|
|
export function HomePageClient({
|
|
dict,
|
|
tours,
|
|
categories,
|
|
reviews
|
|
}: {
|
|
dict: any,
|
|
tours: any[],
|
|
categories: any[],
|
|
reviews: any[]
|
|
}) {
|
|
return (
|
|
<div className="bg-background min-h-screen">
|
|
{/* Hero Section */}
|
|
<section className="relative h-screen min-h-[700px] flex items-center justify-center overflow-hidden">
|
|
<motion.div
|
|
initial={{ scale: 1.1, opacity: 0 }}
|
|
animate={{ scale: 1, opacity: 1 }}
|
|
transition={{ duration: 1.5, ease: EASE }}
|
|
className="absolute inset-0"
|
|
>
|
|
<Image
|
|
src="https://images.unsplash.com/photo-1471922694854-ff1b63b20054?auto=format&fit=crop&q=80"
|
|
alt="Fethiye Hero"
|
|
fill
|
|
className="object-cover"
|
|
priority
|
|
sizes="100vw"
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-b from-background/40 via-background/20 to-background/90" />
|
|
</motion.div>
|
|
|
|
<div className="relative z-10 text-center px-4 max-w-5xl mx-auto flex flex-col items-center">
|
|
<motion.div
|
|
initial="hidden"
|
|
animate="show"
|
|
variants={{
|
|
hidden: { opacity: 0 },
|
|
show: { opacity: 1, transition: { staggerChildren: 0.2 } }
|
|
}}
|
|
>
|
|
<motion.h1
|
|
variants={fadeInUp}
|
|
className="font-heading text-hero text-foreground mb-6 leading-none drop-shadow-2xl"
|
|
>
|
|
{dict.hTitle}
|
|
</motion.h1>
|
|
<motion.p
|
|
variants={fadeInUp}
|
|
className="text-h3 text-foreground/80 mb-12 max-w-2xl mx-auto font-light tracking-wide"
|
|
>
|
|
{dict.hSubtitle}
|
|
</motion.p>
|
|
<motion.div variants={fadeInUp}>
|
|
<Link href="/tours">
|
|
<ShimmerButton
|
|
className="shadow-2xl"
|
|
shimmerColor="var(--primary)"
|
|
background="var(--background)"
|
|
borderRadius="10px"
|
|
>
|
|
<span className="font-bold tracking-widest uppercase text-sm text-foreground flex items-center gap-2">
|
|
{dict.hCta} <ArrowRight className="w-4 h-4 text-primary" />
|
|
</span>
|
|
</ShimmerButton>
|
|
</Link>
|
|
</motion.div>
|
|
</motion.div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Popular Tours Section */}
|
|
<section className="py-32 relative z-20">
|
|
<div className="container mx-auto px-6">
|
|
<motion.div
|
|
initial={{ opacity: 0, y: 40 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: '-100px' }}
|
|
transition={{ duration: 0.8, ease: EASE }}
|
|
className="flex flex-col md:flex-row justify-between items-end mb-16 gap-6"
|
|
>
|
|
<h2 className="font-heading text-h2 text-foreground max-w-md leading-tight">
|
|
{dict.sPopular}
|
|
</h2>
|
|
<Link href="/tours" className="group flex items-center gap-2 text-sm font-bold tracking-widest uppercase text-foreground hover:text-primary transition-colors">
|
|
{dict.sViewAll}
|
|
<ArrowRight className="w-4 h-4 group-hover:translate-x-1 transition-transform" />
|
|
</Link>
|
|
</motion.div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
|
{tours.slice(0, 4).map((tour, i) => (
|
|
<motion.div
|
|
key={tour.id}
|
|
initial={{ opacity: 0, y: 40 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true, margin: '-50px' }}
|
|
transition={{ duration: 0.8, ease: EASE, delay: i * 0.1 }}
|
|
className="group relative flex flex-col gap-4"
|
|
>
|
|
<Link href={`/tours/${tour.slug}`} className="relative h-[400px] overflow-hidden rounded-2xl">
|
|
<Image
|
|
src={tour.imageUrl || ''}
|
|
alt={tour.title}
|
|
fill
|
|
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 25vw"
|
|
className="object-cover transition-transform duration-700 ease-out group-hover:scale-105"
|
|
/>
|
|
<div className="absolute inset-0 bg-black/20 group-hover:bg-transparent transition-colors duration-500" />
|
|
</Link>
|
|
<div className="flex flex-col gap-2">
|
|
<h3 className="font-heading text-2xl font-bold text-foreground group-hover:text-primary transition-colors">{tour.title}</h3>
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-xs tracking-widest uppercase text-muted-foreground">{dict.tFrom}</span>
|
|
<span className="font-sans font-bold text-xl text-primary">${tour.price}</span>
|
|
</div>
|
|
</div>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Editorial Categories */}
|
|
<section className="py-32 bg-card/30 border-y border-border/30">
|
|
<div className="container mx-auto px-6">
|
|
<motion.h2
|
|
initial={{ opacity: 0, y: 40 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
className="font-heading text-h2 text-center text-foreground mb-20"
|
|
>
|
|
{dict.sCategories}
|
|
</motion.h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
{categories.slice(0, 3).map((cat, i) => (
|
|
<motion.div
|
|
key={cat.id}
|
|
initial={{ opacity: 0, y: 40 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.8, ease: EASE, delay: i * 0.1 }}
|
|
>
|
|
<Link href={`/tours?category=${cat.slug}`} className="group block relative h-[500px] overflow-hidden rounded-2xl">
|
|
<Image
|
|
src={cat.imageUrl || ''}
|
|
alt={cat.name}
|
|
fill
|
|
sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
|
|
className="object-cover transition-transform duration-700 ease-out group-hover:scale-105"
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-t from-background/90 via-background/20 to-transparent" />
|
|
<div className="absolute bottom-0 left-0 p-8 w-full flex items-end justify-between">
|
|
<h3 className="font-heading text-3xl font-bold text-foreground">{cat.name}</h3>
|
|
<div className="w-10 h-10 rounded-full bg-primary/20 backdrop-blur-md flex items-center justify-center group-hover:bg-primary transition-colors">
|
|
<ArrowRight className="w-5 h-5 text-foreground" />
|
|
</div>
|
|
</div>
|
|
</Link>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{/* Reviews Section */}
|
|
<section className="py-32">
|
|
<div className="container mx-auto px-6">
|
|
<h2 className="font-heading text-h2 text-center text-foreground mb-20">{dict.sReviews}</h2>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8">
|
|
{reviews.map((review, i) => (
|
|
<motion.div
|
|
key={review.id}
|
|
initial={{ opacity: 0, y: 40 }}
|
|
whileInView={{ opacity: 1, y: 0 }}
|
|
viewport={{ once: true }}
|
|
transition={{ duration: 0.8, ease: EASE, delay: i * 0.1 }}
|
|
className="bg-card/40 p-8 rounded-3xl border border-border/50 hover:border-primary/30 transition-colors"
|
|
>
|
|
<div className="flex text-primary mb-6">
|
|
{[...Array(review.rating)].map((_, j) => <Star key={j} className="w-4 h-4 fill-current mr-1" />)}
|
|
</div>
|
|
<p className="text-foreground/80 font-serif italic text-lg leading-relaxed mb-8">"{review.comment}"</p>
|
|
<div>
|
|
<div className="font-bold text-foreground text-sm tracking-widest uppercase">{review.authorName}</div>
|
|
</div>
|
|
</motion.div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
)
|
|
}
|