feat: i18n fixes, blog rename, footer cleanup, and contact info update

- Rename /news route to /blog across all pages, links, and sitemap
- Fix hardcoded English text in Experiences, QuoteSection, and Footer
  by wiring all content through the TR/EN dictionaries
- Clean up Footer: remove non-existent page links, add contact column
- Update contact info: new phone numbers, bilgi@ email, No:71 address,
  Instagram @ayrisapart link
- Add suppressHydrationWarning to <body> to silence browser-extension
  attribute mismatch errors
- Add sizes prop to all fill-mode Next.js Image components

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-02 18:05:30 +03:00
co-authored by Claude Sonnet 4.6
parent 433252a05d
commit 40b4434a7b
34 changed files with 2864 additions and 509 deletions
+17 -11
View File
@@ -8,21 +8,21 @@ 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 },
{ 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, price: dict.suites_page.list.s1.price },
{ 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_4_2024-04-05_16-04-34.jpg', bed: dict.suites_page.list.s2.bed, guests: dict.suites_page.list.s2.guests, price: dict.suites_page.list.s2.price },
{ 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_8_2024-04-05_16-06-09.jpg', bed: dict.suites_page.list.s3.bed, guests: dict.suites_page.list.s3.guests, price: dict.suites_page.list.s3.price },
{ 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_8_2024-04-05_16-07-01.jpg', bed: dict.suites_page.list.s4.bed, guests: dict.suites_page.list.s4.guests, price: dict.suites_page.list.s4.price },
{ 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, price: dict.suites_page.list.s5.price },
{ 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-33-08.jpg', bed: dict.suites_page.list.s6.bed, guests: dict.suites_page.list.s6.guests, price: dict.suites_page.list.s6.price },
{ 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_5_2024-05-04_15-33-34.jpg', bed: dict.suites_page.list.s7.bed, guests: dict.suites_page.list.s7.guests, price: dict.suites_page.list.s7.price },
{ 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_9_2024-05-04_15-33-34.jpg', bed: dict.suites_page.list.s8.bed, guests: dict.suites_page.list.s8.guests, price: dict.suites_page.list.s8.price },
]
return (
<main className="bg-[#FAF7F0] min-h-screen z-60 ">
<main className="bg-[#FAF7F0] min-h-screen">
{/* HEADER SECTION */}
<section className="pt-44 pb-20 px-6 ">
<section className="pt-44 pb-20 px-6">
<div className="max-w-4xl mx-auto text-center space-y-10">
<motion.h1
initial={{ opacity: 0, y: 30 }}
@@ -45,7 +45,7 @@ export default function SuitesClient({ lang, dict }: { lang: string, dict: any }
{/* SUITES LIST SECTION */}
<section className="pb-32 px-6 md:px-12 max-w-[1400px] mx-auto">
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-24">
<div className="grid grid-cols-1 md:grid-cols-2 gap-x-12 gap-y-32">
{suites.map((suite, idx) => (
<motion.div
key={suite.id}
@@ -61,8 +61,14 @@ export default function SuitesClient({ lang, dict }: { lang: string, dict: any }
src={suite.image}
alt={suite.name}
fill
sizes="(max-width: 768px) 100vw, 50vw"
className="object-cover transition-transform duration-1000 group-hover:scale-105"
/>
{/* Price Badge */}
<div className="absolute top-6 right-6 bg-white/90 backdrop-blur-md px-6 py-3 rounded-full shadow-xl">
<span className="text-[#1A1A1A] font-serif text-xl">{suite.price}</span>
<span className="text-[#1A1A1A]/40 text-xs ml-1 uppercase tracking-widest">/ {lang === 'tr' ? 'Gece' : 'Night'}</span>
</div>
</div>
{/* Info */}
+54 -37
View File
@@ -7,12 +7,13 @@ 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
// Mapping the 8 mythological suites with their Cloudinary assets and dictionary prices
const suitesData: Record<string, any> = {
'iris': {
number: '01',
name: dict.suites_page.list.s1.name,
description: dict.suites_page.list.s1.desc,
price: dict.suites_page.list.s1.price,
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,
@@ -26,7 +27,8 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
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',
price: dict.suites_page.list.s2.price,
mainImage: 'https://res.cloudinary.com/du7xohbct/image/upload/v1776606648/ayrisapart/Daire%202/photo_4_2024-04-05_16-04-34.jpg',
guests: dict.suites_page.list.s2.guests,
bed: dict.suites_page.list.s2.bed,
gallery: [
@@ -39,6 +41,7 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
number: '03',
name: dict.suites_page.list.s3.name,
description: dict.suites_page.list.s3.desc,
price: dict.suites_page.list.s3.price,
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,
@@ -52,6 +55,7 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
number: '04',
name: dict.suites_page.list.s4.name,
description: dict.suites_page.list.s4.desc,
price: dict.suites_page.list.s4.price,
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,
@@ -65,6 +69,7 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
number: '05',
name: dict.suites_page.list.s5.name,
description: dict.suites_page.list.s5.desc,
price: dict.suites_page.list.s5.price,
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,
@@ -78,6 +83,7 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
number: '06',
name: dict.suites_page.list.s6.name,
description: dict.suites_page.list.s6.desc,
price: dict.suites_page.list.s6.price,
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,
@@ -91,6 +97,7 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
number: '07',
name: dict.suites_page.list.s7.name,
description: dict.suites_page.list.s7.desc,
price: dict.suites_page.list.s7.price,
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,
@@ -104,6 +111,7 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
number: '08',
name: dict.suites_page.list.s8.name,
description: dict.suites_page.list.s8.desc,
price: dict.suites_page.list.s8.price,
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,
@@ -131,7 +139,7 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
{/* Title and Brief Header */}
<div className="space-y-8">
<motion.h1
<motion.h1
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="text-6xl md:text-[88px] font-serif text-[#1A1A1A] tracking-tight leading-none uppercase"
@@ -153,19 +161,20 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
</div>
{/* Main Visual */}
<motion.div
<motion.div
initial={{ opacity: 0, scale: 0.98 }}
animate={{ opacity: 1, scale: 1 }}
transition={{ duration: 1 }}
className="aspect-[21/9] relative overflow-hidden rounded-[2px] shadow-2xl"
>
<Image
src={suite.mainImage}
alt={suite.name}
fill
className="object-cover"
priority
/>
<Image
src={suite.mainImage}
alt={suite.name}
fill
sizes="100vw"
className="object-cover"
priority
/>
</motion.div>
</div>
</section>
@@ -174,45 +183,53 @@ export default function SuiteDetailClient({ lang, id, dict }: { lang: string, id
<section className="py-24 px-6 md:px-16 max-w-[1400px] mx-auto">
<div className="grid grid-cols-1 md:grid-cols-12 gap-16 border-b border-[#1A1A1A]/10 pb-20">
<div className="md:col-span-4">
<h2 className="text-4xl font-serif text-[#1A1A1A] uppercase tracking-tight">{lang === 'tr' ? 'Suit Hakkında' : 'About Suite'}</h2>
<h2 className="text-4xl font-serif text-[#1A1A1A] uppercase tracking-tight">{lang === 'tr' ? 'Suit Hakkında' : 'About Suite'}</h2>
</div>
<div className="md:col-span-8 space-y-12">
<p className="text-[#1A1A1A]/70 text-2xl leading-relaxed italic max-w-2xl">
{suite.description}
</p>
<Link
href={`/${lang}/reservation`}
className="inline-flex items-center space-x-3 text-[14px] font-bold tracking-[0.4em] uppercase border-b-2 border-[#1A1A1A] pb-2 group"
>
<span className="transform group-hover:translate-x-1 transition-transform">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" className="rotate-45">
<line x1="12" y1="19" x2="12" y2="5" />
<polyline points="5 12 12 5 19 12" />
</svg>
</span>
<span>{dict.footer.book}</span>
</Link>
<div className="flex justify-between items-baseline">
<span className="text-[13px] font-bold tracking-[0.3em] uppercase text-[#1A1A1A]/40">{lang === 'tr' ? 'Başlayan fiyatlar' : 'Starting at'}</span>
<div className="text-right">
<span className="text-6xl md:text-8xl font-serif text-[#1A1A1A]">{suite.price}</span>
<span className="text-[#1A1A1A]/40 text-lg font-medium ml-2 uppercase tracking-widest">/ {lang === 'tr' ? 'Gece' : 'Night'}</span>
</div>
</div>
<p className="text-[#1A1A1A]/70 text-2xl leading-relaxed italic max-w-2xl">
{suite.description}
</p>
<Link
href={`/${lang}/reservation`}
className="inline-flex items-center space-x-3 text-[14px] font-bold tracking-[0.4em] uppercase border-b-2 border-[#1A1A1A] pb-2 group"
>
<span className="transform group-hover:translate-x-1 transition-transform">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" className="rotate-45">
<line x1="12" y1="19" x2="12" y2="5" />
<polyline points="5 12 12 5 19 12" />
</svg>
</span>
<span>{dict.footer.book}</span>
</Link>
</div>
</div>
{/* INTEGRATED AMENITIES COMPONENT */}
<div className="mt-20">
<Amenities dict={dict} />
<Amenities dict={dict} />
</div>
</section>
{/* SECTION 3: GALLERY GRID */}
<section className="py-24 px-6 md:px-16 max-w-[1400px] mx-auto pb-44">
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="aspect-square relative overflow-hidden rounded-[2px] shadow-lg">
<Image src={suite.gallery[0]} alt="Gallery" fill className="object-cover hover:scale-105 transition-transform duration-1000" />
</div>
<div className="aspect-square relative overflow-hidden rounded-[2px] shadow-lg">
<Image src={suite.gallery[1]} alt="Gallery" fill className="object-cover hover:scale-105 transition-transform duration-1000" />
</div>
<div className="md:col-span-2 aspect-[21/9] relative overflow-hidden rounded-[2px] shadow-lg">
<Image src={suite.gallery[2]} alt="Gallery" fill className="object-cover hover:scale-105 transition-transform duration-1000" />
</div>
<div className="aspect-square relative overflow-hidden rounded-[2px] shadow-lg">
<Image src={suite.gallery[0]} alt="Gallery" fill sizes="(max-width: 768px) 100vw, 50vw" className="object-cover hover:scale-105 transition-transform duration-1000" />
</div>
<div className="aspect-square relative overflow-hidden rounded-[2px] shadow-lg">
<Image src={suite.gallery[1]} alt="Gallery" fill sizes="(max-width: 768px) 100vw, 50vw" className="object-cover hover:scale-105 transition-transform duration-1000" />
</div>
<div className="md:col-span-2 aspect-[21/9] relative overflow-hidden rounded-[2px] shadow-lg">
<Image src={suite.gallery[2]} alt="Gallery" fill sizes="100vw" className="object-cover hover:scale-105 transition-transform duration-1000" />
</div>
</div>
</section>