Blog and contact (and about/pricing/legal) pages rendered a stripped-down header (logo + auth buttons only) with no nav — the site nav "disappeared". Extracted the landing header into a shared <SiteHeader> (logo, nav, theme toggle, auth-aware actions, mobile menu) used on every public page for consistent UX. - new components/site-header.tsx (nav links work from any route via /#…) - landing nav gains Blog + İletişim so all pages share the same 5-link nav - about, contact, pricing, blog, blog/$slug, kvkk, privacy, terms → SiteHeader - demo keeps its purpose-built demo header (sticky + theme + CTA) typecheck + biome clean. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
99 lines
3.5 KiB
TypeScript
99 lines
3.5 KiB
TypeScript
import { usePageMeta } from "@/hooks/use-page-meta";
|
||
import { SiteHeader } from "@/components/site-header";
|
||
import { useBlogPosts } from "@/hooks/use-blog";
|
||
import { Button } from "@sase/ui";
|
||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@sase/ui";
|
||
import { Link, createFileRoute } from "@tanstack/react-router";
|
||
|
||
export const Route = createFileRoute("/blog")({
|
||
component: BlogPage,
|
||
});
|
||
|
||
type PostCard = { title: string; description: string; date: string; slug: string };
|
||
|
||
// Original hand-authored posts. Kept so they never disappear; auto-published
|
||
// posts from the content pipeline are merged in from the API below.
|
||
const staticPosts: PostCard[] = [
|
||
{
|
||
title: "Şase Numarası (VIN) Nedir? Nasıl Okunur?",
|
||
description:
|
||
"17 haneli VIN kodunun her bir bölümünün ne anlama geldiğini, araç geçmişini nasıl ortaya çıkarabileceğinizi adım adım anlatıyoruz.",
|
||
date: "2026-02-10",
|
||
slug: "vin-nedir-nasil-okunur",
|
||
},
|
||
{
|
||
title: "Orijinal Parça mı, Muadil Parça mı?",
|
||
description:
|
||
"OEM ve aftermarket parçalar arasındaki farkları, avantaj ve dezavantajlarını karşılaştırmalı olarak inceliyoruz.",
|
||
date: "2026-01-28",
|
||
slug: "orijinal-mi-muadil-mi",
|
||
},
|
||
{
|
||
title: "Yedek Parça Aramada Dijital Dönüşüm",
|
||
description:
|
||
"Geleneksel katalog yöntemlerinden dijital platformlara geçiş sürecini ve sektöre etkilerini ele alıyoruz.",
|
||
date: "2026-01-15",
|
||
slug: "dijital-donusum",
|
||
},
|
||
{
|
||
title: "Sase.tr ile Doğru Parçayı İlk Seferde Bulun",
|
||
description:
|
||
"Platform özelliklerini kullanarak VIN bazlı arama, şema görüntüleme ve parça eşleştirme rehberi.",
|
||
date: "2026-01-05",
|
||
slug: "dogru-parcayi-bulun",
|
||
},
|
||
];
|
||
|
||
function BlogPage() {
|
||
usePageMeta({
|
||
title: "Blog — Sase.tr | Şase & Yedek Parça Rehberi",
|
||
description: "Şase numarası okuma, OEM vs muadil parça, dijital dönüşüm ve daha fazlası.",
|
||
canonical: "https://sase.tr/blog",
|
||
});
|
||
|
||
const { data: apiPosts } = useBlogPosts();
|
||
|
||
// Merge static + API posts, dedupe by slug (static wins), newest first.
|
||
const bySlug = new Map<string, PostCard>();
|
||
for (const p of staticPosts) bySlug.set(p.slug, p);
|
||
for (const p of apiPosts ?? []) {
|
||
if (bySlug.has(p.slug)) continue;
|
||
bySlug.set(p.slug, {
|
||
slug: p.slug,
|
||
title: p.title,
|
||
description: p.metaDescription ?? "",
|
||
date: p.publishedAt.slice(0, 10),
|
||
});
|
||
}
|
||
const posts = [...bySlug.values()].sort((a, b) => b.date.localeCompare(a.date));
|
||
|
||
return (
|
||
<div className="min-h-screen">
|
||
<SiteHeader />
|
||
|
||
<main className="container mx-auto max-w-4xl px-4 py-16">
|
||
<h1 className="text-4xl font-bold">Blog</h1>
|
||
<p className="mt-4 text-lg text-muted-foreground">
|
||
Yedek parça sektörü, araç bakımı ve Sase.tr hakkında güncel yazılar.
|
||
</p>
|
||
|
||
<div className="mt-12 grid gap-6 sm:grid-cols-2">
|
||
{posts.map((post) => (
|
||
<Link key={post.slug} to="/blog/$slug" params={{ slug: post.slug }}>
|
||
<Card className="h-full transition hover:border-foreground/20">
|
||
<CardHeader>
|
||
<CardDescription>{post.date}</CardDescription>
|
||
<CardTitle className="text-lg">{post.title}</CardTitle>
|
||
</CardHeader>
|
||
<CardContent>
|
||
<p className="text-sm text-muted-foreground">{post.description}</p>
|
||
</CardContent>
|
||
</Card>
|
||
</Link>
|
||
))}
|
||
</div>
|
||
</main>
|
||
</div>
|
||
);
|
||
}
|