248 lines
11 KiB
TypeScript
248 lines
11 KiB
TypeScript
import { getServiceBySlug, getLocationBySlug, getProjectsByService, getSettings } from "@/app/actions";
|
||
import Image from "next/image";
|
||
import Link from "next/link";
|
||
import { ArrowRight, CheckCircle2 } from "lucide-react";
|
||
import { Metadata } from "next";
|
||
import { notFound } from "next/navigation";
|
||
|
||
interface Props {
|
||
params: Promise<{
|
||
slug: string;
|
||
location: string;
|
||
}>;
|
||
}
|
||
|
||
export async function generateMetadata({ params }: Props): Promise<Metadata> {
|
||
const { slug, location: locationSlug } = await params;
|
||
const [service, location] = await Promise.all([
|
||
getServiceBySlug(slug),
|
||
getLocationBySlug(locationSlug)
|
||
]);
|
||
|
||
if (!service || !location) return {};
|
||
|
||
const title = `${location.name} ${service.title} | Muğla Dijital`;
|
||
const description = `${location.name} bölgesinde profesyonel ${service.title.toLowerCase()} hizmetleri. Muğla Dijital Medya Ajansı ile markanızı zirveye taşıyın.`;
|
||
const url = `https://mugladijitalmedya.com/services/${slug}/${locationSlug}`;
|
||
|
||
return {
|
||
title,
|
||
description,
|
||
alternates: {
|
||
canonical: url,
|
||
},
|
||
openGraph: {
|
||
title,
|
||
description,
|
||
url,
|
||
images: [
|
||
{
|
||
url: "https://mugladijitalmedya.com/og-image.jpg", // Default OG image
|
||
width: 1200,
|
||
height: 630,
|
||
alt: title,
|
||
}
|
||
],
|
||
type: 'website',
|
||
}
|
||
};
|
||
}
|
||
|
||
export default async function ServiceLocationPage({ params }: Props) {
|
||
const { slug, location: locationSlug } = await params;
|
||
|
||
// Vercel Best Practice: async-parallel - Fetch independent operations in parallel
|
||
const service = await getServiceBySlug(slug);
|
||
if (!service) notFound();
|
||
|
||
const [location, settings, projects] = await Promise.all([
|
||
getLocationBySlug(locationSlug),
|
||
getSettings(),
|
||
getProjectsByService(service.title)
|
||
]);
|
||
|
||
if (!location) {
|
||
notFound();
|
||
}
|
||
|
||
const breadcrumbLd = {
|
||
"@context": "https://schema.org",
|
||
"@type": "BreadcrumbList",
|
||
"itemListElement": [
|
||
{
|
||
"@type": "ListItem",
|
||
"position": 1,
|
||
"name": "Ana Sayfa",
|
||
"item": "https://mugladijitalmedya.com"
|
||
},
|
||
{
|
||
"@type": "ListItem",
|
||
"position": 2,
|
||
"name": "Hizmetlerimiz",
|
||
"item": "https://mugladijitalmedya.com/services"
|
||
},
|
||
{
|
||
"@type": "ListItem",
|
||
"position": 3,
|
||
"name": service.title,
|
||
"item": `https://mugladijitalmedya.com/services/${service.slug}`
|
||
},
|
||
{
|
||
"@type": "ListItem",
|
||
"position": 4,
|
||
"name": location.name,
|
||
"item": `https://mugladijitalmedya.com/services/${service.slug}/${location.slug}`
|
||
}
|
||
]
|
||
};
|
||
|
||
const serviceLd = {
|
||
"@context": "https://schema.org",
|
||
"@type": "Service",
|
||
"serviceType": service.title,
|
||
"provider": {
|
||
"@type": "Organization",
|
||
"name": "Muğla Dijital",
|
||
"url": "https://mugladijitalmedya.com"
|
||
},
|
||
"areaServed": {
|
||
"@type": "City",
|
||
"name": location.name
|
||
},
|
||
"description": `${location.name} bölgesinde profesyonel ${service.title.toLowerCase()} çözümleri.`,
|
||
"offers": {
|
||
"@type": "Offer",
|
||
"availability": "https://schema.org/InStock",
|
||
"areaServed": location.name
|
||
}
|
||
};
|
||
|
||
return (
|
||
<main className="min-h-screen bg-[#f5f5f0] text-black pt-24">
|
||
<script
|
||
type="application/ld+json"
|
||
dangerouslySetInnerHTML={{ __html: JSON.stringify(breadcrumbLd) }}
|
||
/>
|
||
<script
|
||
type="application/ld+json"
|
||
dangerouslySetInnerHTML={{ __html: JSON.stringify(serviceLd) }}
|
||
/>
|
||
{/* Hero Section */}
|
||
<section className="pt-24 pb-16 px-6 md:px-12 border-b border-black/10">
|
||
<div className="max-w-7xl mx-auto">
|
||
<span className="text-[10px] tracking-[0.2em] uppercase text-black/40 block mb-6">
|
||
{location.name} / {service.title}
|
||
</span>
|
||
<h1 className="editorial-headline text-4xl md:text-6xl lg:text-[5.5rem] text-black uppercase leading-tight">
|
||
{location.name} <br />
|
||
<span className="text-primary">{service.title}</span> <br />
|
||
Çözümleri.
|
||
</h1>
|
||
<p className="text-black/40 text-[14px] max-w-2xl leading-relaxed mt-10">
|
||
{location.name} bölgesindeki işletmeniz için profesyonel {service.title.toLowerCase()} hizmetleri sunuyoruz.
|
||
Markanızın dijital varlığını {location.name} ruhuna uygun, estetik ve stratejik bir dille inşa ediyoruz.
|
||
</p>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Content & Features */}
|
||
<section className="py-24 px-6 md:px-12">
|
||
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-16 items-center">
|
||
<div className="space-y-12">
|
||
<div>
|
||
<h2 className="text-2xl font-light uppercase tracking-widest mb-6">Neler Sunuyoruz?</h2>
|
||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||
{[
|
||
"Profesyonel Ekipman",
|
||
"Yüksek Çözünürlük",
|
||
"Hızlı Teslimat",
|
||
"Stratejik Planlama",
|
||
"Yaratıcı Kurgu",
|
||
"Müşteri Odaklılık"
|
||
].map((feature) => (
|
||
<div key={feature} className="flex items-center gap-3 text-[12px] text-black/60">
|
||
<CheckCircle2 className="w-4 h-4 text-primary" />
|
||
{feature}
|
||
</div>
|
||
))}
|
||
</div>
|
||
</div>
|
||
|
||
<div className="prose prose-sm text-black/60 leading-relaxed max-w-none">
|
||
<p>
|
||
{location.name}, Muğla'nın en değerli bölgelerinden biri olarak kendine has bir kimliğe sahip.
|
||
Muğla Dijital olarak biz, bu bölgedeki rekabetin farkındayız ve markanızı öne çıkaracak
|
||
<strong> {service.title.toLowerCase()}</strong> stratejilerini hayata geçiriyoruz.
|
||
</p>
|
||
<p>
|
||
{service.description || "Hizmetimiz hakkında detaylı bilgi için bizimle iletişime geçebilirsiniz."}
|
||
</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="relative aspect-square bg-black/5 border border-black/10 overflow-hidden group">
|
||
<Image
|
||
src={service.image_url || "https://images.unsplash.com/photo-1473968512647-3e447244af8f?q=80&w=800"}
|
||
alt={`${location.name} ${service.title}`}
|
||
fill
|
||
className="object-cover grayscale group-hover:grayscale-0 transition-all duration-700"
|
||
/>
|
||
</div>
|
||
</div>
|
||
</section>
|
||
|
||
{/* Related Projects */}
|
||
{projects.length > 0 && (
|
||
<section className="py-24 px-6 md:px-12 bg-white/30 border-t border-black/10">
|
||
<div className="max-w-7xl mx-auto">
|
||
<div className="flex justify-between items-end mb-12">
|
||
<div>
|
||
<span className="text-[10px] tracking-[0.2em] uppercase text-black/40 block mb-4">Referanslarımız</span>
|
||
<h2 className="editorial-headline text-3xl md:text-4xl text-black">
|
||
Örnek <span className="text-primary">Çalışmalar</span>
|
||
</h2>
|
||
</div>
|
||
</div>
|
||
|
||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
|
||
{projects.map((project: any) => (
|
||
<Link key={project.id} href={`/works/${project.slug}`} className="group block focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-4 rounded-sm" aria-label={`${project.title} projesini incele`}>
|
||
<div className="space-y-4">
|
||
<div className="relative aspect-video overflow-hidden border border-black/10 bg-black/5">
|
||
<Image
|
||
src={project.hero_image}
|
||
alt={project.title}
|
||
fill
|
||
className="object-cover transition-transform duration-500 group-hover:scale-105"
|
||
/>
|
||
</div>
|
||
<h3 className="text-[12px] uppercase tracking-wider group-hover:text-primary transition-colors">
|
||
{project.title}
|
||
</h3>
|
||
</div>
|
||
</Link>
|
||
))}
|
||
</div>
|
||
</div>
|
||
</section>
|
||
)}
|
||
|
||
{/* CTA */}
|
||
<section className="py-24 px-6 text-center border-t border-black/10">
|
||
<div className="max-w-4xl mx-auto space-y-8">
|
||
<h2 className="editorial-headline text-3xl md:text-5xl text-black uppercase">
|
||
{location.name} İçin <br /><span className="text-primary">Strateji Geliştirelim.</span>
|
||
</h2>
|
||
<p className="text-black/40 text-[13px] tracking-[0.1em]">
|
||
{location.name} bölgesindeki projeniz için profesyonel destek almaya hazır mısınız?
|
||
</p>
|
||
<Link href="/contact" className="button-primary mx-auto inline-flex items-center gap-2 focus-visible:outline-2 focus-visible:outline-primary focus-visible:outline-offset-4" aria-label={`${location.name} projeniz için teklif alın`}>
|
||
Teklif Al
|
||
<ArrowRight className="w-3 h-3" aria-hidden="true" />
|
||
</Link>
|
||
</div>
|
||
</section>
|
||
</main>
|
||
);
|
||
}
|