Files
Ege Can Komur e45c44721f feat: WP'den header + kart stilleri + blog sidebar widget
Header (components/header.tsx + header-scroll.tsx):
- WP'deki 'floating pill' efekti — scroll'da küçülen + yuvarlanan + gölgeli
- 3 sütun grid: Logo | Nav | CTA
- Hizmetler mega menu dropdown — 2 sütunlu (Web&Yazılım + Dijital Pazarlama)
  - Hover'da açılır, services tablosundan dinamik
  - Alt linkle 'Tüm hizmetleri gör'
- Mobil için scroll-down'da gizlenir
- Sağda 'Ücretsiz Teklif' CTA butonu + telefon link

Kart stilleri (WP'ye eşlendi):
- ServicesGrid:
  - Gradient icon (sky → purple) ile WP'deki '🎨 🚀 📱' emoji yerine ikon
  - Hover: -translate-y-2 + colored shadow + scale icon
  - ArrowUpRight ikonu absolute, hover'da görünür
- ProjectsGrid:
  - Kategori bazlı renkli badge (Kurumsal navy, Klinik cyan, Portfolio violet, …)
  - Hover: image scale-105 + gradient overlay
  - 5/3 aspect ratio (daha WP-like)

Public sidebar (components/content-sidebar.tsx):
- CTA card (gradient navy→sky): Telefon + WhatsApp
- Son yazılar (4 adet, kapak + başlık + tarih)
- Etiketler (en sık kullanılan 10)
- Hizmetler menü (6 adet)
- Site analizi lead magnet

Blog detay sayfası (/blog/[slug]):
- Tek sütun → 2 sütun grid (content + sidebar)
- sticky sidebar, max-w-7xl
- Aynı pattern hizmet/proje detay sayfalarına da uygulanabilir

37 route, build temiz.
2026-05-20 18:45:02 +03:00

189 lines
6.9 KiB
TypeScript
Raw Permalink 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 Image from "next/image";
import Link from "next/link";
import { ArrowRight, MessageCircle, Phone, Tag } from "lucide-react";
import {
getSiteSettings,
listPublishedPosts,
listServices,
} from "@/lib/data";
import { siteConfig } from "@/lib/site-config";
interface Props {
/**
* Hangi yazıyı/sayfayı görüntülüyoruz — listede gizlemek için.
*/
currentSlug?: string;
}
export async function ContentSidebar({ currentSlug }: Props) {
const [settings, services, posts] = await Promise.all([
getSiteSettings(),
listServices(),
listPublishedPosts({ limit: 5 }),
]);
const phoneRaw = settings?.contact_phone_raw ?? siteConfig.contact.phoneRaw;
const phone = settings?.contact_phone ?? siteConfig.contact.phone;
const waCleaned = phoneRaw.replace(/[^\d]/g, "");
const waMessage = settings?.whatsapp_message ?? "";
const waHref = `https://wa.me/${waCleaned}${
waMessage ? `?text=${encodeURIComponent(waMessage)}` : ""
}`;
const otherPosts = posts.filter((p) => p.slug !== currentSlug).slice(0, 4);
// Etiket sayımı (tüm yazılardan toplu)
const tagCount = new Map<string, number>();
posts.forEach((p) =>
(p.tags ?? []).forEach((t) =>
tagCount.set(t, (tagCount.get(t) ?? 0) + 1),
),
);
const topTags = Array.from(tagCount.entries())
.sort((a, b) => b[1] - a[1])
.slice(0, 10);
return (
<aside className="space-y-6 lg:sticky lg:top-24 lg:self-start">
{/* CTA card */}
<div className="overflow-hidden rounded-2xl border border-[var(--border)] bg-gradient-to-br from-[var(--navy)] to-[var(--sky-600)] p-6 text-white">
<h3 className="text-base font-bold">Projeniz mi var?</h3>
<p className="mt-2 text-sm text-white/80">
Ücretsiz keşif görüşmesi için bizi arayın veya WhatsApp'tan yazın.
</p>
<div className="mt-4 space-y-2">
<a
href={`tel:${phoneRaw}`}
className="flex items-center justify-center gap-2 rounded-xl bg-white px-4 py-2.5 text-sm font-semibold text-[var(--navy)] transition hover:bg-blue-50"
>
<Phone className="size-3.5" />
{phone}
</a>
<a
href={waHref}
target="_blank"
rel="noopener noreferrer"
className="flex items-center justify-center gap-2 rounded-xl bg-[#25d366] px-4 py-2.5 text-sm font-semibold text-white transition hover:bg-[#1ebe5d]"
>
<MessageCircle className="size-3.5" />
WhatsApp'tan yaz
</a>
</div>
</div>
{/* Diğer yazılar */}
{otherPosts.length > 0 && (
<div className="rounded-2xl border border-[var(--border)] bg-white p-5">
<div className="flex items-center justify-between">
<h3 className="text-sm font-bold uppercase tracking-wider text-[var(--navy)]">
Son Yazılar
</h3>
<Link
href="/blog"
className="text-xs text-[var(--sky-600)] hover:text-[var(--navy)]"
>
Tümü
</Link>
</div>
<ul className="mt-4 space-y-3">
{otherPosts.map((p) => (
<li key={p.$id}>
<Link
href={`/blog/${p.slug}`}
className="group flex gap-3"
>
<div className="relative size-16 shrink-0 overflow-hidden rounded-lg bg-[var(--navy-50)]">
{p.cover_image ? (
<Image
src={p.cover_image}
alt={p.title}
fill
sizes="64px"
className="object-cover"
/>
) : (
<div className="flex h-full items-center justify-center text-lg font-bold text-[var(--navy)]/30">
{p.title.charAt(0)}
</div>
)}
</div>
<div className="min-w-0 flex-1">
<p className="line-clamp-2 text-sm font-medium leading-snug text-[var(--navy)] transition-colors group-hover:text-[var(--sky-600)]">
{p.title}
</p>
{p.published_at && (
<p className="mt-1 text-[11px] text-[var(--muted)]">
{new Date(p.published_at).toLocaleDateString("tr-TR")}
</p>
)}
</div>
</Link>
</li>
))}
</ul>
</div>
)}
{/* Etiketler */}
{topTags.length > 0 && (
<div className="rounded-2xl border border-[var(--border)] bg-white p-5">
<h3 className="flex items-center gap-1.5 text-sm font-bold uppercase tracking-wider text-[var(--navy)]">
<Tag className="size-3.5" />
Etiketler
</h3>
<div className="mt-3 flex flex-wrap gap-1.5">
{topTags.map(([tag]) => (
<span
key={tag}
className="rounded-md bg-[var(--navy-50)] px-2.5 py-1 text-xs font-medium text-[var(--navy-700)] hover:bg-[var(--sky-50)]"
>
{tag}
</span>
))}
</div>
</div>
)}
{/* Hizmetler */}
{services.length > 0 && (
<div className="rounded-2xl border border-[var(--border)] bg-white p-5">
<h3 className="text-sm font-bold uppercase tracking-wider text-[var(--navy)]">
Hizmetlerimiz
</h3>
<ul className="mt-3 space-y-1.5">
{services.slice(0, 6).map((s) => (
<li key={s.slug}>
<Link
href={`/hizmetler/${s.slug}`}
className="flex items-center justify-between rounded-lg px-2 py-1.5 text-sm text-[var(--foreground)] transition hover:bg-[var(--navy-50)] hover:text-[var(--navy)]"
>
<span>{s.title}</span>
<ArrowRight className="size-3 text-[var(--muted)]" />
</Link>
</li>
))}
</ul>
</div>
)}
{/* Site analizi lead magnet */}
<div className="rounded-2xl border border-[var(--sky)]/30 bg-[var(--sky-50)]/50 p-5">
<h3 className="text-sm font-bold text-[var(--navy)]">
Ücretsiz Site Analizi
</h3>
<p className="mt-2 text-xs leading-relaxed text-[var(--muted)]">
Sitenizin SEO, hız ve dönüşüm performansını ücretsiz değerlendirelim.
24 saat içinde rapor e-postanızda.
</p>
<Link
href="/site-analizi"
className="mt-3 inline-flex items-center gap-1 text-xs font-semibold text-[var(--sky-600)] hover:text-[var(--navy)]"
>
Hemen başla
<ArrowRight className="size-3" />
</Link>
</div>
</aside>
);
}