Files
kovakyazilim/app/(site)/hizmetler/[slug]/page.tsx
T
Ege Can Komur fdfa556d42 feat: pill telefon → Ara butonu + hizmet detay zengin sidebar + unique hero
1) Header pill mode:
   - Pill aktifken telefon link gizlenir
   - Yerine kompakt 'Ara' butonu görünür (data-pill-show='true')
   - header-scroll.tsx hem hide hem show class'larını yönetiyor

2) Hizmet detay sayfası — yeni unique hero (ServiceHero component):
   - Gradient gradient icon (sky → purple, glow ile)
   - Profesyonel hizmet badge'i
   - Gradient text başlık
   - 4 'quick trust' satırı (teslim, destek, ücretsiz taslak, yerel)
   - 3 CTA: Teklif al (navy) / WhatsApp (yeşil) / Telefon ara
   - Sağda: hero_image varsa görsel + 'Şimdi başla' floating badge
   - Yoksa: dekoratif dark card + animasyonlu nokta deseni + glow +
     floating '100% Memnuniyet' ve '150+ Proje' kartları

3) Hizmet detay sayfası — sidebar (ServiceSidebar component):
   - QuickLeadForm (ad + telefon)
   - Gradient CTA card (telefon + WhatsApp butonları)
   - 'Risk almazsınız' garanti mini card
   - Diğer hizmetler tam listesi (icon + isim, hover'da gradient)
   - Site analizi lead magnet kartı

   Önceki versiyonda sadece 1 boş CTA + 1 boş diğer hizmetler vardı —
   artık doluyu doluya sidebar.

4) Layout: lg:grid-cols-[2fr_1fr] → lg:grid-cols-[1.5fr_1fr]
   - Sidebar daha geniş, içerik orantılı dağıldı
2026-05-20 19:01:24 +03:00

125 lines
4.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import type { Metadata } from "next";
import { notFound } from "next/navigation";
import { CheckCircle2 } from "lucide-react";
import { renderContent } from "@/lib/content-render";
import { getServiceBySlug, getSiteSettings, listProjects } from "@/lib/data";
import { buildMetadata } from "@/lib/seo";
import { ProjectsGrid } from "@/components/projects-grid";
import { SectionTitle } from "@/components/section-title";
import { FaqList } from "@/components/faq-list";
import { ServiceHero } from "@/components/service-hero";
import { ServiceSidebar } from "@/components/service-sidebar";
import type { FaqItem } from "@/lib/types";
export async function generateMetadata({
params,
}: {
params: Promise<{ slug: string }>;
}): Promise<Metadata> {
const { slug } = await params;
const service = await getServiceBySlug(slug);
if (!service) return { title: "Hizmet bulunamadı" };
return buildMetadata(`/hizmetler/${slug}`, {
title: service.title,
description: service.description.slice(0, 160),
});
}
function parseFaq(items?: string[] | null): FaqItem[] {
if (!items) return [];
const out: FaqItem[] = [];
for (const raw of items) {
try {
const obj = JSON.parse(raw) as Partial<FaqItem>;
if (obj.q && obj.a) out.push({ q: obj.q, a: obj.a });
} catch {
const [q, a] = raw.split("|||").map((s) => s.trim());
if (q && a) out.push({ q, a });
}
}
return out;
}
export default async function ServiceDetailPage({
params,
}: {
params: Promise<{ slug: string }>;
}) {
const { slug } = await params;
const service = await getServiceBySlug(slug);
if (!service) notFound();
const [relatedProjects, settings] = await Promise.all([
listProjects({ serviceSlug: slug, limit: 6 }),
getSiteSettings(),
]);
const faqItems = parseFaq(service.faq);
const html = renderContent(service.content);
return (
<>
<ServiceHero service={service} settings={settings} />
<div className="mx-auto grid max-w-7xl gap-12 px-6 py-16 lg:grid-cols-[1.5fr_1fr]">
<div>
{service.features && service.features.length > 0 && (
<section className="mb-12">
<h2 className="text-2xl font-bold text-[var(--navy)]">
Bu hizmet kapsamında
</h2>
<ul className="mt-6 grid gap-3 sm:grid-cols-2">
{service.features.map((f) => (
<li
key={f}
className="flex items-start gap-2 rounded-xl border border-[var(--border)] bg-white p-4"
>
<CheckCircle2 className="mt-0.5 size-5 shrink-0 text-[var(--sky-600)]" />
<span className="text-sm text-[var(--foreground)]">{f}</span>
</li>
))}
</ul>
</section>
)}
{html && (
<article
className="prose prose-lg max-w-none text-[var(--foreground)]"
dangerouslySetInnerHTML={{ __html: html }}
/>
)}
{faqItems.length > 0 && (
<section className="mt-12">
<h2 className="text-2xl font-bold text-[var(--navy)]">
Sıkça sorulan sorular
</h2>
<div className="mt-6">
<FaqList items={faqItems} />
</div>
</section>
)}
</div>
<ServiceSidebar currentSlug={slug} />
</div>
{relatedProjects.length > 0 && (
<section className="border-t border-[var(--border)] bg-[var(--navy-50)]/40 py-20">
<div className="mx-auto max-w-7xl px-6">
<SectionTitle
align="left"
eyebrow="Referanslar"
title={`${service.title} alanındaki projelerimiz`}
description="Bu hizmette tamamladığımız işlerden seçkiler."
/>
<div className="mt-10">
<ProjectsGrid projects={relatedProjects} />
</div>
</div>
</section>
)}
</>
);
}