feat: add project files
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function About({ dict }: { dict: any }) {
|
||||
const stats = [
|
||||
{ value: "5+", label: dict.about.stats.years },
|
||||
{ value: "10K+", label: dict.about.stats.guests },
|
||||
{ value: "4.8★", label: dict.about.stats.rating },
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="about" className="py-24 bg-sand-light text-sea-dark overflow-hidden">
|
||||
<div className="container mx-auto px-6 max-w-6xl">
|
||||
<div className="grid md:grid-cols-2 gap-16 items-center">
|
||||
|
||||
{/* Text side */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: -50 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
transition={{ duration: 0.8 }}
|
||||
className="space-y-6"
|
||||
>
|
||||
{/* Label with decorative lines */}
|
||||
<div className="flex items-center gap-3">
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
<h2 className="text-sm font-bold tracking-widest uppercase text-coral">{dict.about.title}</h2>
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
</div>
|
||||
|
||||
<h3 className="text-4xl md:text-5xl font-serif leading-tight" dangerouslySetInnerHTML={{ __html: dict.about.heading }}></h3>
|
||||
|
||||
<p className="text-base opacity-75 leading-relaxed">
|
||||
{dict.about.p1}
|
||||
</p>
|
||||
<p className="text-base opacity-75 leading-relaxed">
|
||||
{dict.about.p2}
|
||||
</p>
|
||||
|
||||
{/* Stats row */}
|
||||
<div className="grid grid-cols-3 gap-6 pt-6 border-t border-sand-dark/40">
|
||||
{stats.map((stat) => (
|
||||
<div key={stat.label} className="text-center">
|
||||
<div className="text-2xl md:text-3xl font-serif font-bold text-sea-dark">{stat.value}</div>
|
||||
<div className="text-xs text-gray-500 uppercase tracking-wide mt-1">{stat.label}</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
{/* Image side */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, x: 50 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true, margin: "-100px" }}
|
||||
transition={{ duration: 0.8, delay: 0.2 }}
|
||||
className="relative h-[520px] w-full"
|
||||
>
|
||||
{/* Shadow shape behind */}
|
||||
<div className="absolute inset-0 bg-sand-dark/25 rounded-t-full rounded-br-full transform translate-x-5 translate-y-5" />
|
||||
{/* Image clipped to shape */}
|
||||
<div className="absolute inset-0 rounded-t-full rounded-br-full overflow-hidden shadow-2xl">
|
||||
<Image
|
||||
src="/moy-beach.jpg"
|
||||
alt="Moy Beach Atmosphere"
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 768px) 100vw, 50vw"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
"use client";
|
||||
|
||||
import { MapPin, Phone, Mail, Clock } from "lucide-react";
|
||||
|
||||
export default function Contact({ dict }: { dict: any }) {
|
||||
return (
|
||||
<section id="contact" className="py-24 bg-sand-light text-sea-dark relative">
|
||||
<div className="container mx-auto px-6 max-w-7xl">
|
||||
<div className="text-center mb-16">
|
||||
<h2 className="text-sm font-bold tracking-widest uppercase text-coral mb-4">{dict.contact.title}</h2>
|
||||
<h3 className="text-4xl md:text-5xl font-serif">{dict.contact.heading}</h3>
|
||||
</div>
|
||||
|
||||
<div className="grid lg:grid-cols-2 gap-12 items-start">
|
||||
|
||||
{/* İletişim Bilgileri */}
|
||||
<div className="space-y-8">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center shrink-0 shadow-md">
|
||||
<MapPin className="text-coral w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-xl mb-2 font-serif">{dict.contact.address.title}</h4>
|
||||
<p className="text-gray-600 leading-relaxed">
|
||||
{dict.contact.address.text1}<br />
|
||||
{dict.contact.address.text2}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center shrink-0 shadow-md">
|
||||
<Phone className="text-coral w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-xl mb-2 font-serif">{dict.contact.phone}</h4>
|
||||
<p className="text-gray-600">
|
||||
<a href="tel:+905344656235" className="hover:text-coral transition-colors">+90 534 465 62 35</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center shrink-0 shadow-md">
|
||||
<Mail className="text-coral w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-xl mb-2 font-serif">{dict.contact.email}</h4>
|
||||
<p className="text-gray-600">
|
||||
<a href="mailto:info@moybeachakyaka.com" className="hover:text-coral transition-colors">info@moybeachakyaka.com</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="w-12 h-12 bg-white rounded-full flex items-center justify-center shrink-0 shadow-md">
|
||||
<Clock className="text-coral w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 className="font-bold text-xl mb-2 font-serif">{dict.contact.hours.title}</h4>
|
||||
<p className="text-gray-600">
|
||||
{dict.contact.hours.text}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Google Maps Embed */}
|
||||
<div className="w-full h-[400px] lg:h-full min-h-[400px] bg-gray-200 rounded-2xl overflow-hidden shadow-lg border-4 border-white">
|
||||
<iframe
|
||||
src="https://maps.google.com/maps?hl=tr&gl=TR&cid=17585469489776666725&output=embed"
|
||||
width="100%"
|
||||
height="100%"
|
||||
style={{ border: 0 }}
|
||||
allowFullScreen={false}
|
||||
loading="lazy"
|
||||
referrerPolicy="no-referrer-when-downgrade"
|
||||
title="Moy Beach Konum"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
"use client";
|
||||
|
||||
const socials = [
|
||||
{
|
||||
label: "Instagram",
|
||||
href: "https://instagram.com/moybeachakyaka",
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} className="w-5 h-5">
|
||||
<rect x="2" y="2" width="20" height="20" rx="5" ry="5" />
|
||||
<circle cx="12" cy="12" r="4" />
|
||||
<circle cx="17.5" cy="6.5" r="0.5" fill="currentColor" stroke="none" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "Facebook",
|
||||
href: "https://facebook.com/moybeachakyaka",
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" className="w-5 h-5">
|
||||
<path d="M18 2h-3a5 5 0 0 0-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 0 1 1-1h3z" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
label: "YouTube",
|
||||
href: "https://youtube.com/@moybeach",
|
||||
icon: (
|
||||
<svg viewBox="0 0 24 24" fill="currentColor" className="w-5 h-5">
|
||||
<path d="M22.54 6.42a2.78 2.78 0 0 0-1.95-1.96C18.88 4 12 4 12 4s-6.88 0-8.59.46A2.78 2.78 0 0 0 1.46 6.42 29 29 0 0 0 1 12a29 29 0 0 0 .46 5.58 2.78 2.78 0 0 0 1.95 1.96C5.12 20 12 20 12 20s6.88 0 8.59-.46a2.78 2.78 0 0 0 1.96-1.96A29 29 0 0 0 23 12a29 29 0 0 0-.46-5.58z" />
|
||||
<polygon points="9.75 15.02 15.5 12 9.75 8.98 9.75 15.02" fill="white" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
];
|
||||
|
||||
export default function Footer({ dict }: { dict: any }) {
|
||||
const links = [
|
||||
{ label: dict.nav.about, href: "#about" },
|
||||
{ label: dict.nav.services, href: "#services" },
|
||||
{ label: dict.nav.gallery, href: "#gallery" },
|
||||
{ label: dict.nav.contact, href: "#contact" },
|
||||
];
|
||||
|
||||
return (
|
||||
<footer className="relative bg-sea-dark text-sand-light overflow-hidden">
|
||||
|
||||
{/* Large decorative brand name — background texture */}
|
||||
<div className="absolute inset-x-0 top-0 flex items-start justify-center pointer-events-none select-none overflow-hidden">
|
||||
<span className="text-[clamp(6rem,20vw,18rem)] font-serif text-white/[0.03] leading-none tracking-tight whitespace-nowrap">
|
||||
MOY BEACH
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div className="relative z-10">
|
||||
|
||||
{/* Top section */}
|
||||
<div className="container mx-auto px-6 max-w-6xl pt-20 pb-14">
|
||||
<div className="grid md:grid-cols-3 gap-12 items-start">
|
||||
|
||||
{/* Brand column */}
|
||||
<div className="md:col-span-1">
|
||||
<p className="text-2xl md:text-3xl font-serif text-white tracking-wide mb-3">MOY BEACH</p>
|
||||
<p className="text-xs uppercase tracking-[0.3em] text-coral mb-6">Akyaka · Muğla</p>
|
||||
<p className="text-sm text-sand-light/60 leading-relaxed mb-8">
|
||||
{dict.footer.desc}
|
||||
</p>
|
||||
|
||||
{/* Social icons */}
|
||||
<div className="flex gap-3">
|
||||
{socials.map((s) => (
|
||||
<a
|
||||
key={s.label}
|
||||
href={s.href}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
aria-label={s.label}
|
||||
className="w-10 h-10 rounded-full border border-white/10 flex items-center justify-center text-sand-light/60 hover:text-white hover:border-coral hover:bg-coral/10 transition-all duration-300"
|
||||
>
|
||||
{s.icon}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Navigation column */}
|
||||
<div>
|
||||
<h4 className="text-[11px] uppercase tracking-[0.25em] text-sand-dark mb-5">{dict.footer.pages}</h4>
|
||||
<ul className="space-y-3">
|
||||
{links.map((l) => (
|
||||
<li key={l.label}>
|
||||
<a
|
||||
href={l.href}
|
||||
className="text-sm text-sand-light/65 hover:text-white transition-colors duration-200 flex items-center gap-2 group"
|
||||
>
|
||||
<span className="w-0 group-hover:w-3 h-px bg-coral transition-all duration-300 shrink-0" />
|
||||
{l.label}
|
||||
</a>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Contact column */}
|
||||
<div>
|
||||
<h4 className="text-[11px] uppercase tracking-[0.25em] text-sand-dark mb-5">{dict.footer.contact}</h4>
|
||||
<ul className="space-y-4 text-sm text-sand-light/65">
|
||||
<li className="leading-relaxed">
|
||||
{dict.contact.address.text1}<br />
|
||||
{dict.contact.address.text2}
|
||||
</li>
|
||||
<li>
|
||||
<a href="tel:+905344656235" className="hover:text-white transition-colors">
|
||||
+90 534 465 62 35
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="mailto:info@moybeachakyaka.com" className="hover:text-white transition-colors">
|
||||
info@moybeachakyaka.com
|
||||
</a>
|
||||
</li>
|
||||
<li className="text-sand-light/45">{dict.contact.hours.text}</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Divider */}
|
||||
<div className="border-t border-white/[0.07]" />
|
||||
|
||||
{/* Bottom bar */}
|
||||
<div className="container mx-auto px-6 max-w-6xl py-6 flex flex-col sm:flex-row justify-between items-center gap-3 text-[11px] text-sand-light/35">
|
||||
<p>© {new Date().getFullYear()} {dict.footer.rights}</p>
|
||||
<div className="flex items-center gap-4">
|
||||
<span>{dict.footer.created_by}</span>
|
||||
<a
|
||||
href="https://ayris.tech"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="hover:text-sand-light/70 transition-colors underline underline-offset-4"
|
||||
>
|
||||
ayris.tech
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{/* Floating WhatsApp Button */}
|
||||
<a
|
||||
href="https://wa.me/905344656235"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="fixed bottom-6 right-6 z-50 bg-[#25D366] text-white p-3.5 rounded-full shadow-xl hover:scale-110 transition-transform"
|
||||
aria-label="WhatsApp ile iletişime geçin"
|
||||
>
|
||||
<svg viewBox="0 0 24 24" className="w-6 h-6 fill-current">
|
||||
<path d="M17.472 14.382c-.297-.149-1.758-.867-2.03-.967-.273-.099-.471-.148-.67.15-.197.297-.767.966-.94 1.164-.173.199-.347.223-.644.075-.297-.15-1.255-.463-2.39-1.475-.883-.788-1.48-1.761-1.653-2.059-.173-.297-.018-.458.13-.606.134-.133.298-.347.446-.52.149-.174.198-.298.298-.497.099-.198.05-.371-.025-.52-.075-.149-.669-1.612-.916-2.207-.242-.579-.487-.5-.669-.51a12.8 12.8 0 0 0-.57-.01c-.198 0-.52.074-.792.372-.272.297-1.04 1.016-1.04 2.479 0 1.462 1.065 2.875 1.213 3.074.149.198 2.096 3.2 5.077 4.487.709.306 1.262.489 1.694.625.712.227 1.36.195 1.871.118.571-.085 1.758-.719 2.006-1.413.248-.694.248-1.289.173-1.413-.074-.124-.272-.198-.57-.347m-5.421 7.403h-.004a9.87 9.87 0 0 1-5.031-1.378l-.361-.214-3.741.982.998-3.648-.235-.374a9.86 9.86 0 0 1-1.51-5.26c.001-5.45 4.436-9.884 9.888-9.884 2.64 0 5.122 1.03 6.988 2.898a9.825 9.825 0 0 1 2.893 6.994c-.003 5.45-4.437 9.884-9.885 9.884m8.413-18.297A11.815 11.815 0 0 0 12.05 0C5.495 0 .16 5.335.157 11.892c0 2.096.547 4.142 1.588 5.945L.057 24l6.305-1.654a11.882 11.882 0 0 0 5.683 1.448h.005c6.554 0 11.89-5.335 11.893-11.893a11.821 11.821 0 0 0-3.48-8.413Z" />
|
||||
</svg>
|
||||
</a>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,136 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import { X, ZoomIn } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
|
||||
const photos = [
|
||||
{ id: 1, categoryKey: "beach", url: "https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&q=80&w=1200" },
|
||||
{ id: 2, categoryKey: "rooms", url: "https://images.unsplash.com/photo-1611892440504-42a792e24d32?auto=format&fit=crop&q=80&w=1200" },
|
||||
{ id: 3, categoryKey: "restaurant", url: "https://images.unsplash.com/photo-1414235077428-338989a2e8c0?auto=format&fit=crop&q=80&w=1200" },
|
||||
{ id: 4, categoryKey: "beach", url: "https://images.unsplash.com/photo-1519046904884-53103b34b206?auto=format&fit=crop&q=80&w=1200" },
|
||||
{ id: 5, categoryKey: "events", url: "https://images.unsplash.com/photo-1511285560929-80b456fea0bc?auto=format&fit=crop&q=80&w=1200" },
|
||||
{ id: 6, categoryKey: "restaurant", url: "https://images.unsplash.com/photo-1555396273-367ea4eb4db5?auto=format&fit=crop&q=80&w=1200" },
|
||||
];
|
||||
|
||||
export default function Gallery({ dict }: { dict: any }) {
|
||||
const categories = [
|
||||
{ key: "all", label: dict.gallery.categories.all },
|
||||
{ key: "beach", label: dict.gallery.categories.beach },
|
||||
{ key: "restaurant", label: dict.gallery.categories.restaurant },
|
||||
{ key: "rooms", label: dict.gallery.categories.rooms },
|
||||
{ key: "events", label: dict.gallery.categories.events }
|
||||
];
|
||||
|
||||
const [activeCategoryKey, setActiveCategoryKey] = useState("all");
|
||||
const [selectedImage, setSelectedImage] = useState<string | null>(null);
|
||||
|
||||
const filteredPhotos =
|
||||
activeCategoryKey === "all"
|
||||
? photos
|
||||
: photos.filter((p) => p.categoryKey === activeCategoryKey);
|
||||
|
||||
return (
|
||||
<section id="gallery" className="py-24 bg-sand-light text-sea-dark">
|
||||
<div className="container mx-auto px-6 max-w-7xl">
|
||||
|
||||
<div className="text-center mb-12">
|
||||
<div className="flex items-center justify-center gap-3 mb-4">
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
<h2 className="text-sm font-bold tracking-widest uppercase text-coral">{dict.gallery.title}</h2>
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
</div>
|
||||
<h3 className="text-4xl md:text-5xl font-serif mb-10">{dict.gallery.heading}</h3>
|
||||
|
||||
{/* Category filters */}
|
||||
<div className="flex flex-wrap justify-center gap-3 mb-12">
|
||||
{categories.map((cat) => (
|
||||
<button
|
||||
key={cat.key}
|
||||
onClick={() => setActiveCategoryKey(cat.key)}
|
||||
className={`px-5 py-2 rounded-full text-xs tracking-widest uppercase font-medium transition-all duration-300 ${
|
||||
activeCategoryKey === cat.key
|
||||
? "bg-sea-dark text-white shadow-md"
|
||||
: "bg-white text-sea-dark border border-sand-dark/30 hover:border-sea-dark hover:bg-sea-dark/5"
|
||||
}`}
|
||||
>
|
||||
{cat.label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<motion.div layout className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
|
||||
<AnimatePresence mode="popLayout">
|
||||
{filteredPhotos.map((photo) => (
|
||||
<motion.div
|
||||
key={photo.id}
|
||||
layout
|
||||
initial={{ opacity: 0, scale: 0.92 }}
|
||||
animate={{ opacity: 1, scale: 1 }}
|
||||
exit={{ opacity: 0, scale: 0.92 }}
|
||||
transition={{ duration: 0.3 }}
|
||||
className="relative h-72 cursor-pointer overflow-hidden rounded-2xl group shadow-sm hover:shadow-lg hover:shadow-sea-dark/10 transition-shadow duration-500"
|
||||
onClick={() => setSelectedImage(photo.url)}
|
||||
>
|
||||
<Image
|
||||
src={photo.url}
|
||||
alt={dict.gallery.categories[photo.categoryKey]}
|
||||
fill
|
||||
className="object-cover transform group-hover:scale-108 transition-transform duration-700"
|
||||
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
|
||||
style={{ transform: "scale(1)", transition: "transform 700ms" }}
|
||||
/>
|
||||
{/* Hover overlay */}
|
||||
<div className="absolute inset-0 bg-sea-dark/40 opacity-0 group-hover:opacity-100 transition-opacity duration-300 z-10 flex items-center justify-center">
|
||||
<div className="flex flex-col items-center gap-2 text-white">
|
||||
<ZoomIn size={28} />
|
||||
<span className="text-[10px] uppercase tracking-[0.25em]">{dict.gallery.categories[photo.categoryKey]}</span>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</AnimatePresence>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Lightbox */}
|
||||
<AnimatePresence>
|
||||
{selectedImage && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
className="fixed inset-0 z-[100] bg-black/92 flex items-center justify-center p-4"
|
||||
onClick={() => setSelectedImage(null)}
|
||||
>
|
||||
<button
|
||||
className="absolute top-6 right-6 text-white/70 hover:text-white transition-colors bg-white/10 hover:bg-white/20 p-2.5 rounded-full backdrop-blur-sm"
|
||||
onClick={() => setSelectedImage(null)}
|
||||
aria-label="Kapat"
|
||||
>
|
||||
<X size={20} />
|
||||
</button>
|
||||
<motion.div
|
||||
initial={{ scale: 0.88, opacity: 0 }}
|
||||
animate={{ scale: 1, opacity: 1 }}
|
||||
exit={{ scale: 0.88, opacity: 0 }}
|
||||
transition={{ duration: 0.25, ease: [0.22, 1, 0.36, 1] }}
|
||||
className="relative max-w-4xl max-h-[88vh] w-full h-full"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
<Image
|
||||
src={selectedImage}
|
||||
alt="Büyütülmüş Görsel"
|
||||
fill
|
||||
className="object-contain rounded-lg"
|
||||
sizes="100vw"
|
||||
/>
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
"use client";
|
||||
|
||||
import { useState, useEffect } from "react";
|
||||
import { Menu, X } from "lucide-react";
|
||||
|
||||
export default function Header({ dict, lang }: { dict: any, lang: string }) {
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 50);
|
||||
};
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
const navLinks = [
|
||||
{ name: dict.nav.about, href: "#about" },
|
||||
{ name: dict.nav.services, href: "#services" },
|
||||
{ name: dict.nav.gallery, href: "#gallery" },
|
||||
{ name: dict.nav.contact, href: "#contact" },
|
||||
];
|
||||
|
||||
return (
|
||||
<header
|
||||
className={`fixed top-0 w-full z-50 transition-all duration-300 ${
|
||||
isScrolled ? "bg-white/95 backdrop-blur-md shadow-sm py-4" : "bg-transparent py-6"
|
||||
}`}
|
||||
>
|
||||
<div className="container mx-auto px-4 md:px-6 flex justify-between items-center">
|
||||
<a href="#" className="flex items-center">
|
||||
<img
|
||||
src="/logo.png"
|
||||
alt="Moy Beach Logo"
|
||||
className={`h-12 w-auto transition-all duration-300 ${!isScrolled ? "brightness-0 invert opacity-90" : ""}`}
|
||||
/>
|
||||
</a>
|
||||
|
||||
{/* Desktop Nav */}
|
||||
<nav className="hidden md:flex items-center space-x-8">
|
||||
{navLinks.map((link) => (
|
||||
<a
|
||||
key={link.name}
|
||||
href={link.href}
|
||||
className={`text-sm tracking-wide hover:text-coral transition-colors ${
|
||||
isScrolled ? "text-sea-dark" : "text-white"
|
||||
}`}
|
||||
>
|
||||
{link.name}
|
||||
</a>
|
||||
))}
|
||||
<div className={`flex items-center gap-2 text-sm font-medium ${isScrolled ? "text-sea-dark" : "text-white"}`}>
|
||||
<a href="/tr" className={`cursor-pointer hover:text-coral ${lang === 'tr' ? 'opacity-100 font-bold' : 'opacity-70'}`}>TR</a>
|
||||
<span className="opacity-50">/</span>
|
||||
<a href="/en" className={`cursor-pointer hover:text-coral ${lang === 'en' ? 'opacity-100 font-bold' : 'opacity-70'}`}>EN</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{/* Mobile Menu Toggle */}
|
||||
<button
|
||||
className="md:hidden"
|
||||
onClick={() => setMobileMenuOpen(!mobileMenuOpen)}
|
||||
>
|
||||
{mobileMenuOpen ? (
|
||||
<X className={isScrolled ? "text-sea-dark" : "text-white"} />
|
||||
) : (
|
||||
<Menu className={isScrolled ? "text-sea-dark" : "text-white"} />
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Nav */}
|
||||
{mobileMenuOpen && (
|
||||
<div className="md:hidden absolute top-full left-0 w-full bg-white shadow-xl flex flex-col py-4 px-6 space-y-4">
|
||||
{navLinks.map((link) => (
|
||||
<a
|
||||
key={link.name}
|
||||
href={link.href}
|
||||
className="text-sea-dark text-lg py-2 border-b border-gray-100"
|
||||
onClick={() => setMobileMenuOpen(false)}
|
||||
>
|
||||
{link.name}
|
||||
</a>
|
||||
))}
|
||||
<div className="flex gap-4 pt-2">
|
||||
<a href="/tr" className={`font-medium cursor-pointer ${lang === 'tr' ? 'text-sea-dark font-bold' : 'text-gray-400'}`}>TR</a>
|
||||
<a href="/en" className={`font-medium cursor-pointer ${lang === 'en' ? 'text-sea-dark font-bold' : 'text-gray-400'}`}>EN</a>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { ChevronDown } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Hero({ dict }: { dict: any }) {
|
||||
const words = ["MOY", "BEACH"];
|
||||
|
||||
return (
|
||||
<section className="relative h-screen w-full flex items-center justify-center overflow-hidden">
|
||||
|
||||
{/* Background Image */}
|
||||
<div className="absolute inset-0">
|
||||
<Image
|
||||
src="https://images.unsplash.com/photo-1590523277543-a94d2e4eb00b?auto=format&fit=crop&q=85&w=2400"
|
||||
alt="Moy Beach Akyaka"
|
||||
fill
|
||||
className="object-cover object-center"
|
||||
priority
|
||||
sizes="100vw"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Multi-layer gradient for depth */}
|
||||
<div className="absolute inset-0 bg-gradient-to-b from-sea-dark/55 via-black/15 to-sea-dark/70 z-10" />
|
||||
<div className="absolute inset-0 bg-gradient-to-r from-sea-dark/20 via-transparent to-sea-dark/20 z-10" />
|
||||
|
||||
{/* Main Content */}
|
||||
<div className="relative z-20 text-center px-4 max-w-5xl mx-auto">
|
||||
|
||||
{/* Location badge */}
|
||||
<motion.p
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
transition={{ duration: 1.4, delay: 0.1 }}
|
||||
className="text-sand/60 text-[11px] md:text-xs uppercase tracking-[0.45em] mb-6 font-light"
|
||||
>
|
||||
Akyaka · Muğla · Türkiye
|
||||
</motion.p>
|
||||
|
||||
{/* Decorative line */}
|
||||
<motion.div
|
||||
initial={{ scaleX: 0 }}
|
||||
animate={{ scaleX: 1 }}
|
||||
transition={{ duration: 0.7, delay: 0.25 }}
|
||||
className="w-12 h-px bg-coral mx-auto mb-8 origin-center"
|
||||
/>
|
||||
|
||||
{/* Main Title — word-by-word reveal */}
|
||||
<h1 className="text-[4.5rem] md:text-[8rem] lg:text-[11rem] font-serif text-white leading-none tracking-tight mb-6">
|
||||
{words.map((word, i) => (
|
||||
<span key={word} className="inline-block overflow-hidden">
|
||||
<motion.span
|
||||
initial={{ y: 110, opacity: 0 }}
|
||||
animate={{ y: 0, opacity: 1 }}
|
||||
transition={{
|
||||
duration: 0.9,
|
||||
delay: 0.4 + i * 0.2,
|
||||
ease: [0.22, 1, 0.36, 1],
|
||||
}}
|
||||
className="inline-block"
|
||||
>
|
||||
{word}
|
||||
</motion.span>
|
||||
{i === 0 && (
|
||||
<span className="inline-block w-4 md:w-8 lg:w-12" />
|
||||
)}
|
||||
</span>
|
||||
))}
|
||||
</h1>
|
||||
|
||||
{/* Subtitle */}
|
||||
<motion.p
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 1, delay: 1.0 }}
|
||||
className="text-lg md:text-2xl text-sand-light font-light tracking-wide mb-12 drop-shadow-md"
|
||||
>
|
||||
{dict.hero.subtitle}
|
||||
</motion.p>
|
||||
|
||||
{/* CTA Buttons */}
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: 20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.8, delay: 1.35 }}
|
||||
className="flex flex-wrap items-center justify-center gap-4"
|
||||
>
|
||||
<a
|
||||
href="#about"
|
||||
className="border border-white/50 hover:border-white text-white px-8 py-3.5 rounded-full text-sm tracking-widest uppercase font-medium transition-all hover:bg-white/10 backdrop-blur-sm"
|
||||
>
|
||||
{dict.hero.explore}
|
||||
</a>
|
||||
</motion.div>
|
||||
</div>
|
||||
|
||||
{/* Scroll Indicator — direct child of section, correctly positioned */}
|
||||
<motion.a
|
||||
href="#about"
|
||||
className="absolute bottom-20 left-1/2 -translate-x-1/2 z-20 text-white flex flex-col items-center gap-2 cursor-pointer"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 0.65 }}
|
||||
transition={{ duration: 1, delay: 2.2 }}
|
||||
whileHover={{ opacity: 1 }}
|
||||
aria-label="Aşağı kaydır"
|
||||
>
|
||||
<span className="text-[9px] uppercase tracking-[0.35em] font-light">Kaydır</span>
|
||||
<motion.div
|
||||
animate={{ y: [0, 7, 0] }}
|
||||
transition={{
|
||||
duration: 1.6,
|
||||
repeat: Infinity,
|
||||
repeatType: "loop",
|
||||
ease: "easeInOut",
|
||||
delay: 2.6,
|
||||
}}
|
||||
>
|
||||
<ChevronDown size={18} />
|
||||
</motion.div>
|
||||
</motion.a>
|
||||
|
||||
{/* Wave divider into About section */}
|
||||
<div className="absolute bottom-0 left-0 right-0 z-20 leading-none pointer-events-none">
|
||||
<svg
|
||||
viewBox="0 0 1440 56"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
preserveAspectRatio="none"
|
||||
className="w-full h-14 block"
|
||||
>
|
||||
<path
|
||||
d="M0,28 C360,56 720,0 1080,28 C1260,42 1380,14 1440,28 L1440,56 L0,56 Z"
|
||||
fill="#F4EFEB"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
"use client";
|
||||
|
||||
const reels = [
|
||||
{ id: 1, url: "https://www.instagram.com/reel/C97iqFqoSyl/embed" },
|
||||
{ id: 2, url: "https://www.instagram.com/reel/C-slzOcIQB3/embed" },
|
||||
{ id: 3, url: "https://www.instagram.com/reel/DLM8ng6MOKf/embed" },
|
||||
{ id: 4, url: "https://www.instagram.com/reel/DX-BDErM5qd/embed" },
|
||||
];
|
||||
|
||||
function InstagramIcon() {
|
||||
return (
|
||||
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5} className="w-4 h-4">
|
||||
<rect x="2" y="2" width="20" height="20" rx="5" ry="5" />
|
||||
<circle cx="12" cy="12" r="4" />
|
||||
<circle cx="17.5" cy="6.5" r="0.8" fill="currentColor" stroke="none" />
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default function InstagramFeed({ dict }: { dict: any }) {
|
||||
return (
|
||||
<section className="py-24 bg-sand-light text-sea-dark overflow-hidden">
|
||||
<div className="container mx-auto px-6 max-w-7xl">
|
||||
|
||||
{/* Header */}
|
||||
<div className="text-center mb-14">
|
||||
<div className="flex items-center justify-center gap-3 mb-4">
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
<h2 className="text-sm font-bold tracking-widest uppercase text-coral flex items-center gap-2">
|
||||
<InstagramIcon />
|
||||
{dict.social.title}
|
||||
</h2>
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
</div>
|
||||
|
||||
<h3 className="text-4xl md:text-5xl font-serif mb-5">{dict.social.heading}</h3>
|
||||
|
||||
<a
|
||||
href="https://www.instagram.com/moy_akyaka/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="inline-flex items-center gap-2 text-sm text-sea-dark/60 hover:text-coral transition-colors tracking-wide"
|
||||
>
|
||||
<InstagramIcon />
|
||||
@moy_akyaka
|
||||
</a>
|
||||
</div>
|
||||
|
||||
{/* Reels grid */}
|
||||
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 md:gap-6">
|
||||
{reels.map((reel) => (
|
||||
<div
|
||||
key={reel.id}
|
||||
className="group relative bg-white rounded-2xl overflow-hidden shadow-sm hover:shadow-xl hover:shadow-sea-dark/10 transition-all duration-500 hover:-translate-y-1"
|
||||
>
|
||||
{/* Thin coral top border accent */}
|
||||
<div className="absolute top-0 left-0 right-0 h-[2px] bg-gradient-to-r from-coral/0 via-coral to-coral/0 opacity-0 group-hover:opacity-100 transition-opacity duration-500 z-10" />
|
||||
|
||||
<iframe
|
||||
src={reel.url}
|
||||
className="w-full h-[520px] md:h-[580px]"
|
||||
style={{ border: "none", display: "block" }}
|
||||
scrolling="no"
|
||||
frameBorder="0"
|
||||
allow="encrypted-media"
|
||||
title={`Instagram Reel ${reel.id}`}
|
||||
/>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* CTA */}
|
||||
<div className="text-center mt-12">
|
||||
<a
|
||||
href="https://www.instagram.com/moy_akyaka/"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="btn-shimmer inline-flex items-center gap-2.5 bg-sea-dark hover:bg-sea-blue text-white px-8 py-3.5 rounded-full text-sm tracking-widest uppercase font-medium transition-colors shadow-md hover:shadow-lg"
|
||||
>
|
||||
<InstagramIcon />
|
||||
{dict.social.button}
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { Calendar, Users, Coffee } from "lucide-react";
|
||||
|
||||
export default function Reservation() {
|
||||
return (
|
||||
<section id="reservation" className="py-24 bg-white relative overflow-hidden">
|
||||
{/* Decorative background blobs */}
|
||||
<div className="absolute top-0 right-0 w-[500px] h-[500px] bg-sand-light rounded-full blur-3xl opacity-60 -translate-y-1/2 translate-x-1/3 pointer-events-none" />
|
||||
<div className="absolute bottom-0 left-0 w-[380px] h-[380px] bg-coral-light/15 rounded-full blur-3xl opacity-50 translate-y-1/2 -translate-x-1/3 pointer-events-none" />
|
||||
|
||||
<div className="container mx-auto px-6 max-w-5xl relative z-10">
|
||||
<div className="bg-sea-dark rounded-[2.5rem] p-8 md:p-14 shadow-2xl overflow-hidden relative">
|
||||
{/* Inner glow */}
|
||||
<div className="absolute top-0 right-0 w-72 h-72 bg-sea-light rounded-full blur-3xl opacity-25 -translate-y-1/2 translate-x-1/2 pointer-events-none" />
|
||||
|
||||
<div className="text-center mb-12 relative z-10 text-white">
|
||||
<div className="flex items-center justify-center gap-3 mb-4">
|
||||
<span className="w-8 h-px bg-coral/70" />
|
||||
<h2 className="text-sm font-bold tracking-widest uppercase text-coral">Hemen Yerinizi Ayırtın</h2>
|
||||
<span className="w-8 h-px bg-coral/70" />
|
||||
</div>
|
||||
<h3 className="text-4xl md:text-5xl font-serif mb-4">Rezervasyon Talebi</h3>
|
||||
<p className="text-sand-light/80 max-w-2xl mx-auto text-sm leading-relaxed">
|
||||
Unutulmaz bir Ege deneyimi için hemen formumuzu doldurun, ekibimiz en kısa sürede sizinle iletişime geçsin.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<motion.form
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6 }}
|
||||
className="relative z-10 bg-white p-7 md:p-10 rounded-2xl shadow-xl max-w-4xl mx-auto"
|
||||
onSubmit={(e) => e.preventDefault()}
|
||||
>
|
||||
<div className="grid md:grid-cols-3 gap-5 mb-6">
|
||||
|
||||
{/* Date */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide flex items-center gap-1.5">
|
||||
<Calendar size={13} className="text-coral" /> Tarih
|
||||
</label>
|
||||
<input
|
||||
type="date"
|
||||
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Guests */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide flex items-center gap-1.5">
|
||||
<Users size={13} className="text-coral" /> Kişi Sayısı
|
||||
</label>
|
||||
<select className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors bg-white text-sm">
|
||||
<option>1 Kişi</option>
|
||||
<option>2 Kişi</option>
|
||||
<option>3 Kişi</option>
|
||||
<option>4 Kişi</option>
|
||||
<option>5+ Kişi</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
{/* Service type */}
|
||||
<div className="space-y-1.5">
|
||||
<label className="text-xs font-semibold text-gray-600 uppercase tracking-wide flex items-center gap-1.5">
|
||||
<Coffee size={13} className="text-coral" /> Hizmet Tipi
|
||||
</label>
|
||||
<select className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors bg-white text-sm">
|
||||
<option>Beach Club (Şezlong/Loca)</option>
|
||||
<option>Restoran Akşam Yemeği</option>
|
||||
<option>Konaklama</option>
|
||||
<option>Özel Etkinlik / Organizasyon</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 gap-5 mb-7">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Adınız Soyadınız"
|
||||
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors text-sm"
|
||||
/>
|
||||
<input
|
||||
type="tel"
|
||||
placeholder="Telefon Numaranız"
|
||||
className="w-full px-4 py-3 rounded-xl border border-gray-200 focus:outline-none focus:ring-2 focus:ring-coral/40 focus:border-coral transition-colors text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Shimmer submit button */}
|
||||
<button
|
||||
type="submit"
|
||||
className="btn-shimmer w-full bg-coral hover:bg-coral-dark text-white font-medium py-4 rounded-xl transition-colors shadow-lg hover:shadow-xl text-sm tracking-wide uppercase"
|
||||
>
|
||||
Rezervasyon Talebi Gönder
|
||||
</button>
|
||||
|
||||
<p className="text-[11px] text-center text-gray-400 mt-4">
|
||||
Bu form ön rezervasyon talebidir. Kesin onay için ekibimiz sizinle iletişime geçecektir.
|
||||
</p>
|
||||
</motion.form>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { Waves, UtensilsCrossed, Hotel, CalendarHeart } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Services({ dict }: { dict: any }) {
|
||||
const services = [
|
||||
{
|
||||
title: dict.services.items.beach.title,
|
||||
description: dict.services.items.beach.description,
|
||||
icon: Waves,
|
||||
image: "https://images.unsplash.com/photo-1519046904884-53103b34b206?auto=format&fit=crop&q=80&w=800",
|
||||
},
|
||||
{
|
||||
title: dict.services.items.restaurant.title,
|
||||
description: dict.services.items.restaurant.description,
|
||||
icon: UtensilsCrossed,
|
||||
image: "https://images.unsplash.com/photo-1544148103-0773bf10d330?auto=format&fit=crop&q=80&w=800",
|
||||
},
|
||||
{
|
||||
title: dict.services.items.hotel.title,
|
||||
description: dict.services.items.hotel.description,
|
||||
icon: Hotel,
|
||||
image: "https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?auto=format&fit=crop&q=80&w=800",
|
||||
},
|
||||
{
|
||||
title: dict.services.items.events.title,
|
||||
description: dict.services.items.events.description,
|
||||
icon: CalendarHeart,
|
||||
image: "https://images.unsplash.com/photo-1511285560929-80b456fea0bc?auto=format&fit=crop&q=80&w=800",
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<section id="services" className="py-24 bg-white text-sea-dark">
|
||||
<div className="container mx-auto px-6 max-w-7xl">
|
||||
|
||||
<div className="text-center mb-16">
|
||||
<div className="flex items-center justify-center gap-3 mb-4">
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
<h2 className="text-sm font-bold tracking-widest uppercase text-coral">{dict.services.title}</h2>
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
</div>
|
||||
<h3 className="text-4xl md:text-5xl font-serif">{dict.services.heading}</h3>
|
||||
</div>
|
||||
|
||||
<div className="grid md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||||
{services.map((service, index) => (
|
||||
<motion.div
|
||||
key={service.title}
|
||||
initial={{ opacity: 0, y: 30 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
transition={{ duration: 0.6, delay: index * 0.1 }}
|
||||
className="group cursor-pointer"
|
||||
>
|
||||
{/* Image card with gradient border on hover */}
|
||||
<div className="relative mb-6">
|
||||
{/* Border beam — visible on hover */}
|
||||
<div className="absolute -inset-[1px] rounded-2xl bg-gradient-to-br from-coral/0 to-coral/0 group-hover:from-coral/50 group-hover:to-sea-light/40 transition-all duration-500 opacity-0 group-hover:opacity-100 z-0" />
|
||||
|
||||
<div className="relative h-80 overflow-hidden rounded-2xl shadow-md group-hover:shadow-lg group-hover:shadow-coral/15 transition-shadow duration-500 z-10">
|
||||
<div className="absolute inset-0 bg-sea-dark/20 group-hover:bg-transparent transition-colors duration-500 z-10" />
|
||||
|
||||
<Image
|
||||
src={service.image}
|
||||
alt={service.title}
|
||||
fill
|
||||
className="object-cover transform group-hover:scale-110 transition-transform duration-700"
|
||||
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 25vw"
|
||||
/>
|
||||
|
||||
{/* Icon badge */}
|
||||
<div className="absolute top-4 left-4 z-20 bg-white/90 backdrop-blur-sm p-3 rounded-full shadow-lg ring-2 ring-coral/10 group-hover:ring-coral/50 transition-all duration-300">
|
||||
<service.icon className="w-5 h-5 text-coral" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h4 className="text-xl font-serif mb-2 group-hover:text-coral transition-colors duration-300">
|
||||
{service.title}
|
||||
</h4>
|
||||
<p className="text-sm text-gray-500 leading-relaxed">{service.description}</p>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
"use client";
|
||||
|
||||
import { motion } from "framer-motion";
|
||||
import { Star, Quote, Play } from "lucide-react";
|
||||
import Image from "next/image";
|
||||
|
||||
const testimonials = [
|
||||
{
|
||||
name: "Ayşe Y.",
|
||||
platform: "Google Yorumu",
|
||||
text: "Ege'de gördüğüm en kaliteli mekanlardan biri. Yemekler harika, denizi zaten muhteşem. Özellikle kokteyllerini denemelisiniz.",
|
||||
rating: 5,
|
||||
},
|
||||
{
|
||||
name: "David M.",
|
||||
platform: "TripAdvisor",
|
||||
text: "Mükemmel bir deneyimdi. Ailece geldik ve çocuklar da biz de çok eğlendik. Personel çok ilgili ve güler yüzlüydü.",
|
||||
rating: 5,
|
||||
},
|
||||
{
|
||||
name: "Caner K.",
|
||||
platform: "Google Yorumu",
|
||||
text: "Harika bir atmosfer. Akşam yemeği için tercih ettik, gün batımı manzarası eşliğinde unutulmaz bir anı oldu.",
|
||||
rating: 4,
|
||||
},
|
||||
];
|
||||
|
||||
export default function VideoTestimonials() {
|
||||
return (
|
||||
<section className="bg-sea-dark text-white overflow-hidden relative">
|
||||
<div className="grid lg:grid-cols-2">
|
||||
|
||||
{/* Video / Image Panel */}
|
||||
<div className="relative h-[50vh] lg:h-auto min-h-[500px] overflow-hidden">
|
||||
<Image
|
||||
src="https://images.unsplash.com/photo-1507525428034-b723cf961d3e?auto=format&fit=crop&q=80&w=1200"
|
||||
alt="Moy Beach Video"
|
||||
fill
|
||||
className="object-cover"
|
||||
sizes="(max-width: 1024px) 100vw, 50vw"
|
||||
/>
|
||||
<div className="absolute inset-0 bg-sea-dark/50 z-10" />
|
||||
|
||||
{/* Play button overlay */}
|
||||
<div className="absolute inset-0 z-20 flex flex-col items-center justify-center gap-6 p-8 text-center">
|
||||
<a
|
||||
href="https://www.youtube.com/@moybeach"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="group w-20 h-20 bg-white/15 hover:bg-white/25 border-2 border-white/60 hover:border-white rounded-full flex items-center justify-center transition-all duration-300 hover:scale-110 backdrop-blur-sm"
|
||||
aria-label="Videoyu izle"
|
||||
>
|
||||
<Play className="w-7 h-7 text-white ml-1 group-hover:scale-110 transition-transform" fill="white" />
|
||||
</a>
|
||||
<p className="text-sand/80 text-sm tracking-wide">Moy Beach'i Keşfedin</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Testimonials Panel */}
|
||||
<div className="py-20 px-8 lg:px-14 flex flex-col justify-center">
|
||||
<div className="flex items-center gap-3 mb-4">
|
||||
<span className="w-8 h-px bg-coral" />
|
||||
<h2 className="text-sm font-bold tracking-widest uppercase text-coral">Referanslar</h2>
|
||||
</div>
|
||||
<h3 className="text-4xl md:text-5xl font-serif mb-10">Misafirlerimiz<br />Ne Diyor?</h3>
|
||||
|
||||
<div className="space-y-6">
|
||||
{testimonials.map((testimonial, index) => (
|
||||
<motion.div
|
||||
key={index}
|
||||
initial={{ opacity: 0, x: 40 }}
|
||||
whileInView={{ opacity: 1, x: 0 }}
|
||||
viewport={{ once: true }}
|
||||
transition={{ duration: 0.6, delay: index * 0.15 }}
|
||||
className="bg-white/6 hover:bg-white/10 p-6 rounded-2xl relative border border-white/5 hover:border-white/10 transition-colors duration-300"
|
||||
>
|
||||
<Quote className="absolute top-5 right-6 text-coral/20 w-10 h-10" />
|
||||
|
||||
{/* Stars */}
|
||||
<div className="flex text-coral mb-3">
|
||||
{[...Array(5)].map((_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
className={`w-3.5 h-3.5 ${i < testimonial.rating ? "fill-current" : "opacity-25"}`}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="text-base italic text-sand-light/90 mb-5 leading-relaxed">
|
||||
"{testimonial.text}"
|
||||
</p>
|
||||
|
||||
<div className="flex items-center gap-3">
|
||||
<div className="w-9 h-9 bg-coral rounded-full flex items-center justify-center font-bold text-sm shrink-0">
|
||||
{testimonial.name.charAt(0)}
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-sm">{testimonial.name}</p>
|
||||
<p className="text-xs text-gray-400">{testimonial.platform}</p>
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Aggregate rating */}
|
||||
<div className="mt-8 flex items-center gap-4 pt-6 border-t border-white/10">
|
||||
<div className="flex items-baseline gap-1">
|
||||
<span className="text-3xl font-bold font-serif">4.8</span>
|
||||
<span className="text-coral text-lg">/ 5</span>
|
||||
</div>
|
||||
<p className="text-sm text-gray-400 leading-snug">
|
||||
Google & TripAdvisor değerlendirmelerine göre
|
||||
<br />
|
||||
<span className="text-sand/60">(150+ Yorum)</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user