anatolian2/components/home/ExperienceGrid.tsx
Temmuz Aslan 591d878ac6 Initial commit: The Anatolian Edit website
Next.js 14 website with standalone output configured for Docker deployment.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:34:25 +03:00

219 lines
9.8 KiB
TypeScript

"use client";
import { motion, useInView } from "framer-motion";
import { useRef } from "react";
import Image from "next/image";
import Link from "next/link";
import { experiences } from "@/lib/constants";
import { SectionHeader } from "@/components/shared/SectionHeader";
import { Button } from "@/components/shared/Button";
function ExperienceCard({
experience,
index,
featured = false,
}: {
experience: (typeof experiences)[0];
index: number;
featured?: boolean;
}) {
const ref = useRef(null);
const isInView = useInView(ref, { once: true, margin: "-50px" });
if (featured) {
return (
<motion.div
ref={ref}
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ delay: 0.1, duration: 0.6 }}
className="col-span-full"
>
<Link href={`/experiences/${experience.slug}`} className="group block">
<div className="relative bg-white rounded-3xl overflow-hidden shadow-lg hover:shadow-xl transition-shadow">
<div className="grid grid-cols-1 lg:grid-cols-2">
<div className="relative aspect-[4/3] lg:aspect-auto">
<Image
src={experience.image}
alt={`${experience.name}${experience.hook}`}
fill
className="object-cover group-hover:scale-105 transition-transform duration-700"
sizes="(max-width: 1024px) 100vw, 50vw"
/>
<div
className="absolute -top-1 -left-1 bg-sun-yolk text-deep-nazar px-5 py-2 rounded-br-2xl rounded-tl-3xl text-xs font-bold uppercase tracking-wide"
style={{ boxShadow: "0 4px 14px rgba(0,0,0,0.15), 0 1px 4px rgba(0,0,0,0.1)" }}
>
Popular Sells out 3 days in advance
</div>
</div>
<div className="p-8 lg:p-12 flex flex-col justify-center">
<p className="text-bosphorus font-semibold text-sm tracking-widest uppercase mb-2">
{experience.tagline}
</p>
<h3 className="font-display text-3xl md:text-4xl font-bold text-deep-nazar mb-4">
{experience.name}
</h3>
<p className="text-deep-nazar/70 text-lg leading-relaxed mb-6">
{experience.hook}
</p>
<div className="flex flex-wrap gap-2.5 mb-6">
{experience.highlights.map((h, i) => (
<span
key={i}
className="inline-flex items-center gap-1.5 bg-warm-sand rounded-full px-3 py-1.5 text-sm text-deep-nazar"
>
<span>{h.icon}</span>
{h.text}
</span>
))}
</div>
<div className="flex items-center justify-between pt-6 border-t border-deep-nazar/10">
<div className="flex flex-col">
<div className="flex items-center gap-4 text-sm text-deep-nazar/50 mb-1">
<span className="inline-flex items-center gap-1">
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
{experience.duration}
</span>
<span className="inline-flex items-center gap-1">
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" /></svg>
{experience.groupSize}
</span>
</div>
<div>
<span className="text-sm text-deep-nazar/60">From</span>
<span className="text-3xl font-bold text-deep-nazar ml-2">
{experience.price}
</span>
<span className="text-deep-nazar/60">/person</span>
</div>
</div>
<span className="px-6 py-3 bg-coral-spritz text-white font-semibold rounded-full shadow-lg shadow-coral-spritz/25 group-hover:shadow-xl transition-shadow">
Book Now
</span>
</div>
</div>
</div>
</div>
</Link>
</motion.div>
);
}
return (
<motion.div
ref={ref}
initial={{ opacity: 0, y: 30 }}
animate={isInView ? { opacity: 1, y: 0 } : {}}
transition={{ delay: index * 0.1, duration: 0.6 }}
>
<Link href={`/experiences/${experience.slug}`} className="group block h-full">
<div className="bg-white rounded-3xl overflow-hidden shadow-md hover:shadow-lg transition-all h-full flex flex-col">
<div className="relative aspect-[4/3] overflow-hidden">
<Image
src={experience.image}
alt={`${experience.name}${experience.hook}`}
fill
className="object-cover group-hover:scale-105 transition-transform duration-700"
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
/>
</div>
<div className="p-6 flex flex-col flex-1">
<p className="text-bosphorus font-semibold text-xs tracking-widest uppercase mb-1">
{experience.tagline}
</p>
<h3 className="font-display text-xl font-bold text-deep-nazar mb-2">
{experience.name}
</h3>
<p className="text-deep-nazar/70 text-sm leading-relaxed mb-4">
{experience.hook}
</p>
<div className="flex flex-wrap gap-2 mb-4">
{experience.highlights.slice(0, 3).map((h, i) => (
<span
key={i}
className="inline-flex items-center gap-1 bg-warm-sand rounded-full px-2.5 py-1 text-xs text-deep-nazar"
>
<span>{h.icon}</span>
{h.text}
</span>
))}
</div>
<div className="flex items-center gap-4 mb-4 text-xs text-deep-nazar/50">
<span className="inline-flex items-center gap-1">
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
{experience.duration}
</span>
<span className="inline-flex items-center gap-1">
<svg className="w-3 h-3" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0z" /></svg>
{experience.groupSize}
</span>
</div>
<div className="flex items-center justify-between pt-4 border-t border-deep-nazar/10 mt-auto">
<div>
<span className="text-xs text-deep-nazar/60">From </span>
<span className="text-xl font-bold text-deep-nazar">
{experience.price}
</span>
</div>
<span className="px-4 py-2 border-2 border-coral-spritz text-coral-spritz font-semibold text-sm rounded-full group-hover:bg-coral-spritz group-hover:text-white transition-colors">
Book Now
</span>
</div>
</div>
</div>
</Link>
</motion.div>
);
}
export function ExperienceGrid() {
const featured = experiences.find((e) => e.featured);
const others = experiences.filter((e) => !e.featured);
return (
<section id="experiences" className="py-20 md:py-32 section-padding">
<div className="max-w-7xl mx-auto">
<SectionHeader
eyebrow="Experiences"
title="Choose Your Edit"
subtitle="Every experience is handcrafted, small-group, and designed around the places we'd take our own friends."
/>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{featured && <ExperienceCard experience={featured} index={0} featured />}
{others.map((exp, i) => (
<ExperienceCard key={exp.slug} experience={exp} index={i + 1} />
))}
</div>
<motion.div
className="mt-16 bg-gradient-to-r from-deep-nazar to-deep-nazar/90 rounded-3xl p-8 md:p-12 text-white text-center"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true }}
>
<h3 className="font-display text-2xl md:text-3xl font-bold mb-3">
Private Editions
</h3>
<p className="text-white/80 text-lg mb-6 max-w-2xl mx-auto">
Want The Anatolian Edit all to yourself? Every experience is
available as a private edition for couples, families, or groups of up
to 12.
</p>
<div className="flex flex-col sm:flex-row items-center justify-center gap-4">
<Button href="/contact" variant="coral" size="lg">
Inquire About Private Experiences
</Button>
<span className="text-white/60 text-sm">Starting from 250</span>
</div>
</motion.div>
</div>
</section>
);
}