Markdown'daki \`\`\`mermaid çitleri artık yazıyı parçalara bölüyor ve şemalar üründeki ortak el çizimi bileşeniyle (ElCizimiSema) çiziliyor; çitte "%% aria:" satırı zorunlu, "%% altyazi:" figcaption veriyor. Tercih dönemi aramalarına dayanan dört yeni yazı: merkezi yerleştirme algoritması, OBP hesabı, üniversite kayıt rehberi ve yerleşememe/istenmeyen bölüm karar ağacı — her biri risk renk dilinde birer şemayla. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
154 lines
4.9 KiB
TypeScript
154 lines
4.9 KiB
TypeScript
import type { Metadata } from "next";
|
||
import Link from "next/link";
|
||
import { notFound } from "next/navigation";
|
||
import { ChevronRight } from "lucide-react";
|
||
import { getAllRehberSlugs, getAllRehberler, getRehber } from "@/lib/rehber";
|
||
import { JsonLd, articleJsonLd, breadcrumbJsonLd } from "@/lib/seo";
|
||
import { CtaSiraForm } from "@/components/cta-sira-form";
|
||
import { ElCizimiSema } from "@/components/el-cizimi-sema";
|
||
import { RehberKapak } from "@/components/rehber-kapak";
|
||
import { SiteFooter } from "@/components/site-footer";
|
||
|
||
export function generateStaticParams() {
|
||
const slugs = getAllRehberSlugs();
|
||
if (slugs.length === 0) {
|
||
throw new Error("rehber: content/rehber altında hiç makale yok");
|
||
}
|
||
return slugs.map((slug) => ({ slug }));
|
||
}
|
||
|
||
export async function generateMetadata({
|
||
params,
|
||
}: {
|
||
params: Promise<{ slug: string }>;
|
||
}): Promise<Metadata> {
|
||
const { slug } = await params;
|
||
const yazi = getRehber(slug);
|
||
if (!yazi) return {};
|
||
return {
|
||
title: yazi.baslik,
|
||
description: yazi.aciklama,
|
||
alternates: { canonical: `/rehber/${slug}` },
|
||
openGraph: {
|
||
type: "article",
|
||
title: yazi.baslik,
|
||
description: yazi.aciklama,
|
||
publishedTime: yazi.tarih,
|
||
},
|
||
};
|
||
}
|
||
|
||
export default async function RehberYaziPage({
|
||
params,
|
||
}: {
|
||
params: Promise<{ slug: string }>;
|
||
}) {
|
||
const { slug } = await params;
|
||
const yazi = getRehber(slug);
|
||
if (!yazi) notFound();
|
||
|
||
const digerYazilar = getAllRehberler()
|
||
.filter((y) => y.slug !== slug)
|
||
.slice(0, 4);
|
||
|
||
return (
|
||
<>
|
||
<main className="mx-auto w-full max-w-3xl px-4 py-12 sm:py-16">
|
||
<JsonLd
|
||
data={articleJsonLd({
|
||
title: yazi.baslik,
|
||
description: yazi.aciklama,
|
||
path: `/rehber/${slug}`,
|
||
datePublished: yazi.tarih,
|
||
})}
|
||
/>
|
||
<JsonLd
|
||
data={breadcrumbJsonLd([
|
||
{ name: "Ana Sayfa", path: "/" },
|
||
{ name: "Rehber", path: "/rehber" },
|
||
{ name: yazi.baslik, path: `/rehber/${slug}` },
|
||
])}
|
||
/>
|
||
|
||
<nav
|
||
aria-label="breadcrumb"
|
||
className="flex items-center gap-1 text-xs text-slate-500"
|
||
>
|
||
<Link href="/" className="hover:text-primary hover:underline">
|
||
Ana Sayfa
|
||
</Link>
|
||
<ChevronRight className="size-3" aria-hidden />
|
||
<Link href="/rehber" className="hover:text-primary hover:underline">
|
||
Rehber
|
||
</Link>
|
||
</nav>
|
||
|
||
<article>
|
||
<RehberKapak baslik={yazi.baslik} className="mt-6 shadow-sm" />
|
||
<h1 className="mt-8 font-heading text-3xl font-bold text-slate-900 sm:text-4xl">
|
||
{yazi.baslik}
|
||
</h1>
|
||
<p className="mt-3 text-base leading-7 text-slate-600">
|
||
{yazi.aciklama}
|
||
</p>
|
||
<div
|
||
className="mt-8 text-[15px] leading-7 text-slate-700
|
||
[&_h2]:mt-10 [&_h2]:font-heading [&_h2]:text-xl [&_h2]:font-bold [&_h2]:text-slate-900
|
||
[&_h3]:mt-6 [&_h3]:font-heading [&_h3]:text-base [&_h3]:font-bold [&_h3]:text-slate-900
|
||
[&_p]:mt-3
|
||
[&_a]:font-medium [&_a]:text-primary hover:[&_a]:underline
|
||
[&_strong]:font-semibold [&_strong]:text-slate-900
|
||
[&_ul]:mt-3 [&_ul]:list-disc [&_ul]:space-y-1.5 [&_ul]:pl-6
|
||
[&_ol]:mt-3 [&_ol]:list-decimal [&_ol]:space-y-1.5 [&_ol]:pl-6
|
||
[&_table]:mt-4 [&_table]:w-full [&_table]:border-collapse [&_table]:text-sm
|
||
[&_th]:border [&_th]:border-slate-200 [&_th]:bg-slate-50 [&_th]:px-3 [&_th]:py-2 [&_th]:text-left [&_th]:font-semibold
|
||
[&_td]:border [&_td]:border-slate-200 [&_td]:px-3 [&_td]:py-2
|
||
[&_blockquote]:mt-4 [&_blockquote]:border-l-4 [&_blockquote]:border-primary/30 [&_blockquote]:pl-4 [&_blockquote]:italic [&_blockquote]:text-slate-600"
|
||
>
|
||
{yazi.parcalar.map((parca, i) =>
|
||
parca.tip === "html" ? (
|
||
<div
|
||
key={i}
|
||
dangerouslySetInnerHTML={{ __html: parca.html }}
|
||
/>
|
||
) : (
|
||
<ElCizimiSema
|
||
key={i}
|
||
tanim={parca.sema.tanim}
|
||
ariaLabel={parca.sema.ariaLabel}
|
||
figcaption={parca.sema.altyazi}
|
||
/>
|
||
),
|
||
)}
|
||
</div>
|
||
</article>
|
||
|
||
<div className="mt-12">
|
||
<CtaSiraForm />
|
||
</div>
|
||
|
||
{digerYazilar.length > 0 ? (
|
||
<section className="mt-12">
|
||
<h2 className="font-heading text-xl font-bold text-slate-900">
|
||
Diğer rehber yazıları
|
||
</h2>
|
||
<ul className="mt-3 space-y-2">
|
||
{digerYazilar.map((y) => (
|
||
<li key={y.slug}>
|
||
<Link
|
||
href={`/rehber/${y.slug}`}
|
||
className="text-sm font-medium text-primary hover:underline"
|
||
>
|
||
{y.baslik}
|
||
</Link>
|
||
</li>
|
||
))}
|
||
</ul>
|
||
</section>
|
||
) : null}
|
||
</main>
|
||
<SiteFooter />
|
||
</>
|
||
);
|
||
}
|