diff --git a/app/[lang]/about/AboutClient.tsx b/app/[lang]/about/AboutClient.tsx
new file mode 100644
index 0000000..ae4a81a
--- /dev/null
+++ b/app/[lang]/about/AboutClient.tsx
@@ -0,0 +1,142 @@
+'use client'
+
+import { motion } from "framer-motion"
+import Image from "next/image"
+import { Check, Hotel, Star, Globe } from 'lucide-react'
+
+
+
+export default function AboutClient({ lang, dict }: { lang: string, dict: any }) {
+ const whyUs = [
+ { title: dict.about.why['1'].t, desc: dict.about.why['1'].d },
+ { title: dict.about.why['2'].t, desc: dict.about.why['2'].d },
+ { title: dict.about.why['3'].t, desc: dict.about.why['3'].d },
+ { title: dict.about.why['4'].t, desc: dict.about.why['4'].d }
+ ]
+
+ const stats = [
+ { icon: , value: '8+', label: 'Premium Room' },
+ { icon: , value: '4.8', label: 'Guest Rating' },
+ { icon: , value: '10+', label: 'Countries' }
+ ]
+
+ return (
+
+
+
+ {/* HERO SECTION */}
+
+
+
+ {dict.about.title}
+
+
+ {dict.about.subtitle}
+
+
+
+
+ {/* STORY & WHY US SECTION */}
+
+
+
+ {/* Left: Story */}
+
+ {dict.about.story.title}
+
+
{dict.about.story.p1}
+
{dict.about.story.p2}
+
+
+
+ {/* Right: Why Us Card */}
+
+ {dict.about.why.title}
+
+ {whyUs.map((item, idx) => (
+
+
+
+
+
+
{item.title}
+
{item.desc}
+
+
+ ))}
+
+
+
+
+
+ {/* STATS SECTION */}
+
+
+ {stats.map((stat, idx) => (
+
+
+ {stat.icon}
+
+
+
{stat.value}
+
{stat.label}
+
+
+ ))}
+
+
+
+ {/* VISION SECTION */}
+
+
+
+ {dict.about.vision.title}
+
+
+ {dict.about.vision.text}
+
+
+
+
+
+
+ )
+}
diff --git a/app/[lang]/about/page.tsx b/app/[lang]/about/page.tsx
new file mode 100644
index 0000000..1903813
--- /dev/null
+++ b/app/[lang]/about/page.tsx
@@ -0,0 +1,18 @@
+import { getDictionary } from "@/dictionaries/get-dictionary"
+import AboutClient from "./AboutClient"
+
+export async function generateMetadata({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+ return {
+ title: `${dict.about.title} - Ayris Apart`,
+ description: dict.about.subtitle,
+ }
+}
+
+export default async function AboutPage({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ return
+}
diff --git a/app/[lang]/contact/ContactClient.tsx b/app/[lang]/contact/ContactClient.tsx
new file mode 100644
index 0000000..999dc10
--- /dev/null
+++ b/app/[lang]/contact/ContactClient.tsx
@@ -0,0 +1,184 @@
+'use client'
+
+import { motion } from "framer-motion"
+import { Mail, Phone, MapPin, Clock, ArrowUpRight, MessageCircle } from 'lucide-react'
+import Link from "next/link"
+
+
+
+const InstagramIcon = ({ size = 20 }: { size?: number }) => (
+
+
+
+
+
+)
+
+export default function ContactClient({ lang, dict }: { lang: string, dict: any }) {
+ return (
+
+
+
+ {/* HERO SECTION */}
+
+
+
+ {dict.contact.title.split(' ')[0]} {dict.contact.title.split(' ').slice(1).join(' ')}
+
+
+
+
+ {/* MINIMALIST INFO GRID */}
+
+
+
+ {/* Address */}
+
+
+
+
{dict.contact.visit.t}
+
+ {dict.contact.visit.d}
+
+
+
{dict.contact.btn.map}
+
+
+
+
+
+ {/* Direct Connect */}
+
+
+
+
{dict.contact.call.t}
+
+
+90 543 231 87 13
+
{dict.contact.call.d}
+
+
+
{dict.contact.btn.call}
+
+
+
+
+
+ {/* Email */}
+
+
+
+
{dict.contact.write.t}
+
+
hello@ayrisapart.com
+
{dict.contact.write.d}
+
+
+
{dict.contact.btn.mail}
+
+
+
+
+
+ {/* WhatsApp */}
+
+
+
+
{dict.contact.wa.t}
+
+ {dict.contact.wa.d}
+
+
+
{dict.contact.btn.wa}
+
+
+
+
+
+ {/* Instagram */}
+
+
+
+
{dict.contact.ig.t}
+
+ {dict.contact.ig.d}
+
+
+
{dict.contact.btn.ig}
+
+
+
+
+
+ {/* Working Hours */}
+
+
+
+
{dict.contact.hours.t}
+
+
{dict.contact.hours.d}
+
{dict.contact.hours.sub}
+
+
Open 24/7 for you
+
+
+
+
+
+ {/* FULL WIDTH MAP SECTION */}
+
+
+
+
+ )
+}
diff --git a/app/[lang]/contact/page.tsx b/app/[lang]/contact/page.tsx
new file mode 100644
index 0000000..a44786d
--- /dev/null
+++ b/app/[lang]/contact/page.tsx
@@ -0,0 +1,18 @@
+import { getDictionary } from "@/dictionaries/get-dictionary"
+import ContactClient from "./ContactClient"
+
+export async function generateMetadata({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+ return {
+ title: `${dict.contact.title} - Ayris Apart`,
+ description: dict.contact.subtitle,
+ }
+}
+
+export default async function ContactPage({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ return
+}
diff --git a/app/[lang]/layout.tsx b/app/[lang]/layout.tsx
new file mode 100644
index 0000000..cf42a68
--- /dev/null
+++ b/app/[lang]/layout.tsx
@@ -0,0 +1,49 @@
+import type { Metadata } from "next";
+import { Oranienbaum, Inter } from "next/font/google";
+import "../globals.css";
+import Navbar from "@/components/Navbar";
+import { getDictionary } from "@/dictionaries/get-dictionary";
+import Footer from "@/components/Footer";
+
+const oranienbaum = Oranienbaum({
+ subsets: ["latin", "latin-ext"],
+ weight: ["400"],
+ variable: "--font-oranienbaum",
+ display: "swap",
+});
+
+const inter = Inter({
+ subsets: ["latin", "latin-ext"],
+ variable: "--font-inter",
+ display: "swap",
+});
+
+export const metadata: Metadata = {
+ title: "Ayris - Luxury Accommodation",
+ description: "Experience the ultimate comfort and luxury at Ayris.",
+};
+
+export async function generateStaticParams() {
+ return [{ lang: 'en' }, { lang: 'tr' }]
+}
+
+export default async function RootLayout({
+ children,
+ params,
+}: {
+ children: React.ReactNode;
+ params: Promise<{ lang: string }>;
+}) {
+ const { lang } = await params;
+ const dict = await getDictionary(lang as 'en' | 'tr');
+
+ return (
+
+
+
+ {children}
+
+
+
+ );
+}
diff --git a/app/[lang]/news/NewsClient.tsx b/app/[lang]/news/NewsClient.tsx
new file mode 100644
index 0000000..5dc6cc2
--- /dev/null
+++ b/app/[lang]/news/NewsClient.tsx
@@ -0,0 +1,120 @@
+'use client'
+
+import { motion } from "framer-motion"
+import Image from "next/image"
+import Link from "next/link"
+import { Calendar, ArrowRight } from 'lucide-react'
+
+
+export default function NewsClient({ lang, dict }: { lang: string, dict: any }) {
+ const newsItems = [
+ {
+ id: 'hidden-gems-oren',
+ title: dict.news_page.list.n1.title,
+ excerpt: dict.news_page.list.n1.excerpt,
+ image: 'https://images.unsplash.com/photo-1544124499-58912cbddaad?q=80&w=2127&auto=format&fit=crop',
+ date: 'April 15, 2026',
+ author: dict.news_page.list.n1.author
+ },
+ {
+ id: 'summer-cocktails-retreat',
+ title: dict.news_page.list.n2.title,
+ excerpt: dict.news_page.list.n2.excerpt,
+ image: 'https://images.unsplash.com/photo-1519046904884-53103b34b206?q=80&w=2073&auto=format&fit=crop',
+ date: 'April 10, 2026',
+ author: dict.news_page.list.n2.author
+ },
+ {
+ id: 'luxury-interior-trends',
+ title: dict.news_page.list.n3.title,
+ excerpt: dict.news_page.list.n3.excerpt,
+ image: 'https://images.unsplash.com/photo-1618773928121-c32242e63f39?q=80&w=1964&auto=format&fit=crop',
+ date: 'April 05, 2026',
+ author: dict.news_page.list.n3.author
+ }
+ ]
+
+ return (
+
+
+
+ {/* HEADER SECTION */}
+
+
+
+ {dict.news_page.title}
+
+
+ {dict.news_page.subtitle}
+
+
+
+
+ {/* ARTICLES GRID SECTION */}
+
+
+ {newsItems.map((article, idx) => (
+
+
+
+ {/* Image Card */}
+
+
+ {/* Metadata and Title */}
+
+
+
+
+ {article.date}
+
+
+
+
+ {article.title}
+
+
+
+ {article.excerpt}
+
+
+
+
{dict.news_page.read}
+
+
+
+
+
+
+ ))}
+
+
+
+
+
+ )
+}
diff --git a/app/[lang]/news/[slug]/NewsDetailClient.tsx b/app/[lang]/news/[slug]/NewsDetailClient.tsx
new file mode 100644
index 0000000..ec79a0a
--- /dev/null
+++ b/app/[lang]/news/[slug]/NewsDetailClient.tsx
@@ -0,0 +1,157 @@
+'use client'
+
+import { motion } from "framer-motion"
+import Image from "next/image"
+import Link from "next/link"
+import { Calendar, User, Share2, ArrowLeft } from 'lucide-react'
+
+
+export default function NewsDetailClient({ lang, slug, dict }: { lang: string, slug: string, dict: any }) {
+ // Use dictionary instead of hardcoded data where possible
+ // For demo, we still use a local map but referring to Ören
+ const newsData: Record = {
+ 'hidden-gems-oren': {
+ title: dict.news_page.list.n1.title,
+ date: 'April 15, 2026',
+ author: dict.news_page.list.n1.author,
+ category: 'Travel Guide',
+ image: 'https://images.unsplash.com/photo-1544124499-58912cbddaad?q=80&w=2127&auto=format&fit=crop',
+ content: [
+ { type: 'paragraph', text: dict.news_page.list.n1.excerpt + ' ' + (lang === 'tr' ? 'Ören’in saklı koyları, zamanın ötesinde bir huzur sunuyor. Turkuaz suların üzerinden sabah sisi kalkarken, standart haritaların ötesine bakmaya istekli olanlar için gizli sığınaklar kendilerini göstermeye başlıyor. Bugünkü yolculuğumuz bizi Ege’nin saklı kalbinde bir keşfe çıkarıyor.' : 'Beyond the crowded beaches, the secret coves of Oren offer a peace beyond time. As the morning mist lifts from the turquoise waters, hidden havens begin to reveal themselves to those willing to look beyond standard maps. Our journey today takes us on an exploration in the hidden heart of the Aegean.') },
+ { type: 'quote', text: lang === 'tr' ? 'Gerçek keşif yolculuğu yeni manzaralar aramak değil, yeni gözlere sahip olmaktan geçer.' : 'The real voyage of discovery consists not in seeking new landscapes, but in having new eyes.' },
+ { type: 'paragraph', text: lang === 'tr' ? 'Gemile koyunun sessiz kıyılarında, zeytinlikler arasında sessizce oturan antik kalıntılar bunlardan sadece biri. Bu sessiz taşların arasında yürürken, Bizanslı tüccarların yankılarını neredeyse duyabilirsiniz. Burası, tarihin, doğanın ve sessiz lüksün harmanlandığı, Ayris Apart\'ın gerçek özünü bulduğumuz yerdir.' : 'The ancient ruins sitting quietly amidst olive groves on the silent shores of Gemile Bay are just one of them. Walking among these silent stones, you can almost hear the echoes of Byzantine merchants. This is where we find the true essence of Ayris Apart, where history, nature, and silent luxury blend.' },
+ { type: 'image', url: 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=2073&auto=format&fit=crop' }
+ ]
+ },
+ 'summer-cocktails-retreat': {
+ title: dict.news_page.list.n2.title,
+ date: 'April 10, 2026',
+ author: dict.news_page.list.n2.author,
+ category: 'Lifestyle',
+ image: 'https://images.unsplash.com/photo-1519046904884-53103b34b206?q=80&w=2073&auto=format&fit=crop',
+ content: [
+ { type: 'paragraph', text: dict.news_page.list.n2.excerpt }
+ ]
+ },
+ 'luxury-interior-trends': {
+ title: dict.news_page.list.n3.title,
+ date: 'April 05, 2026',
+ author: dict.news_page.list.n3.author,
+ category: 'Design',
+ image: 'https://images.unsplash.com/photo-1618773928121-c32242e63f39?q=80&w=1964&auto=format&fit=crop',
+ content: [
+ { type: 'paragraph', text: dict.news_page.list.n3.excerpt }
+ ]
+ }
+ }
+
+ const post = newsData[slug] || newsData['hidden-gems-oren']
+
+ return (
+
+
+
+ {/* HEADER SECTION */}
+
+
+
+ {post.category}
+
+ {post.date}
+
+
+
+ {post.title}
+
+
+
+
+
+
+
+
Written By
+
{post.author}
+
+
+
+
+
+ {/* FEATURE IMAGE */}
+
+
+ {/* CONTENT SECTION */}
+
+
+ {post.content.map((block: any, idx: number) => {
+ if (block.type === 'paragraph') {
+ return (
+
+ {block.text}
+
+ )
+ }
+ if (block.type === 'quote') {
+ return (
+
+
+ “{block.text}”
+
+
+ )
+ }
+ if (block.type === 'image') {
+ return (
+
+
+
+ )
+ }
+ return null
+ })}
+
+ {/* SHARE & BACK */}
+
+
+
+
{lang === 'tr' ? 'Haberlere Dön' : 'Back to News'}
+
+
+ Share
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/app/[lang]/news/[slug]/page.tsx b/app/[lang]/news/[slug]/page.tsx
new file mode 100644
index 0000000..bbf42b8
--- /dev/null
+++ b/app/[lang]/news/[slug]/page.tsx
@@ -0,0 +1,20 @@
+import { getDictionary } from "@/dictionaries/get-dictionary"
+import NewsDetailClient from "./NewsDetailClient"
+
+export async function generateMetadata({ params }: { params: Promise<{ lang: string, slug: string }> }) {
+ const { lang, slug } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ // Dynamic title based on slug if possible, or just section title
+ return {
+ title: `News - Ayris Apart`,
+ description: dict.news_page.subtitle,
+ }
+}
+
+export default async function NewsDetailPage({ params }: { params: Promise<{ lang: string, slug: string }> }) {
+ const { lang, slug } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ return
+}
diff --git a/app/[lang]/news/page.tsx b/app/[lang]/news/page.tsx
new file mode 100644
index 0000000..ec9fe68
--- /dev/null
+++ b/app/[lang]/news/page.tsx
@@ -0,0 +1,18 @@
+import { getDictionary } from "@/dictionaries/get-dictionary"
+import NewsClient from "./NewsClient"
+
+export async function generateMetadata({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+ return {
+ title: `${dict.news_page.title} - Ayris Apart`,
+ description: dict.news_page.subtitle,
+ }
+}
+
+export default async function NewsPage({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ return
+}
diff --git a/app/[lang]/page.tsx b/app/[lang]/page.tsx
new file mode 100644
index 0000000..404353d
--- /dev/null
+++ b/app/[lang]/page.tsx
@@ -0,0 +1,40 @@
+import Hero from "@/components/Hero";
+import Welcome from "@/components/Welcome";
+import ShowcaseImage from "@/components/ShowcaseImage";
+import QuoteSection from "@/components/QuoteSection";
+import SuitesHighlights from "@/components/SuitesHighlights";
+import Experiences from "@/components/Experiences";
+import ScrollReveal from "@/components/ScrollReveal";
+import CallToAction from "@/components/CallToAction";
+import Amenities from "@/components/Amenities";
+
+import { getDictionary } from "@/dictionaries/get-dictionary";
+
+export async function generateMetadata({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params;
+ const dict = await getDictionary(lang as 'en' | 'tr');
+ return {
+ title: `${dict.hero.title} - ${dict.hero.desc.split('.')[0]}`,
+ description: dict.hero.desc,
+ };
+}
+
+export default async function Home({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params;
+ const dict = await getDictionary(lang as 'en' | 'tr');
+
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/[lang]/suites/SuitesClient.tsx b/app/[lang]/suites/SuitesClient.tsx
new file mode 100644
index 0000000..ca0c4c7
--- /dev/null
+++ b/app/[lang]/suites/SuitesClient.tsx
@@ -0,0 +1,117 @@
+'use client'
+
+import { motion } from "framer-motion"
+import Image from "next/image"
+import Link from "next/link"
+import { Users, BedDouble } from 'lucide-react'
+import Amenities from "@/components/Amenities"
+
+export default function SuitesClient({ lang, dict }: { lang: string, dict: any }) {
+ const suites = [
+ { id: 'iris', number: '01', name: dict.suites_page.list.s1.name, desc: dict.suites_page.list.s1.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606641/ayrisapart/Daire%201/photo_1_2024-04-05_12-32-09.jpg', bed: dict.suites_page.list.s1.bed, guests: dict.suites_page.list.s1.guests },
+ { id: 'electra', number: '02', name: dict.suites_page.list.s2.name, desc: dict.suites_page.list.s2.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606648/ayrisapart/Daire%202/photo_1_2024-04-05_16-04-34.jpg', bed: dict.suites_page.list.s2.bed, guests: dict.suites_page.list.s2.guests },
+ { id: 'arke', number: '03', name: dict.suites_page.list.s3.name, desc: dict.suites_page.list.s3.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606654/ayrisapart/Daire%203/photo_1_2024-04-05_16-06-09.jpg', bed: dict.suites_page.list.s3.bed, guests: dict.suites_page.list.s3.guests },
+ { id: 'harpy', number: '04', name: dict.suites_page.list.s4.name, desc: dict.suites_page.list.s4.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606661/ayrisapart/Daire%204/photo_1_2024-04-05_16-07-01.jpg', bed: dict.suites_page.list.s4.bed, guests: dict.suites_page.list.s4.guests },
+ { id: 'hydaspes', number: '05', name: dict.suites_page.list.s5.name, desc: dict.suites_page.list.s5.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606671/ayrisapart/Daire%205/photo_1_2024-05-04_15-32-44.jpg', bed: dict.suites_page.list.s5.bed, guests: dict.suites_page.list.s5.guests },
+ { id: 'zephyrus', number: '06', name: dict.suites_page.list.s6.name, desc: dict.suites_page.list.s6.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606681/ayrisapart/Daire%206/photo_1_2024-05-04_15-32-44.jpg', bed: dict.suites_page.list.s6.bed, guests: dict.suites_page.list.s6.guests },
+ { id: 'pothos', number: '07', name: dict.suites_page.list.s7.name, desc: dict.suites_page.list.s7.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606689/ayrisapart/Daire%207/photo_1_2024-05-04_15-33-34.jpg', bed: dict.suites_page.list.s7.bed, guests: dict.suites_page.list.s7.guests },
+ { id: 'thaumas', number: '08', name: dict.suites_page.list.s8.name, desc: dict.suites_page.list.s8.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606696/ayrisapart/Daire%208/photo_1_2024-05-04_15-33-34.jpg', bed: dict.suites_page.list.s8.bed, guests: dict.suites_page.list.s8.guests },
+ ]
+
+ return (
+
+
+ {/* HEADER SECTION */}
+
+
+
+ {dict.suites_page.title}
+
+
+ {dict.suites_page.subtitle}
+
+
+
+
+ {/* SUITES LIST SECTION */}
+
+
+ {suites.map((suite, idx) => (
+
+ {/* Image Card */}
+
+
+
+
+ {/* Info */}
+
+
+ {suite.number}.
+ {suite.name}
+
+
+ {/* Icons row */}
+
+
+
+ {suite.guests}
+
+
+
+ {suite.bed}
+
+
+
+
+ {suite.desc}
+
+
+ {/* Link */}
+
+
+
+
+
+
+
+
{dict.suites_page.details}
+
+
+
+ ))}
+
+
+
+ {/* GENERAL AMENITIES SECTION */}
+
+
+
+ )
+}
diff --git a/app/[lang]/suites/[id]/SuiteDetailClient.tsx b/app/[lang]/suites/[id]/SuiteDetailClient.tsx
new file mode 100644
index 0000000..7c61732
--- /dev/null
+++ b/app/[lang]/suites/[id]/SuiteDetailClient.tsx
@@ -0,0 +1,221 @@
+'use client'
+
+import { motion } from "framer-motion"
+import Image from "next/image"
+import Link from "next/link"
+import { Users, BedDouble, ArrowLeft } from 'lucide-react'
+import Amenities from "@/components/Amenities"
+
+export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id: string, dict: any }) {
+ // Mapping the 8 mythological suites with their Cloudinary assets
+ const suitesData: Record = {
+ 'iris': {
+ number: '01',
+ name: dict.suites_page.list.s1.name,
+ description: dict.suites_page.list.s1.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606641/ayrisapart/Daire%201/photo_1_2024-04-05_12-32-09.jpg',
+ guests: dict.suites_page.list.s1.guests,
+ bed: dict.suites_page.list.s1.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606642/ayrisapart/Daire%201/photo_2_2024-04-05_12-32-09.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606643/ayrisapart/Daire%201/photo_3_2024-04-05_12-32-09.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606644/ayrisapart/Daire%201/photo_4_2024-04-05_12-32-09.jpg'
+ ]
+ },
+ 'electra': {
+ number: '02',
+ name: dict.suites_page.list.s2.name,
+ description: dict.suites_page.list.s2.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606648/ayrisapart/Daire%202/photo_1_2024-04-05_16-04-34.jpg',
+ guests: dict.suites_page.list.s2.guests,
+ bed: dict.suites_page.list.s2.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606649/ayrisapart/Daire%202/photo_2_2024-04-05_16-04-34.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606650/ayrisapart/Daire%202/photo_3_2024-04-05_16-04-34.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606651/ayrisapart/Daire%202/photo_5_2024-04-05_16-04-34.jpg'
+ ]
+ },
+ 'arke': {
+ number: '03',
+ name: dict.suites_page.list.s3.name,
+ description: dict.suites_page.list.s3.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606654/ayrisapart/Daire%203/photo_1_2024-04-05_16-06-09.jpg',
+ guests: dict.suites_page.list.s3.guests,
+ bed: dict.suites_page.list.s3.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606655/ayrisapart/Daire%203/photo_2_2024-04-05_16-06-09.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606655/ayrisapart/Daire%203/photo_3_2024-04-05_16-06-09.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606656/ayrisapart/Daire%203/photo_4_2024-04-05_16-06-09.jpg'
+ ]
+ },
+ 'harpy': {
+ number: '04',
+ name: dict.suites_page.list.s4.name,
+ description: dict.suites_page.list.s4.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606661/ayrisapart/Daire%204/photo_1_2024-04-05_16-07-01.jpg',
+ guests: dict.suites_page.list.s4.guests,
+ bed: dict.suites_page.list.s4.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606662/ayrisapart/Daire%204/photo_2_2024-04-05_16-07-01.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606663/ayrisapart/Daire%204/photo_3_2024-04-05_16-07-01.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606664/ayrisapart/Daire%204/photo_5_2024-04-05_16-07-01.jpg'
+ ]
+ },
+ 'hydaspes': {
+ number: '05',
+ name: dict.suites_page.list.s5.name,
+ description: dict.suites_page.list.s5.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606671/ayrisapart/Daire%205/photo_1_2024-05-04_15-32-44.jpg',
+ guests: dict.suites_page.list.s5.guests,
+ bed: dict.suites_page.list.s5.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606672/ayrisapart/Daire%205/photo_2_2024-05-04_15-33-08.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606673/ayrisapart/Daire%205/photo_3_2024-05-04_15-33-08.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606674/ayrisapart/Daire%205/photo_4_2024-05-04_15-33-08.jpg'
+ ]
+ },
+ 'zephyrus': {
+ number: '06',
+ name: dict.suites_page.list.s6.name,
+ description: dict.suites_page.list.s6.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606681/ayrisapart/Daire%206/photo_1_2024-05-04_15-32-44.jpg',
+ guests: dict.suites_page.list.s6.guests,
+ bed: dict.suites_page.list.s6.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606682/ayrisapart/Daire%206/photo_2_2024-05-04_15-33-08.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606683/ayrisapart/Daire%206/photo_3_2024-05-04_15-33-08.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606684/ayrisapart/Daire%206/photo_5_2024-05-04_15-33-08.jpg'
+ ]
+ },
+ 'pothos': {
+ number: '07',
+ name: dict.suites_page.list.s7.name,
+ description: dict.suites_page.list.s7.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606689/ayrisapart/Daire%207/photo_1_2024-05-04_15-33-34.jpg',
+ guests: dict.suites_page.list.s7.guests,
+ bed: dict.suites_page.list.s7.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606690/ayrisapart/Daire%207/photo_2_2024-05-04_15-33-34.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606691/ayrisapart/Daire%207/photo_3_2024-05-04_15-33-34.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606692/ayrisapart/Daire%207/photo_5_2024-05-04_15-33-34.jpg'
+ ]
+ },
+ 'thaumas': {
+ number: '08',
+ name: dict.suites_page.list.s8.name,
+ description: dict.suites_page.list.s8.desc,
+ mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606696/ayrisapart/Daire%208/photo_1_2024-05-04_15-33-34.jpg',
+ guests: dict.suites_page.list.s8.guests,
+ bed: dict.suites_page.list.s8.bed,
+ gallery: [
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606697/ayrisapart/Daire%208/photo_2_2024-05-04_15-33-34.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606698/ayrisapart/Daire%208/photo_4_2024-05-04_15-33-34.jpg',
+ 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606699/ayrisapart/Daire%208/photo_5_2024-05-04_15-33-34.jpg'
+ ]
+ }
+ }
+
+ const suite = suitesData[id] || suitesData['iris']
+
+ return (
+
+
+ {/* SECTION 1: HEADER & MAIN IMAGE */}
+
+
+ {/* Back Button */}
+
+
+
{lang === 'tr' ? 'Tüm Odalar' : 'All Suites'}
+
+
+ {/* Title and Brief Header */}
+
+
+ {suite.number}.
+ {suite.name}
+
+
+
+
+
+ {suite.guests}
+
+
+
+ {suite.bed}
+
+
+
+
+ {/* Main Visual */}
+
+
+
+
+
+
+ {/* SECTION 2: ABOUT & AMENITIES */}
+
+
+
+
{lang === 'tr' ? 'Suit Hakkında' : 'About Suite'}
+
+
+
+ {suite.description}
+
+
+
+
+
+
+
+
+
{dict.footer.book}
+
+
+
+
+ {/* INTEGRATED AMENITIES COMPONENT */}
+
+
+
+ {/* SECTION 3: GALLERY GRID */}
+
+
+
+ )
+}
diff --git a/app/[lang]/suites/[id]/page.tsx b/app/[lang]/suites/[id]/page.tsx
new file mode 100644
index 0000000..ac49065
--- /dev/null
+++ b/app/[lang]/suites/[id]/page.tsx
@@ -0,0 +1,19 @@
+import { getDictionary } from "@/dictionaries/get-dictionary"
+import SuiteDetailClient from "./SuiteDetailClient"
+
+export async function generateMetadata({ params }: { params: Promise<{ lang: string, id: string }> }) {
+ const { lang, id } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ return {
+ title: `Suites - Ayris Apart`,
+ description: dict.suites_page.subtitle,
+ }
+}
+
+export default async function SuiteDetailPage({ params }: { params: Promise<{ lang: string, id: string }> }) {
+ const { lang, id } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ return
+}
diff --git a/app/[lang]/suites/page.tsx b/app/[lang]/suites/page.tsx
new file mode 100644
index 0000000..c2261a6
--- /dev/null
+++ b/app/[lang]/suites/page.tsx
@@ -0,0 +1,18 @@
+import { getDictionary } from "@/dictionaries/get-dictionary"
+import SuitesClient from "./SuitesClient"
+
+export async function generateMetadata({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+ return {
+ title: `${dict.suites_page.title} - Ayris Apart`,
+ description: dict.suites_page.subtitle,
+ }
+}
+
+export default async function SuitesPage({ params }: { params: Promise<{ lang: string }> }) {
+ const { lang } = await params
+ const dict = await getDictionary(lang as 'en' | 'tr')
+
+ return
+}
diff --git a/app/api/upload/route.ts b/app/api/upload/route.ts
new file mode 100644
index 0000000..9ea069e
--- /dev/null
+++ b/app/api/upload/route.ts
@@ -0,0 +1,33 @@
+import { NextRequest, NextResponse } from 'next/server';
+import cloudinary from '@/lib/cloudinary';
+
+export async function POST(request: NextRequest) {
+ try {
+ const formData = await request.formData();
+ const file = formData.get('file') as File;
+
+ if (!file) {
+ return NextResponse.json({ error: 'No file provided' }, { status: 400 });
+ }
+
+ // Convert file to base64
+ const arrayBuffer = await file.arrayBuffer();
+ const buffer = Buffer.from(arrayBuffer);
+ const base64File = `data:${file.type};base64,${buffer.toString('base64')}`;
+
+ // Upload to Cloudinary
+ const result = await cloudinary.uploader.upload(base64File, {
+ folder: 'ayris-apart', // Organize images in a specific folder
+ resource_type: 'auto',
+ });
+
+ return NextResponse.json({
+ url: result.secure_url,
+ public_id: result.public_id,
+ });
+
+ } catch (error: any) {
+ console.error('Upload Error:', error);
+ return NextResponse.json({ error: error.message }, { status: 500 });
+ }
+}
diff --git a/app/globals.css b/app/globals.css
index a2dc41e..f9fde8b 100644
--- a/app/globals.css
+++ b/app/globals.css
@@ -1,26 +1,25 @@
@import "tailwindcss";
+@theme {
+ --font-serif: var(--font-oranienbaum), serif;
+ --font-sans: var(--font-inter), sans-serif;
+
+ --color-background: #faf7f0;
+ --color-foreground: #1a1a1a;
+ --color-brand: #c88c4b;
+}
+
:root {
- --background: #ffffff;
- --foreground: #171717;
-}
-
-@theme inline {
- --color-background: var(--background);
- --color-foreground: var(--foreground);
- --font-sans: var(--font-geist-sans);
- --font-mono: var(--font-geist-mono);
-}
-
-@media (prefers-color-scheme: dark) {
- :root {
- --background: #0a0a0a;
- --foreground: #ededed;
- }
+ --background: #faf7f0;
+ --foreground: #1a1a1a;
}
body {
background: var(--background);
color: var(--foreground);
- font-family: Arial, Helvetica, sans-serif;
+ font-family: var(--font-inter), sans-serif;
+}
+
+h1, h2, h3, h4, h5, h6, .font-serif {
+ font-family: var(--font-oranienbaum), serif;
}
diff --git a/app/layout.tsx b/app/layout.tsx
deleted file mode 100644
index 976eb90..0000000
--- a/app/layout.tsx
+++ /dev/null
@@ -1,33 +0,0 @@
-import type { Metadata } from "next";
-import { Geist, Geist_Mono } from "next/font/google";
-import "./globals.css";
-
-const geistSans = Geist({
- variable: "--font-geist-sans",
- subsets: ["latin"],
-});
-
-const geistMono = Geist_Mono({
- variable: "--font-geist-mono",
- subsets: ["latin"],
-});
-
-export const metadata: Metadata = {
- title: "Create Next App",
- description: "Generated by create next app",
-};
-
-export default function RootLayout({
- children,
-}: Readonly<{
- children: React.ReactNode;
-}>) {
- return (
-
- {children}
-
- );
-}
diff --git a/app/page.tsx b/app/page.tsx
deleted file mode 100644
index 3f36f7c..0000000
--- a/app/page.tsx
+++ /dev/null
@@ -1,65 +0,0 @@
-import Image from "next/image";
-
-export default function Home() {
- return (
-
-
-
-
-
- To get started, edit the page.tsx file.
-
-
- Looking for a starting point or more instructions? Head over to{" "}
-
- Templates
- {" "}
- or the{" "}
-
- Learning
- {" "}
- center.
-
-
-
-
-
- );
-}
diff --git a/cloudinary-assets.json b/cloudinary-assets.json
new file mode 100644
index 0000000..4f410df
--- /dev/null
+++ b/cloudinary-assets.json
@@ -0,0 +1,412 @@
+[
+ {
+ "localPath": "Daire 1\\photo_1_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606641/ayrisapart/Daire%201/photo_1_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_1_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_2_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606642/ayrisapart/Daire%201/photo_2_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_2_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_3_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606643/ayrisapart/Daire%201/photo_3_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_3_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_4_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606644/ayrisapart/Daire%201/photo_4_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_4_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_5_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606644/ayrisapart/Daire%201/photo_5_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_5_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_6_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606645/ayrisapart/Daire%201/photo_6_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_6_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_7_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606646/ayrisapart/Daire%201/photo_7_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_7_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_8_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606646/ayrisapart/Daire%201/photo_8_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_8_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 1\\photo_9_2024-04-05_12-32-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606647/ayrisapart/Daire%201/photo_9_2024-04-05_12-32-09.jpg",
+ "public_id": "ayrisapart/Daire 1/photo_9_2024-04-05_12-32-09"
+ },
+ {
+ "localPath": "Daire 2\\photo_1_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606648/ayrisapart/Daire%202/photo_1_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_1_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 2\\photo_2_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606649/ayrisapart/Daire%202/photo_2_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_2_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 2\\photo_3_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606650/ayrisapart/Daire%202/photo_3_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_3_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 2\\photo_4_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606650/ayrisapart/Daire%202/photo_4_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_4_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 2\\photo_5_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606651/ayrisapart/Daire%202/photo_5_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_5_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 2\\photo_6_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606652/ayrisapart/Daire%202/photo_6_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_6_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 2\\photo_7_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606652/ayrisapart/Daire%202/photo_7_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_7_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 2\\photo_8_2024-04-05_16-04-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606653/ayrisapart/Daire%202/photo_8_2024-04-05_16-04-34.jpg",
+ "public_id": "ayrisapart/Daire 2/photo_8_2024-04-05_16-04-34"
+ },
+ {
+ "localPath": "Daire 3\\photo_1_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606654/ayrisapart/Daire%203/photo_1_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_1_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_2_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606655/ayrisapart/Daire%203/photo_2_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_2_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_3_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606655/ayrisapart/Daire%203/photo_3_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_3_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_4_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606656/ayrisapart/Daire%203/photo_4_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_4_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_5_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606657/ayrisapart/Daire%203/photo_5_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_5_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_6_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606657/ayrisapart/Daire%203/photo_6_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_6_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_7_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606658/ayrisapart/Daire%203/photo_7_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_7_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_8_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606659/ayrisapart/Daire%203/photo_8_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_8_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 3\\photo_9_2024-04-05_16-06-09.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606660/ayrisapart/Daire%203/photo_9_2024-04-05_16-06-09.jpg",
+ "public_id": "ayrisapart/Daire 3/photo_9_2024-04-05_16-06-09"
+ },
+ {
+ "localPath": "Daire 4\\photo_10_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606660/ayrisapart/Daire%204/photo_10_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_10_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_1_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606661/ayrisapart/Daire%204/photo_1_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_1_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_2_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606662/ayrisapart/Daire%204/photo_2_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_2_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_3_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606663/ayrisapart/Daire%204/photo_3_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_3_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_4_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606663/ayrisapart/Daire%204/photo_4_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_4_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_5_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606664/ayrisapart/Daire%204/photo_5_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_5_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_6_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606665/ayrisapart/Daire%204/photo_6_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_6_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_7_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606665/ayrisapart/Daire%204/photo_7_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_7_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_8_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606666/ayrisapart/Daire%204/photo_8_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_8_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 4\\photo_9_2024-04-05_16-07-01.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606667/ayrisapart/Daire%204/photo_9_2024-04-05_16-07-01.jpg",
+ "public_id": "ayrisapart/Daire 4/photo_9_2024-04-05_16-07-01"
+ },
+ {
+ "localPath": "Daire 5\\photo_10_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606668/ayrisapart/Daire%205/photo_10_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_10_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_11_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606669/ayrisapart/Daire%205/photo_11_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_11_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_12_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606669/ayrisapart/Daire%205/photo_12_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_12_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_1_2024-05-04_15-32-44.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606671/ayrisapart/Daire%205/photo_1_2024-05-04_15-32-44.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_1_2024-05-04_15-32-44"
+ },
+ {
+ "localPath": "Daire 5\\photo_1_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606672/ayrisapart/Daire%205/photo_1_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_1_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_2_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606672/ayrisapart/Daire%205/photo_2_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_2_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_3_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606673/ayrisapart/Daire%205/photo_3_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_3_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_4_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606674/ayrisapart/Daire%205/photo_4_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_4_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_5_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606675/ayrisapart/Daire%205/photo_5_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_5_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_6_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606676/ayrisapart/Daire%205/photo_6_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_6_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_7_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606677/ayrisapart/Daire%205/photo_7_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_7_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_8_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606677/ayrisapart/Daire%205/photo_8_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_8_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 5\\photo_9_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606678/ayrisapart/Daire%205/photo_9_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 5/photo_9_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_10_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606679/ayrisapart/Daire%206/photo_10_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_10_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_11_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606679/ayrisapart/Daire%206/photo_11_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_11_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_12_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606680/ayrisapart/Daire%206/photo_12_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_12_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_1_2024-05-04_15-32-44.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606681/ayrisapart/Daire%206/photo_1_2024-05-04_15-32-44.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_1_2024-05-04_15-32-44"
+ },
+ {
+ "localPath": "Daire 6\\photo_1_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606681/ayrisapart/Daire%206/photo_1_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_1_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_2_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606682/ayrisapart/Daire%206/photo_2_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_2_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_3_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606683/ayrisapart/Daire%206/photo_3_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_3_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_4_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606683/ayrisapart/Daire%206/photo_4_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_4_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_5_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606684/ayrisapart/Daire%206/photo_5_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_5_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_6_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606685/ayrisapart/Daire%206/photo_6_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_6_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_7_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606686/ayrisapart/Daire%206/photo_7_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_7_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_8_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606687/ayrisapart/Daire%206/photo_8_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_8_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 6\\photo_9_2024-05-04_15-33-08.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606688/ayrisapart/Daire%206/photo_9_2024-05-04_15-33-08.jpg",
+ "public_id": "ayrisapart/Daire 6/photo_9_2024-05-04_15-33-08"
+ },
+ {
+ "localPath": "Daire 7\\photo_10_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606688/ayrisapart/Daire%207/photo_10_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_10_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_1_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606689/ayrisapart/Daire%207/photo_1_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_1_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_2_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606690/ayrisapart/Daire%207/photo_2_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_2_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_3_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606691/ayrisapart/Daire%207/photo_3_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_3_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_4_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606691/ayrisapart/Daire%207/photo_4_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_4_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_5_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606692/ayrisapart/Daire%207/photo_5_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_5_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_6_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606693/ayrisapart/Daire%207/photo_6_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_6_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_7_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606693/ayrisapart/Daire%207/photo_7_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_7_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_8_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606694/ayrisapart/Daire%207/photo_8_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_8_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 7\\photo_9_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606695/ayrisapart/Daire%207/photo_9_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 7/photo_9_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_10_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606696/ayrisapart/Daire%208/photo_10_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_10_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_1_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606696/ayrisapart/Daire%208/photo_1_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_1_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_2_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606697/ayrisapart/Daire%208/photo_2_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_2_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_3_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606697/ayrisapart/Daire%208/photo_3_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_3_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_4_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606698/ayrisapart/Daire%208/photo_4_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_4_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_5_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606699/ayrisapart/Daire%208/photo_5_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_5_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_6_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606699/ayrisapart/Daire%208/photo_6_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_6_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_7_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606700/ayrisapart/Daire%208/photo_7_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_7_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_8_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606701/ayrisapart/Daire%208/photo_8_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_8_2024-05-04_15-33-34"
+ },
+ {
+ "localPath": "Daire 8\\photo_9_2024-05-04_15-33-34.jpg",
+ "url": "https://res.cloudinary.com/du7xohbct/image/upload/v1776606702/ayrisapart/Daire%208/photo_9_2024-05-04_15-33-34.jpg",
+ "public_id": "ayrisapart/Daire 8/photo_9_2024-05-04_15-33-34"
+ }
+]
\ No newline at end of file
diff --git a/components/Amenities.tsx b/components/Amenities.tsx
new file mode 100644
index 0000000..a5cbc73
--- /dev/null
+++ b/components/Amenities.tsx
@@ -0,0 +1,46 @@
+'use client'
+
+import {
+ ShieldCheck,
+ Bell,
+ Car,
+ BedDouble,
+ CookingPot,
+ AirVent,
+ Bed,
+ Flame,
+ Wifi,
+ Video
+} from 'lucide-react'
+
+export default function Amenities({ dict }: { dict: any }) {
+ const ams = [
+ { icon: , label: dict.amenities.cctv },
+ { icon: , label: dict.amenities.fire_alarm },
+ { icon: , label: dict.amenities.parking },
+ { icon: , label: dict.amenities.double_bed },
+ { icon: , label: dict.amenities.kitchen },
+ { icon: , label: dict.amenities.ac },
+ { icon: , label: dict.amenities.single_bed },
+ { icon: , label: dict.amenities.fire_ext },
+ { icon: , label: dict.amenities.wifi },
+ ]
+
+ return (
+
+
{dict.amenities.title}
+
+ {ams.map((item, idx) => (
+
+
+ {item.icon}
+
+
+ {item.label}
+
+
+ ))}
+
+
+ )
+}
diff --git a/components/CallToAction.tsx b/components/CallToAction.tsx
new file mode 100644
index 0000000..0e283eb
--- /dev/null
+++ b/components/CallToAction.tsx
@@ -0,0 +1,124 @@
+'use client'
+
+import { motion, useScroll, useTransform } from 'framer-motion'
+import { useRef } from 'react'
+import Link from 'next/link'
+import Image from 'next/image'
+
+const images = [
+ {
+ src: "https://images.unsplash.com/photo-1541410950669-e771b058097d?q=80&w=2070&auto=format&fit=crop",
+ w: 305, h: 225,
+ tx: -550, ty: -350,
+ rotate: -2
+ },
+ {
+ src: "https://images.unsplash.com/photo-1590490360182-c33d57733427?q=80&w=2100&auto=format&fit=crop",
+ w: 325, h: 425,
+ tx: 550, ty: -350,
+ rotate: 1
+ },
+ {
+ src: "https://images.unsplash.com/photo-1566665797739-1674de7a421a?q=80&w=2070&auto=format&fit=crop",
+ w: 385, h: 485,
+ tx: -550, ty: 350,
+ rotate: -1
+ },
+ {
+ src: "https://images.unsplash.com/photo-1571896349842-33c89424de2d?q=80&w=2073&auto=format&fit=crop",
+ w: 425, h: 365,
+ tx: 550, ty: 350,
+ rotate: 2
+ },
+]
+
+export default function CallToAction({ lang, dict }: { lang: string, dict: any }) {
+ const containerRef = useRef(null)
+
+ const { scrollYProgress } = useScroll({
+ target: containerRef,
+ offset: ["start start", "end end"]
+ })
+
+ // Title: Stays hit at 0 until scroll hits 30%, then reveals quickly.
+ const entranceOpacity = useTransform(scrollYProgress, [0.85, 0.95, 1], [0, 1, 1])
+
+ // Description / Button: Reveals even later, ensuring images are already scattering
+ const textOpacity = useTransform(scrollYProgress, [0.5, 0.7, 1], [0, 1, 1])
+ const textY = useTransform(scrollYProgress, [0.5, 0.7, 1], [50, 0, 0])
+
+ // Scatter range: Images start dispersing at 20% to clear the path for text
+ const scatterRange = [0.2, 0.95]
+ const scatterTLX = useTransform(scrollYProgress, scatterRange, [0, -580])
+ const scatterTLY = useTransform(scrollYProgress, scatterRange, [0, -380])
+
+ const scatterTRX = useTransform(scrollYProgress, scatterRange, [0, 580])
+ const scatterTRY = useTransform(scrollYProgress, scatterRange, [0, -380])
+
+ const scatterBLX = useTransform(scrollYProgress, scatterRange, [0, -580])
+ const scatterBLY = useTransform(scrollYProgress, scatterRange, [0, 380])
+
+ const scatterBRX = useTransform(scrollYProgress, scatterRange, [0, 580])
+ const scatterBRY = useTransform(scrollYProgress, scatterRange, [0, 380])
+
+ const scatterX = [scatterTLX, scatterTRX, scatterBLX, scatterBRX]
+ const scatterY = [scatterTLY, scatterTRY, scatterBLY, scatterBRY]
+
+ return (
+
+
+
+ {/* SCATTERING POLAROIDS */}
+ {images.map((img, i) => (
+
+
+
+ ))}
+
+ {/* REVEALING CENTER CONTENT */}
+
+
+
+ {dict.hero.title}
+
+
+
+
+ "{dict.footer.desc}"
+
+
+
+
+ ↳
+ {dict.footer.book}
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/components/Experiences.tsx b/components/Experiences.tsx
new file mode 100644
index 0000000..4d0ca35
--- /dev/null
+++ b/components/Experiences.tsx
@@ -0,0 +1,104 @@
+'use client'
+
+import { motion, AnimatePresence } from 'framer-motion'
+import Image from 'next/image'
+import { useState } from 'react'
+
+const experiences = [
+ {
+ title: "Infinity Pool",
+ description: "Swim towards the horizon in our stunning heated infinity pool, overlooking the turquoise expanse of the Aegean Sea.",
+ image: "https://images.unsplash.com/photo-1576013551627-0cfde316be70?q=80&w=1974&auto=format&fit=crop"
+ },
+ {
+ title: "Snorkeling",
+ description: "Discover vibrant marine life, swim through crystal-clear waters, and experience the wonder of ocean.",
+ image: "https://images.unsplash.com/photo-1544551763-46a013bb70d5?q=80&w=2070&auto=format&fit=crop"
+ },
+ {
+ title: "Paddle boarding",
+ description: "Balance your soul and body while gliding over calm morning waves on our premium paddle boards.",
+ image: "https://images.unsplash.com/photo-1517176641128-052478950337?q=80&w=1974&auto=format&fit=crop"
+ },
+ {
+ title: "Fishing trips",
+ description: "Join our local experts for an authentic Mediterranean fishing experience at sunrise.",
+ image: "https://images.unsplash.com/photo-1524704652723-21444983944d?q=80&w=1974&auto=format&fit=crop"
+ }
+]
+
+export default function Experiences() {
+ const [hoveredIdx, setHoveredIdx] = useState(null)
+
+ return (
+
+
+
+
+ Discover experiences beyond the shore
+
+
+
+
+ {experiences.map((exp, idx) => (
+
setHoveredIdx(idx)}
+ onMouseLeave={() => setHoveredIdx(null)}
+ animate={{
+ filter: hoveredIdx !== null && hoveredIdx !== idx ? 'blur(4px)' : 'blur(0px)',
+ opacity: hoveredIdx !== null && hoveredIdx !== idx ? 0.5 : 1,
+ scale: hoveredIdx === idx ? 1.02 : 1
+ }}
+ className="group cursor-pointer flex flex-col relative"
+ >
+
+
+
+ {/* Overlay Description */}
+
+ {hoveredIdx === idx && (
+
+
+ {exp.description}
+
+
+ )}
+
+
+
+
+ {exp.title}
+
+
+ ))}
+
+
+
+ )
+}
diff --git a/components/Footer.tsx b/components/Footer.tsx
new file mode 100644
index 0000000..88e14f4
--- /dev/null
+++ b/components/Footer.tsx
@@ -0,0 +1,126 @@
+'use client'
+
+import Link from 'next/link'
+import Image from 'next/image'
+import { Phone, Mail } from 'lucide-react'
+
+export default function Footer({ lang, dict }: { lang: string, dict: any }) {
+ return (
+
+ )
+}
diff --git a/components/Hero.tsx b/components/Hero.tsx
new file mode 100644
index 0000000..5132b5e
--- /dev/null
+++ b/components/Hero.tsx
@@ -0,0 +1,167 @@
+'use client'
+
+import { motion, AnimatePresence } from 'framer-motion'
+import { useState, useEffect } from 'react'
+import Link from 'next/link'
+import Image from 'next/image'
+
+const heroSlots = [
+ {
+ srcs: [
+ 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?q=80&w=2070&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1566665797739-1674de7a421a?q=80&w=2070&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1590490360182-c33d57733427?q=80&w=2070&auto=format&fit=crop',
+ ],
+ rotate: -12,
+ top: '15%',
+ left: '22%',
+ size: 'w-48 h-64 md:w-64 md:h-80',
+ delay: 0.2
+ },
+ {
+ srcs: [
+ 'https://images.unsplash.com/photo-1544124499-58912cbddaad?q=80&w=2127&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1520250497591-112f2f40a3f4?q=80&w=2127&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1571896349842-33c89424de2d?q=80&w=2127&auto=format&fit=crop',
+ ],
+ rotate: 10,
+ top: '10%',
+ left: '58%',
+ size: 'w-52 h-64 md:w-72 md:h-80',
+ delay: 0.4
+ },
+ {
+ srcs: [
+ 'https://images.unsplash.com/photo-1507525428034-b723cf961d3e?q=80&w=2073&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1519046904884-53103b34b206?q=80&w=2073&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1506929199020-feee17651703?q=80&w=2073&auto=format&fit=crop',
+ ],
+ rotate: -8,
+ top: '65%',
+ left: '18%',
+ size: 'w-48 h-60 md:w-64 md:h-72',
+ delay: 0.6
+ },
+ {
+ srcs: [
+ 'https://images.unsplash.com/photo-1536935338218-422119932906?q=80&w=1964&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1618773928121-c32242e63f39?q=80&w=1964&auto=format&fit=crop',
+ 'https://images.unsplash.com/photo-1560185007-cde436f6a4d0?q=80&w=1964&auto=format&fit=crop',
+ ],
+ rotate: 15,
+ top: '72%',
+ left: '62%',
+ size: 'w-52 h-64 md:w-72 md:h-88',
+ delay: 0.8
+ }
+]
+
+function FloatingSlot({ slot, idx }: { slot: typeof heroSlots[0], idx: number }) {
+ const [currentIdx, setCurrentIdx] = useState(0)
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setCurrentIdx((prev) => (prev + 1) % slot.srcs.length)
+ }, 4000 + idx * 500)
+ return () => clearInterval(interval)
+ }, [slot.srcs.length, idx])
+
+ return (
+
+
+
+
+
+
+
+ )
+}
+
+export default function Hero({ lang, dict }: { lang: string, dict: any }) {
+ return (
+
+ {/* BACKGROUND TEXT */}
+
+
+ {dict.hero.title}
+
+
+
+ {/* FLOATING SLOTS */}
+ {heroSlots.map((slot, idx) => (
+
+ ))}
+
+ {/* BOTTOM CONTENT */}
+
+
+ {dict.hero.desc}
+
+
+
+
+ {dict.hero.explore}
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/components/Navbar.tsx b/components/Navbar.tsx
new file mode 100644
index 0000000..7a05d7d
--- /dev/null
+++ b/components/Navbar.tsx
@@ -0,0 +1,167 @@
+'use client'
+
+import { useState, useEffect } from 'react'
+import Link from 'next/link'
+import { motion, AnimatePresence } from 'framer-motion'
+import { usePathname, useRouter } from 'next/navigation'
+import Image from 'next/image'
+import { ArrowRight, ChevronDown, Menu, X, Plus } from 'lucide-react'
+
+export default function Navbar({ lang, dict }: { lang: string, dict: any }) {
+ const router = useRouter()
+ const pathname = usePathname()
+
+ const [isVisible, setIsVisible] = useState(true)
+ const [lastScrollY, setLastScrollY] = useState(0)
+ const [isScrolled, setIsScrolled] = useState(false)
+ const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false)
+
+ const handleLangChange = (newLang: string) => {
+ const segments = pathname.split('/')
+ if (segments[1] === 'en' || segments[1] === 'tr') {
+ segments[1] = newLang
+ } else {
+ segments.splice(1, 0, newLang)
+ }
+ router.push(segments.join('/'))
+ }
+
+ const navLinks = [
+ { name: dict.nav.about, href: `/${lang}/about` },
+ { name: dict.nav.suites, href: `/${lang}/suites`, hasDropdown: true },
+ { name: dict.nav.news, href: `/${lang}/news` },
+ ]
+
+ useEffect(() => {
+ const controlNavbar = () => {
+ if (typeof window !== 'undefined') {
+ const currentScrollY = window.scrollY
+ if (currentScrollY > lastScrollY && currentScrollY > 100) {
+ setIsVisible(false)
+ } else {
+ setIsVisible(true)
+ }
+ setLastScrollY(currentScrollY)
+ setIsScrolled(currentScrollY > 50)
+ }
+ }
+ window.addEventListener('scroll', controlNavbar)
+ return () => window.removeEventListener('scroll', controlNavbar)
+ }, [lastScrollY])
+
+ return (
+ <>
+
+
+ {/* LOGO */}
+
+
+ AYRIS APART
+
+
+
+ {/* DESKTOP NAV */}
+
+ {navLinks.map((link) => (
+
+ {link.name}
+
+
+ ))}
+
+
+
+ {/* LANGUAGE SWITCHER */}
+
+ handleLangChange('tr')}
+ className={`transition-colors ${lang === 'tr' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30 hover:text-[#1A1A1A]'}`}
+ >
+ TR
+
+
+ handleLangChange('en')}
+ className={`transition-colors ${lang === 'en' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30 hover:text-[#1A1A1A]'}`}
+ >
+ EN
+
+
+
+
+
{dict.nav.contact}
+
+
+
+ {/* MOBILE MENU TOGGLE */}
+
setIsMobileMenuOpen(!isMobileMenuOpen)}
+ className="md:hidden w-10 h-10 flex flex-col items-center justify-center space-y-1.5"
+ >
+
+
+
+
+
+
+
+
+ {/* MOBILE MENU */}
+
+ {isMobileMenuOpen && (
+
+
+ AYRIS
+ setIsMobileMenuOpen(false)} className="p-2">
+
+
+ {navLinks.map((link, idx) => (
+
+ setIsMobileMenuOpen(false)} className="text-5xl font-serif text-[#1A1A1A] tracking-tighter">
+ {link.name}
+
+
+ ))}
+
+ setIsMobileMenuOpen(false)} className="text-5xl font-serif text-[#1A1A1A] tracking-tighter">
+ {dict.nav.contact}
+
+
+
+ {/* Lang Toggle Mobile */}
+
+ { handleLangChange('tr'); setIsMobileMenuOpen(false); }} className={`text-xl font-bold tracking-widest ${lang === 'tr' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30'}`}>TR
+ { handleLangChange('en'); setIsMobileMenuOpen(false); }} className={`text-xl font-bold tracking-widest ${lang === 'en' ? 'text-[#C88C4B]' : 'text-[#1A1A1A]/30'}`}>EN
+
+
+
+ )}
+
+ >
+ )
+}
diff --git a/components/QuoteSection.tsx b/components/QuoteSection.tsx
new file mode 100644
index 0000000..fb1ca5f
--- /dev/null
+++ b/components/QuoteSection.tsx
@@ -0,0 +1,19 @@
+'use client'
+
+import { motion } from 'framer-motion'
+
+export default function QuoteSection() {
+ return (
+
+
+ Luxury stays designed for ocean lovers
+
+
+ )
+}
diff --git a/components/ScrollReveal.tsx b/components/ScrollReveal.tsx
new file mode 100644
index 0000000..32baced
--- /dev/null
+++ b/components/ScrollReveal.tsx
@@ -0,0 +1,76 @@
+'use client'
+
+import { motion, useScroll, useTransform } from 'framer-motion'
+import { useRef } from 'react'
+
+export default function ScrollReveal() {
+ const containerRef = useRef(null)
+
+ const { scrollYProgress } = useScroll({
+ target: containerRef,
+ offset: ["start start", "end end"]
+ })
+
+ // Text Animations - Sharp movement
+ const topTextY = useTransform(scrollYProgress, [0.1, 0.5], [0, -400])
+ const bottomTextY = useTransform(scrollYProgress, [0.1, 0.5], [0, 400])
+
+ // Video Animations - Sharp appearing.
+ // We use opacity as a "switch" at 0.1 to keep it hidden until then.
+ const videoVisible = useTransform(scrollYProgress, [0, 1], [0, 1])
+ const videoScale = useTransform(scrollYProgress, [0, 0.8], [0, 1])
+ const videoWidth = useTransform(scrollYProgress, [0, 0.8], ["20vw", "100vw"])
+ const videoHeight = useTransform(scrollYProgress, [0, 0.8], ["10vh", "100vh"])
+ const videoBorderRadius = useTransform(scrollYProgress, [0.6, 0.9], ["40px", "0px"])
+
+ return (
+
+
+
+ {/* TEXT MASK CONTAINER */}
+
+
+
+
+ Stay bliss
+
+
+ Enjoy more
+
+
+
+
+
+ {/* EXPANDING VIDEO CONTAINER */}
+
+
+
+
+
+
+ )
+}
diff --git a/components/ShowcaseImage.tsx b/components/ShowcaseImage.tsx
new file mode 100644
index 0000000..a4ed158
--- /dev/null
+++ b/components/ShowcaseImage.tsx
@@ -0,0 +1,40 @@
+'use client'
+
+import { motion, useScroll, useTransform } from 'framer-motion'
+import { useRef } from 'react'
+import Image from 'next/image'
+
+export default function ShowcaseImage() {
+ const containerRef = useRef(null)
+ const { scrollYProgress } = useScroll({
+ target: containerRef,
+ offset: ["start end", "end start"]
+ })
+
+ // Slightly increased scales for a better balance
+ const scale = useTransform(scrollYProgress, [0, 0.4], [0.8, 1.0])
+ const opacity = useTransform(scrollYProgress, [0, 0.2], [0, 1])
+
+ return (
+
+ )
+}
diff --git a/components/SuitesHighlights.tsx b/components/SuitesHighlights.tsx
new file mode 100644
index 0000000..a5163c1
--- /dev/null
+++ b/components/SuitesHighlights.tsx
@@ -0,0 +1,112 @@
+'use client'
+
+import { useRef } from 'react'
+import { motion, useScroll, useTransform } from 'framer-motion'
+import Image from 'next/image'
+import Link from 'next/link'
+
+interface Suite {
+ id: string
+ name: string
+ number: string
+ image: string
+ desc: string
+}
+
+export default function SuitesHighlights({ lang, dict }: { lang: string, dict: any }) {
+ const container = useRef(null)
+
+ const suites: Suite[] = [
+ { id: 'iris', number: '01', name: dict.suites.s1.name, desc: dict.suites.s1.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606641/ayrisapart/Daire%201/photo_1_2024-04-05_12-32-09.jpg' },
+ { id: 'electra', number: '02', name: dict.suites.s2.name, desc: dict.suites.s2.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606648/ayrisapart/Daire%202/photo_1_2024-04-05_16-04-34.jpg' },
+ { id: 'arke', number: '03', name: dict.suites.s3.name, desc: dict.suites.s3.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606654/ayrisapart/Daire%203/photo_1_2024-04-05_16-06-09.jpg' },
+ { id: 'harpy', number: '04', name: dict.suites.s4.name, desc: dict.suites.s4.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606661/ayrisapart/Daire%204/photo_1_2024-04-05_16-07-01.jpg' },
+ { id: 'hydaspes', number: '05', name: dict.suites.s5.name, desc: dict.suites.s5.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606671/ayrisapart/Daire%205/photo_1_2024-05-04_15-32-44.jpg' },
+ { id: 'zephyrus', number: '06', name: dict.suites.s6.name, desc: dict.suites.s6.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606681/ayrisapart/Daire%206/photo_1_2024-05-04_15-32-44.jpg' },
+ { id: 'pothos', number: '07', name: dict.suites.s7.name, desc: dict.suites.s7.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606689/ayrisapart/Daire%207/photo_1_2024-05-04_15-33-34.jpg' },
+ { id: 'thaumas', number: '08', name: dict.suites.s8.name, desc: dict.suites.s8.desc, image: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606696/ayrisapart/Daire%208/photo_1_2024-05-04_15-33-34.jpg' },
+ ]
+
+ return (
+
+
+
+ {suites.map((suite, idx) => (
+
+ ))}
+
+
+ {/* Bottom spacer to allow the last item to scroll */}
+
+
+ )
+}
+
+function SuiteCard({ suite, index, lang, dict }: { suite: Suite, index: number, lang: string, dict: any }) {
+ const cardRef = useRef(null)
+ const { scrollYProgress } = useScroll({
+ target: cardRef,
+ offset: ["start end", "start start"]
+ })
+
+ // Stacking (Curtain) Effect: Each card is sticky and 100vh to cover the previous one
+ return (
+
+
+
+
+ {/* Room Number & Info */}
+
+
+ {suite.number}.
+
{suite.name}
+
+
+
+ {suite.desc}
+
+
+
+
+ {dict.suites.btn.more}
+ ↳
+
+
+
+
+ {/* Image */}
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/components/Welcome.tsx b/components/Welcome.tsx
new file mode 100644
index 0000000..affd88c
--- /dev/null
+++ b/components/Welcome.tsx
@@ -0,0 +1,70 @@
+'use client'
+
+import { motion } from 'framer-motion'
+import Link from 'next/link'
+
+export default function Welcome({ lang, dict }: { lang: string, dict: any }) {
+ return (
+
+ {/* Lotus/Floral Icon */}
+
+
+
+
+
+
+
+
+
+
+ {/* Heading */}
+
+ {dict.welcome.title}
+
+
+ {/* Description */}
+
+ {dict.welcome.desc}
+
+
+ {/* Link */}
+
+
+ {dict.nav.about}
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/dictionaries/en.json b/dictionaries/en.json
new file mode 100644
index 0000000..ca9812f
--- /dev/null
+++ b/dictionaries/en.json
@@ -0,0 +1,132 @@
+{
+ "nav": {
+ "about": "About",
+ "suites": "Suites",
+ "news": "News",
+ "contact": "Contact",
+ "home": "Home"
+ },
+ "hero": {
+ "title": "Ayris Apart",
+ "desc": "In the heart of Muğla Milas Ören, discover refined suites and unforgettable comfort. Your luxury vacation awaits.",
+ "explore": "Explore Suites"
+ },
+ "welcome": {
+ "title": "Welcome to luxury seaside suites on the shores of Oren",
+ "desc": "On the shores of the Aegean Sea, we offer a perfect blend of timeless elegance and coastal serenity."
+ },
+ "footer": {
+ "book": "Book Your Stay",
+ "explore": "Explore",
+ "others": "Others",
+ "utility": "Utility",
+ "socials": "Socials",
+ "desc": "Book today and discover seaside luxury, breathtaking views, and unforgettable moments on the shores of Oren."
+ },
+ "contact": {
+ "title": "Contact Us",
+ "subtitle": "Let's Stay Connected",
+ "visit": {
+ "t": "Visit Us",
+ "d": "Oren District, Orta Iskele Street No:51 Ayris Apart 48220 Milas/Mugla"
+ },
+ "call": {
+ "t": "Call Us",
+ "d": "We are at your service 24/7 for tranquility"
+ },
+ "write": {
+ "t": "Write Us",
+ "d": "We respond within 2 hours"
+ },
+ "wa": {
+ "t": "WhatsApp",
+ "d": "Connect with us instantly for reservations or local tips."
+ },
+ "ig": {
+ "t": "Experience",
+ "d": "Follow our daily stories and coastal inspirations."
+ },
+ "hours": {
+ "t": "Hours",
+ "d": "Monday — Sunday",
+ "sub": "Check-in: 14:00 | Check-out: 11:00"
+ },
+ "btn": {
+ "map": "Open Map",
+ "call": "Call Now",
+ "mail": "Send Email",
+ "wa": "Start Chat",
+ "ig": "Follow Us"
+ }
+ },
+ "about": {
+ "title": "About Us",
+ "subtitle": "Experience unique accommodation where comfort and luxury meet with Ayris Apart.",
+ "story": {
+ "title": "Our Story",
+ "p1": "Founded in 2021, AYRIS APART set out with the vision of offering our guests an accommodation experience in the comfort of home. Located in the quietest part of Oren, we blend our modern design approach with traditional Turkish hospitality.",
+ "p2": "In our rooms where every detail is carefully thought out, we aim to provide unforgettable moments to our guests traveling for business and leisure by combining technology and comfort."
+ },
+ "why": {
+ "title": "Why Ayris Apart?",
+ "1": { "t": "Premium Location", "d": "Easy access to the sea and everywhere in the quietest part of Oren" },
+ "2": { "t": "Modern Design", "d": "Comfortable and stylish rooms with contemporary architecture" },
+ "3": { "t": "24/7 Service", "d": "Our experienced team is with you at every moment" },
+ "4": { "t": "Secure Payment", "d": "SSL certified secure reservation system" }
+ },
+ "vision": {
+ "title": "Our Vision",
+ "text": "\"Determining the quality standard in the sector and creating memories that will add value to the lives of every guest by transforming into Turkey's most reliable apart hotel chain.\""
+ }
+ },
+ "suites": {
+ "s1": { "name": "Iris", "desc": "Our most special suite carrying the colors of the rainbow, shining with uninterrupted ocean views." },
+ "s2": { "name": "Electra", "desc": "A bright living space adorned with amber tones, where peace and elegance meet." },
+ "s3": { "name": "Arke", "desc": "A sanctuary that rests your soul with its design giving a sense of lightness and freedom." },
+ "s4": { "name": "Harpy", "desc": "The suite that combines the power of the storm and the energy of the sea in a single panoramic view." },
+ "s5": { "name": "Hydaspes", "desc": "A room designed for those seeking serenity, reflecting the fluidity and purity of water." },
+ "s6": { "name": "Zephyrus", "desc": "Our breeze suite that brings the coolness of the west wind and the freshness of the garden to your balcony." },
+ "s7": { "name": "Pothos", "desc": "Accommodation where you will feel luxury in every detail, where desire and passion meet aesthetics." },
+ "s8": { "name": "Thaumas", "desc": "The suite with the widest-angle coastal view of Oren, where you will witness the wonders of the sea." },
+ "btn": {
+ "more": "Learn More"
+ }
+ },
+ "suites_page": {
+ "title": "Our Suites",
+ "subtitle": "Enjoy characterful design, peaceful ocean views, and a mythological atmosphere. Each of our rooms tells its own unique story.",
+ "list": {
+ "s1": { "name": "Iris", "desc": "Named after the rainbow messenger, this suite comes alive every morning with colors rising from the sea.", "bed": "1 King-size bed", "guests": "2 Guests" },
+ "s2": { "name": "Electra", "desc": "A comfort zone that embraces golden sunsets, enchanting with its brilliance.", "bed": "1 King-size bed", "guests": "2 Guests" },
+ "s3": { "name": "Arke", "desc": "A suite that invites the light breeze of the Aegean in, standing out with its minimalist and spacious design.", "bed": "1 Queen-size bed", "guests": "2 Guests" },
+ "s4": { "name": "Harpy", "desc": "A room with a dynamic atmosphere where you can listen to the song of sea waves and the wind.", "bed": "1 King-size bed", "guests": "2 Guests" },
+ "s5": { "name": "Hydaspes", "desc": "Peaceful interiors adorned with the sounds of water, reflecting the stillness of ancient rivers.", "bed": "1 King-size bed", "guests": "2 Guests" },
+ "s6": { "name": "Zephyrus", "desc": "An experience intertwined with nature, offering the scent of garden flowers and the coolness of the west wind.", "bed": "1 King-size bed", "guests": "2 Guests" },
+ "s7": { "name": "Pothos", "desc": "A special living space designed with an aesthetic longing, bringing romance and elegance together.", "bed": "1 King-size bed", "guests": "2 Guests" },
+ "s8": { "name": "Thaumas", "desc": "Our most comfortable and spacious suite, laying the wonders of the sea at your feet.", "bed": "2 King-size beds", "guests": "4 Guests" }
+ },
+ "details": "Explore Details"
+ },
+ "news_page": {
+ "title": "News & Stories",
+ "excerpt": "Discover stories filled with coastal charm, travel inspiration, and insider tips.",
+ "read": "Read More",
+ "list": {
+ "n1": { "title": "Hidden Gems of Oren", "excerpt": "Discover secret coves known only to locals.", "author": "Ayris Team" },
+ "n2": { "title": "Summer Cocktails", "excerpt": "Meet our new season menu.", "author": "Chef Rez" },
+ "n3": { "title": "Luxury Interior Trends", "excerpt": "The design story of Ayris Apart.", "author": "Design Team" }
+ }
+ },
+ "amenities": {
+ "title": "Amenities",
+ "cctv": "CCTV Security",
+ "fire_alarm": "Fire Alarm",
+ "parking": "Free Parking",
+ "double_bed": "Double Bed",
+ "kitchen": "Kitchen",
+ "ac": "Air Conditioning",
+ "single_bed": "Single Bed",
+ "fire_ext": "Fire Extinguisher",
+ "wifi": "Free Wi-Fi"
+ }
+}
diff --git a/dictionaries/get-dictionary.ts b/dictionaries/get-dictionary.ts
new file mode 100644
index 0000000..2da751d
--- /dev/null
+++ b/dictionaries/get-dictionary.ts
@@ -0,0 +1,9 @@
+import 'server-only'
+
+const dictionaries = {
+ en: () => import('./en.json').then((module) => module.default),
+ tr: () => import('./tr.json').then((module) => module.default),
+}
+
+export const getDictionary = async (locale: 'en' | 'tr') =>
+ dictionaries[locale]?.() ?? dictionaries.en()
diff --git a/dictionaries/tr.json b/dictionaries/tr.json
new file mode 100644
index 0000000..3dfd48d
--- /dev/null
+++ b/dictionaries/tr.json
@@ -0,0 +1,132 @@
+{
+ "nav": {
+ "about": "Hakkımızda",
+ "suites": "Odalar",
+ "news": "Haberler",
+ "contact": "İletişim",
+ "home": "Anasayfa"
+ },
+ "hero": {
+ "title": "Ayris Apart",
+ "desc": "Muğla Milas Ören'in kalbinde, rafine suitler ve unutulmaz bir konforu keşfedin. Lüks tatiliniz sizi bekliyor.",
+ "explore": "Odaları Keşfedin"
+ },
+ "welcome": {
+ "title": "Ören'in kıyısında lüks deniz suitlerine hoş geldiniz",
+ "desc": "Ege Denizi'nin kıyısında, zamansız zarafet ve sahil huzurunun mükemmel bir karışımını sunuyoruz."
+ },
+ "footer": {
+ "book": "Rezervasyon Yapın",
+ "explore": "Keşfedin",
+ "others": "Diğer",
+ "utility": "Yardımcı",
+ "socials": "Sosyal Medya",
+ "desc": "Bugün rezervasyon yapın ve Ören kıyılarında deniz kenarı lüksünü, nefes kesen manzaraları ve unutulmaz anları keşfedin."
+ },
+ "contact": {
+ "title": "Bize Ulaşın",
+ "subtitle": "Bağlantıda Kalalım",
+ "visit": {
+ "t": "Bizi Ziyaret Edin",
+ "d": "Ören Mahallesi, Orta İskele Caddesi No:51 Ayris Apart 48220 Milas/Muğla"
+ },
+ "call": {
+ "t": "Bizi Arayın",
+ "d": "Sakiniyet için 7/24 hizmetinizdeyiz"
+ },
+ "write": {
+ "t": "Bize Yazın",
+ "d": "2 saat içinde yanıtlıyoruz"
+ },
+ "wa": {
+ "t": "WhatsApp",
+ "d": "Rezervasyon veya yerel ipuçları için anında bize ulaşın."
+ },
+ "ig": {
+ "t": "Deneyim",
+ "d": "Günlük hikayelerimizi ve sahil ilhamlarımızı takip edin."
+ },
+ "hours": {
+ "t": "Saatler",
+ "d": "Pazartesi — Pazar",
+ "sub": "Giriş: 14:00 | Çıkış: 11:00"
+ },
+ "btn": {
+ "map": "Haritayı Aç",
+ "call": "Hemen Ara",
+ "mail": "E-posta Gönder",
+ "wa": "Sohbeti Başlat",
+ "ig": "Bizi Takip Et"
+ }
+ },
+ "about": {
+ "title": "Hakkımızda",
+ "subtitle": "Ayris Apart ile konfor ve lüksün buluştuğu eşsiz konaklama deneyimi yaşayın.",
+ "story": {
+ "title": "Bizim Hikayemiz",
+ "p1": "2021 yılında kurulan AYRİS APART, misafirlerimize ev konforunda konaklama deneyimi sunma vizyonuyla yola çıktı. Ören'in en sakin bölgesinde yer alan konumu ile, modern tasarım anlayışımızı geleneksel Türk misafirperverliği ile harmanlıyoruz.",
+ "p2": "Her detayın özenle düşünüldüğü odalarımızda, teknoloji ve konforu bir araya getirerek, iş ve tatil amaçlı seyahat eden misafirlerimize unutulmaz anlar yaşatmayı hedefliyoruz."
+ },
+ "why": {
+ "title": "Neden Ayris Apart?",
+ "1": { "t": "Premium Konum", "d": "Ören'in en sakin bölgesinde, denize ve her yere kolay ulaşım imkanı" },
+ "2": { "t": "Modern Tasarım", "d": "Çağdaş mimariye sahip, konforlu ve şık odalar" },
+ "3": { "t": "24/7 Hizmet", "d": "Her an yanınızda olan deneyimli ekibimiz" },
+ "4": { "t": "Güvenli Ödeme", "d": "SSL sertifikalı güvenli rezervasyon sistemi" }
+ },
+ "vision": {
+ "title": "Vizyonumuz",
+ "text": "“Türkiye'nin en güvenilir apart otel zincirine dönüşerek, her misafirimizin hayatına değer katacak anılar oluşturmak ve sektörde kalite standardını belirlemek.”"
+ }
+ },
+ "suites": {
+ "s1": { "name": "Iris", "desc": "Gökkuşağının renklerini taşıyan, kesintisiz deniz manzarasıyla parlayan en özel suitimiz." },
+ "s2": { "name": "Electra", "desc": "Kehribar tonlarıyla bezenmiş, huzur ve zarafetin buluştuğu aydınlık bir yaşam alanı." },
+ "s3": { "name": "Arke", "desc": "Hafiflik ve özgürlük hissi veren tasarımıyla, ruhunuzu dinlendiren bir sığınak." },
+ "s4": { "name": "Harpy", "desc": "Fırtınanın gücünü ve denizin enerjisini tek bir panoramik manzarada birleştiren suit." },
+ "s5": { "name": "Hydaspes", "desc": "Suyun akışkanlığını ve saflığını yansıtan, dinginlik arayanlar için tasarlanmış oda." },
+ "s6": { "name": "Zephyrus", "desc": "Batı rüzgarının serinliğini ve bahçenin ferahlığını balkonunuza taşıyan meltem suitimiz." },
+ "s7": { "name": "Pothos", "desc": "Arzu ve tutkunun estetikle buluştuğu, her detayında lüksü hissedeceğiniz konaklama." },
+ "s8": { "name": "Thaumas", "desc": "Denizin mucizelerine tanıklık edeceğiniz, Ören'in en geniş açılı sahil manzarasına sahip suit." },
+ "btn": {
+ "more": "Daha Fazla"
+ }
+ },
+ "suites_page": {
+ "title": "Odalarımız",
+ "subtitle": "Karakterli tasarımın, huzurlu okyanus manzaralarının ve mitolojik bir atmosferin tadını çıkarın. Her odamız kendine has bir hikaye anlatır.",
+ "list": {
+ "s1": { "name": "Iris", "desc": "Gökkuşağı postacısının adını taşıyan bu suit, her sabah denizden doğan renklerle canlanır.", "bed": "1 King-size yatak", "guests": "2 Misafir" },
+ "s2": { "name": "Electra", "desc": "Altın sarısı gün batımlarını kucaklayan, parlaklığıyla büyüleyen bir konfor alanı.", "bed": "1 King-size yatak", "guests": "2 Misafir" },
+ "s3": { "name": "Arke", "desc": "Ege'nin hafif meltemini içeri davet eden, minimalist ve ferah tasarımıyla öne çıkan suit.", "bed": "1 Queen-size yatak", "guests": "2 Misafir" },
+ "s4": { "name": "Harpy", "desc": "Deniz dalgalarının ve rüzgarın şarkısını dinleyebileceğiniz, dinamik bir atmosfere sahip oda.", "bed": "1 King-size yatak", "guests": "2 Misafir" },
+ "s5": { "name": "Hydaspes", "desc": "Antik nehirlerin dinginliğini yansıtan, huzur dolu su sesleriyle bezenmiş iç mekanlar.", "bed": "1 King-size yatak", "guests": "2 Misafir" },
+ "s6": { "name": "Zephyrus", "desc": "Bahçe çiçeklerinin kokusunu ve batı rüzgarının serinliğini sunan, doğayla iç içe bir deneyim.", "bed": "1 King-size yatak", "guests": "2 Misafir" },
+ "s7": { "name": "Pothos", "desc": "Estetik bir özlemle tasarlanmış, romantizm ve şıklığı bir araya getiren özel yaşam alanı.", "bed": "1 King-size yatak", "guests": "2 Misafir" },
+ "s8": { "name": "Thaumas", "desc": "Denizin harikalarını ayaklarınızın altına seren, en üst düzey konforlu ve geniş suitimiz.", "bed": "2 King-size yatak", "guests": "4 Misafir" }
+ },
+ "details": "Detayları Keşfet"
+ },
+ "news_page": {
+ "title": "Haberler & Yazılar",
+ "excerpt": "Sahil cazibesi, seyahat ilhamı ve içeriden ipuçları ile dolu hikayeleri keşfedin.",
+ "read": "Yazıyı Oku",
+ "list": {
+ "n1": { "title": "Ören'in Gizli Cevherleri", "excerpt": "Sadece yerellerin bildiği gizli koyları keşfedin.", "author": "Ayris Ekibi" },
+ "n2": { "title": "Yaz Kokteylleri", "excerpt": "Yeni sezon menümüzle tanışın.", "author": "Şef Rez" },
+ "n3": { "title": "Lüks İç Mekan Trendleri", "excerpt": "Ayris Apart'ın tasarım hikayesi.", "author": "Tasarım Ekibi" }
+ }
+ },
+ "amenities": {
+ "title": "Sunulan Olanaklar",
+ "cctv": "Güvenlik Kamerası",
+ "fire_alarm": "Yangın Dedektörü",
+ "parking": "Ücretsiz Otopark",
+ "double_bed": "Çift Kişilik Yatak",
+ "kitchen": "Mutfak",
+ "ac": "Klima",
+ "single_bed": "Tek Kişilik Yatak",
+ "fire_ext": "Yangın Tüpü",
+ "wifi": "Ücretsiz Wi-Fi"
+ }
+}
diff --git a/lib/cloudinary.ts b/lib/cloudinary.ts
new file mode 100644
index 0000000..a07912b
--- /dev/null
+++ b/lib/cloudinary.ts
@@ -0,0 +1,11 @@
+import { v2 as cloudinary } from 'cloudinary';
+
+// Configure Cloudinary with environment variables
+cloudinary.config({
+ cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
+ api_key: process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY,
+ api_secret: process.env.NEXT_PUBLIC_CLOUDINARY_API_SECRET,
+ secure: true,
+});
+
+export default cloudinary;
diff --git a/middleware.ts b/middleware.ts
new file mode 100644
index 0000000..f3d2b45
--- /dev/null
+++ b/middleware.ts
@@ -0,0 +1,26 @@
+import { NextResponse, type NextRequest } from 'next/server'
+
+let locales = ['en', 'tr']
+let defaultLocale = 'tr'
+
+export function middleware(request: NextRequest) {
+ // Check if there is any supported locale in the pathname
+ const { pathname } = request.nextUrl
+ const pathnameHasLocale = locales.some(
+ (locale) => pathname.startsWith(`/${locale}/`) || pathname === `/${locale}`
+ )
+
+ if (pathnameHasLocale) return
+
+ // Redirect if there is no locale
+ request.nextUrl.pathname = `/${defaultLocale}${pathname}`
+ // e.g. incoming is /about -> /tr/about
+ return NextResponse.redirect(request.nextUrl)
+}
+
+export const config = {
+ matcher: [
+ // Skip all internal paths (_next)
+ '/((?!api|_next/static|_next/image|favicon.ico|logo.png|images|.*\\..*).*)',
+ ],
+}
diff --git a/next.config.ts b/next.config.ts
index e9ffa30..38c449b 100644
--- a/next.config.ts
+++ b/next.config.ts
@@ -1,7 +1,18 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ images: {
+ remotePatterns: [
+ {
+ protocol: "https",
+ hostname: "images.unsplash.com",
+ },
+ {
+ protocol: "https",
+ hostname: "res.cloudinary.com",
+ },
+ ],
+ },
};
export default nextConfig;
diff --git a/package-lock.json b/package-lock.json
index 3bcb929..96b1483 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -8,7 +8,12 @@
"name": "ayrisapart",
"version": "0.1.0",
"dependencies": {
+ "cloudinary": "^2.9.0",
+ "dotenv": "^17.4.2",
+ "framer-motion": "^12.38.0",
+ "lucide-react": "^1.8.0",
"next": "16.2.4",
+ "next-cloudinary": "^6.17.5",
"react": "19.2.4",
"react-dom": "19.2.4"
},
@@ -276,6 +281,63 @@
"node": ">=6.9.0"
}
},
+ "node_modules/@cloudinary-util/types": {
+ "version": "1.5.10",
+ "resolved": "https://registry.npmjs.org/@cloudinary-util/types/-/types-1.5.10.tgz",
+ "integrity": "sha512-n5lrm7SdAXhgWEbkSJKHZGnaoO9G/g4WYS6HYnq/k4nLj79sYfQZOoKjyR8hF2iyLRdLkT+qlk68RNFFv5tKew==",
+ "license": "MIT"
+ },
+ "node_modules/@cloudinary-util/url-loader": {
+ "version": "5.10.4",
+ "resolved": "https://registry.npmjs.org/@cloudinary-util/url-loader/-/url-loader-5.10.4.tgz",
+ "integrity": "sha512-gHkdvOaV+rlcwuIT7Vqd0ts/H5bsH4+bwFten/gIZ8oRjzdTBvgIY3R6F8bbJt0pFIEfpFEQLe4rPkl0NNqEWg==",
+ "license": "MIT",
+ "dependencies": {
+ "@cloudinary-util/types": "1.5.10",
+ "@cloudinary-util/util": "3.3.2",
+ "@cloudinary/url-gen": "1.15.0",
+ "zod": "^3.22.4"
+ }
+ },
+ "node_modules/@cloudinary-util/url-loader/node_modules/@cloudinary-util/util": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/@cloudinary-util/util/-/util-3.3.2.tgz",
+ "integrity": "sha512-Cc0iFxzfl7fcOXuznpeZFGYC885Of/vDgccRDnhTe/8Rf8YKv2PjLtezyo0VgmdA/CpeZy29NCXAsf6liokbwg==",
+ "license": "MIT"
+ },
+ "node_modules/@cloudinary-util/url-loader/node_modules/zod": {
+ "version": "3.25.76",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz",
+ "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
+ },
+ "node_modules/@cloudinary-util/util": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/@cloudinary-util/util/-/util-4.0.0.tgz",
+ "integrity": "sha512-S4xcou/3A7l5o+bcKlw2VHBNgwups7/0lbVDT/cO5YmtrcEYXgj6LGmwnjvpTm/x571VPVN8x5jWdT3rLZiKJQ==",
+ "license": "MIT"
+ },
+ "node_modules/@cloudinary/transformation-builder-sdk": {
+ "version": "1.21.2",
+ "resolved": "https://registry.npmjs.org/@cloudinary/transformation-builder-sdk/-/transformation-builder-sdk-1.21.2.tgz",
+ "integrity": "sha512-ehOgKUaP+Nvuf7B0TosmB8iilL0kdiVjzjl8tIK06cjvsNnwSJI3xP9nEJmKkvqNxwwFwvYXT+mxUTqnSv9JOA==",
+ "license": "MIT",
+ "dependencies": {
+ "@cloudinary/url-gen": "^1.7.0"
+ }
+ },
+ "node_modules/@cloudinary/url-gen": {
+ "version": "1.15.0",
+ "resolved": "https://registry.npmjs.org/@cloudinary/url-gen/-/url-gen-1.15.0.tgz",
+ "integrity": "sha512-bjU67eZxLUgoRy/Plli4TQio7q6P31OYqnEgXxeN9TKXrzr6h0DeEdIUhKI9gy3HkEBWXWWJIPh7j7gkOJPnyA==",
+ "license": "MIT",
+ "dependencies": {
+ "@cloudinary/transformation-builder-sdk": "^1.10.0"
+ }
+ },
"node_modules/@emnapi/core": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz",
@@ -2715,6 +2777,18 @@
"integrity": "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==",
"license": "MIT"
},
+ "node_modules/cloudinary": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/cloudinary/-/cloudinary-2.9.0.tgz",
+ "integrity": "sha512-F3iKMOy4y0zy0bi5JBp94SC7HY7i/ImfTPSUV07iJmRzH1Iz8WavFfOlJTR1zvYM/xKGoiGZ3my/zy64In0IQQ==",
+ "license": "MIT",
+ "dependencies": {
+ "lodash": "^4.17.21"
+ },
+ "engines": {
+ "node": ">=9"
+ }
+ },
"node_modules/color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
@@ -2916,6 +2990,18 @@
"node": ">=0.10.0"
}
},
+ "node_modules/dotenv": {
+ "version": "17.4.2",
+ "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-17.4.2.tgz",
+ "integrity": "sha512-nI4U3TottKAcAD9LLud4Cb7b2QztQMUEfHbvhTH09bqXTxnSie8WnjPALV/WMCrJZ6UV/qHJ6L03OqO3LcdYZw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://dotenvx.com"
+ }
+ },
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
@@ -3706,6 +3792,33 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/framer-motion": {
+ "version": "12.38.0",
+ "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.38.0.tgz",
+ "integrity": "sha512-rFYkY/pigbcswl1XQSb7q424kSTQ8q6eAC+YUsSKooHQYuLdzdHjrt6uxUC+PRAO++q5IS7+TamgIw1AphxR+g==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-dom": "^12.38.0",
+ "motion-utils": "^12.36.0",
+ "tslib": "^2.4.0"
+ },
+ "peerDependencies": {
+ "@emotion/is-prop-valid": "*",
+ "react": "^18.0.0 || ^19.0.0",
+ "react-dom": "^18.0.0 || ^19.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@emotion/is-prop-valid": {
+ "optional": true
+ },
+ "react": {
+ "optional": true
+ },
+ "react-dom": {
+ "optional": true
+ }
+ }
+ },
"node_modules/function-bind": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -4936,6 +5049,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/lodash": {
+ "version": "4.18.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.18.1.tgz",
+ "integrity": "sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==",
+ "license": "MIT"
+ },
"node_modules/lodash.merge": {
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
@@ -4966,6 +5085,15 @@
"yallist": "^3.0.2"
}
},
+ "node_modules/lucide-react": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-1.8.0.tgz",
+ "integrity": "sha512-WuvlsjngSk7TnTBJ1hsCy3ql9V9VOdcPkd3PKcSmM34vJD8KG6molxz7m7zbYFgICwsanQWmJ13JlYs4Zp7Arw==",
+ "license": "ISC",
+ "peerDependencies": {
+ "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
+ }
+ },
"node_modules/magic-string": {
"version": "0.30.21",
"resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
@@ -5033,6 +5161,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/motion-dom": {
+ "version": "12.38.0",
+ "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.38.0.tgz",
+ "integrity": "sha512-pdkHLD8QYRp8VfiNLb8xIBJis1byQ9gPT3Jnh2jqfFtAsWUA3dEepDlsWe/xMpO8McV+VdpKVcp+E+TGJEtOoA==",
+ "license": "MIT",
+ "dependencies": {
+ "motion-utils": "^12.36.0"
+ }
+ },
+ "node_modules/motion-utils": {
+ "version": "12.36.0",
+ "resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.36.0.tgz",
+ "integrity": "sha512-eHWisygbiwVvf6PZ1vhaHCLamvkSbPIeAYxWUuL3a2PD/TROgE7FvfHWTIH4vMl798QLfMw15nRqIaRDXTlYRg==",
+ "license": "MIT"
+ },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -5134,6 +5277,21 @@
}
}
},
+ "node_modules/next-cloudinary": {
+ "version": "6.17.5",
+ "resolved": "https://registry.npmjs.org/next-cloudinary/-/next-cloudinary-6.17.5.tgz",
+ "integrity": "sha512-YIyIWw5Ds30f4rnED+E9ssLUd94FOPTtbkO2KUvOcw9z4irOEIpb1goxMxbn2EUBnIGQOd6uUf1gFizjME7pMg==",
+ "license": "MIT",
+ "dependencies": {
+ "@cloudinary-util/types": "1.5.10",
+ "@cloudinary-util/url-loader": "5.10.4",
+ "@cloudinary-util/util": "4.0.0"
+ },
+ "peerDependencies": {
+ "next": "^12 || ^13 || ^14 || >=15.0.0-rc || ^15",
+ "react": "^17 || ^18 || >=19.0.0-beta || ^19"
+ }
+ },
"node_modules/next/node_modules/postcss": {
"version": "8.4.31",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.31.tgz",
diff --git a/package.json b/package.json
index 66da400..fa76012 100644
--- a/package.json
+++ b/package.json
@@ -9,7 +9,12 @@
"lint": "eslint"
},
"dependencies": {
+ "cloudinary": "^2.9.0",
+ "dotenv": "^17.4.2",
+ "framer-motion": "^12.38.0",
+ "lucide-react": "^1.8.0",
"next": "16.2.4",
+ "next-cloudinary": "^6.17.5",
"react": "19.2.4",
"react-dom": "19.2.4"
},
diff --git a/public/ayrisapart/Daire 1/photo_1_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_1_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..d1580e6
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_1_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_2_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_2_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..b1dfa86
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_2_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_3_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_3_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..468e177
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_3_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_4_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_4_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..6c87a8e
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_4_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_5_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_5_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..1a8bcc2
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_5_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_6_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_6_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..d997f2d
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_6_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_7_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_7_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..8ad04e4
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_7_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_8_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_8_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..5adedd5
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_8_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 1/photo_9_2024-04-05_12-32-09.jpg b/public/ayrisapart/Daire 1/photo_9_2024-04-05_12-32-09.jpg
new file mode 100644
index 0000000..d5f2554
Binary files /dev/null and b/public/ayrisapart/Daire 1/photo_9_2024-04-05_12-32-09.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_1_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_1_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..9a76f41
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_1_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_2_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_2_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..1a88ecb
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_2_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_3_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_3_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..9073f9b
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_3_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_4_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_4_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..b2fca15
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_4_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_5_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_5_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..374479c
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_5_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_6_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_6_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..0009411
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_6_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_7_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_7_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..734005f
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_7_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 2/photo_8_2024-04-05_16-04-34.jpg b/public/ayrisapart/Daire 2/photo_8_2024-04-05_16-04-34.jpg
new file mode 100644
index 0000000..5daf6e0
Binary files /dev/null and b/public/ayrisapart/Daire 2/photo_8_2024-04-05_16-04-34.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_1_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_1_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..05b9ba5
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_1_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_2_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_2_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..12dec8b
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_2_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_3_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_3_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..9ca05dc
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_3_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_4_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_4_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..5d9e23c
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_4_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_5_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_5_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..f827470
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_5_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_6_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_6_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..f66a736
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_6_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_7_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_7_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..0288fbb
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_7_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_8_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_8_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..a267c3f
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_8_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 3/photo_9_2024-04-05_16-06-09.jpg b/public/ayrisapart/Daire 3/photo_9_2024-04-05_16-06-09.jpg
new file mode 100644
index 0000000..939fe15
Binary files /dev/null and b/public/ayrisapart/Daire 3/photo_9_2024-04-05_16-06-09.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_10_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_10_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..0467385
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_10_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_1_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_1_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..3fc38da
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_1_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_2_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_2_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..83c2c96
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_2_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_3_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_3_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..80e014b
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_3_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_4_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_4_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..3897536
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_4_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_5_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_5_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..3f32d53
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_5_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_6_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_6_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..207e4ea
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_6_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_7_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_7_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..b9d4862
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_7_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_8_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_8_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..a26e91f
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_8_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 4/photo_9_2024-04-05_16-07-01.jpg b/public/ayrisapart/Daire 4/photo_9_2024-04-05_16-07-01.jpg
new file mode 100644
index 0000000..c3c73bb
Binary files /dev/null and b/public/ayrisapart/Daire 4/photo_9_2024-04-05_16-07-01.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_10_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_10_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..36973df
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_10_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_11_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_11_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..c249428
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_11_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_12_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_12_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..6ac178b
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_12_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_1_2024-05-04_15-32-44.jpg b/public/ayrisapart/Daire 5/photo_1_2024-05-04_15-32-44.jpg
new file mode 100644
index 0000000..36973df
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_1_2024-05-04_15-32-44.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_1_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_1_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..cd31fb7
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_1_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_2_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_2_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..760c52c
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_2_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_3_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_3_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..c77835d
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_3_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_4_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_4_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..0e59c36
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_4_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_5_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_5_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..0c87c90
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_5_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_6_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_6_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..2ccceaf
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_6_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_7_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_7_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..826f335
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_7_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_8_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_8_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..d77d874
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_8_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 5/photo_9_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 5/photo_9_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..b619be4
Binary files /dev/null and b/public/ayrisapart/Daire 5/photo_9_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_10_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_10_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..36973df
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_10_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_11_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_11_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..c249428
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_11_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_12_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_12_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..6ac178b
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_12_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_1_2024-05-04_15-32-44.jpg b/public/ayrisapart/Daire 6/photo_1_2024-05-04_15-32-44.jpg
new file mode 100644
index 0000000..36973df
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_1_2024-05-04_15-32-44.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_1_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_1_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..cd31fb7
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_1_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_2_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_2_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..760c52c
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_2_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_3_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_3_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..c77835d
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_3_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_4_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_4_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..0e59c36
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_4_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_5_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_5_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..0c87c90
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_5_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_6_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_6_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..2ccceaf
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_6_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_7_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_7_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..826f335
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_7_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_8_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_8_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..d77d874
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_8_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 6/photo_9_2024-05-04_15-33-08.jpg b/public/ayrisapart/Daire 6/photo_9_2024-05-04_15-33-08.jpg
new file mode 100644
index 0000000..b619be4
Binary files /dev/null and b/public/ayrisapart/Daire 6/photo_9_2024-05-04_15-33-08.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_10_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_10_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..be4c27f
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_10_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_1_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_1_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..978eaa7
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_1_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_2_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_2_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..1a030c2
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_2_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_3_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_3_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..0683bbf
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_3_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_4_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_4_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..de79e6a
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_4_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_5_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_5_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..604d428
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_5_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_6_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_6_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..e07bf45
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_6_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_7_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_7_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..76fdc56
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_7_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_8_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_8_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..8082306
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_8_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 7/photo_9_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 7/photo_9_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..62815b5
Binary files /dev/null and b/public/ayrisapart/Daire 7/photo_9_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_10_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_10_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..be4c27f
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_10_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_1_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_1_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..978eaa7
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_1_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_2_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_2_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..1a030c2
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_2_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_3_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_3_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..0683bbf
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_3_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_4_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_4_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..de79e6a
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_4_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_5_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_5_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..604d428
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_5_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_6_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_6_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..e07bf45
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_6_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_7_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_7_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..76fdc56
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_7_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_8_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_8_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..8082306
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_8_2024-05-04_15-33-34.jpg differ
diff --git a/public/ayrisapart/Daire 8/photo_9_2024-05-04_15-33-34.jpg b/public/ayrisapart/Daire 8/photo_9_2024-05-04_15-33-34.jpg
new file mode 100644
index 0000000..62815b5
Binary files /dev/null and b/public/ayrisapart/Daire 8/photo_9_2024-05-04_15-33-34.jpg differ
diff --git a/public/logo.png b/public/logo.png
new file mode 100644
index 0000000..426e67d
Binary files /dev/null and b/public/logo.png differ
diff --git a/scripts/upload.mjs b/scripts/upload.mjs
new file mode 100644
index 0000000..bcf669c
--- /dev/null
+++ b/scripts/upload.mjs
@@ -0,0 +1,77 @@
+import { v2 as cloudinary } from 'cloudinary';
+import { promises as fs } from 'fs';
+import path from 'path';
+import dotenv from 'dotenv';
+
+// Load environment variables from .env.local
+dotenv.config({ path: '.env.local' });
+
+cloudinary.config({
+ cloud_name: process.env.NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME,
+ api_key: process.env.NEXT_PUBLIC_CLOUDINARY_API_KEY,
+ api_secret: process.env.NEXT_PUBLIC_CLOUDINARY_API_SECRET,
+ secure: true,
+});
+
+async function* getFiles(dir) {
+ const dirents = await fs.readdir(dir, { withFileTypes: true });
+ for (const dirent of dirents) {
+ const res = path.resolve(dir, dirent.name);
+ if (dirent.isDirectory()) {
+ yield* getFiles(res);
+ } else {
+ yield res;
+ }
+ }
+}
+
+const uploadEverything = async (sourceRoot) => {
+ try {
+ const results = [];
+ const absoluteRoot = path.resolve(sourceRoot);
+
+ console.log(`🚀 Starting recursive upload from: ${sourceRoot}\n`);
+
+ for await (const filePath of getFiles(absoluteRoot)) {
+ const relativePath = path.relative(absoluteRoot, filePath);
+ const ext = path.extname(filePath).toLowerCase();
+
+ if (['.jpg', '.jpeg', '.png', '.webp', '.svg'].includes(ext)) {
+ // Calculate the folder path inside Cloudinary
+ // It will be: ayrisapart/Daire 1/image.jpg
+ const cloudinaryFolder = path.join('ayrisapart', path.dirname(relativePath)).replace(/\\/g, '/');
+ const filename = path.basename(filePath, ext);
+
+ console.log(`⬆️ Uploading: ${relativePath}...`);
+
+ const result = await cloudinary.uploader.upload(filePath, {
+ folder: cloudinaryFolder,
+ public_id: filename,
+ use_filename: true,
+ unique_filename: false,
+ });
+
+ console.log(`✅ Success: ${result.secure_url}`);
+ results.push({
+ localPath: relativePath,
+ url: result.secure_url,
+ public_id: result.public_id
+ });
+ }
+ }
+
+ // Save final mapping
+ await fs.writeFile(
+ 'cloudinary-assets.json',
+ JSON.stringify(results, null, 2)
+ );
+
+ console.log(`\n✨ GREAT SUCCESS! ${results.length} images uploaded.`);
+ console.log(`📄 Mapping details saved to: cloudinary-assets.json`);
+ } catch (error) {
+ console.error('❌ Error during recursive upload:', error);
+ }
+};
+
+const target = process.argv[2] || 'public/ayrisapart';
+uploadEverything(target);