Update routing in next.config.ts to redirect "/tercih-robotu" to the hero form, add simple-icons dependency in package.json, and enhance database indexing for improved query performance. Remove unused SVG files and update metadata across various pages for better SEO and clarity.
All checks were successful
Deploy / deploy (push) Successful in 14m14s

This commit is contained in:
bilalgursen
2026-08-01 17:28:38 +03:00
parent 569b9e5da2
commit 8cf0c3267d
76 changed files with 5050 additions and 255 deletions

90
src/lib/rehber.ts Normal file
View File

@@ -0,0 +1,90 @@
import fs from "node:fs";
import path from "node:path";
import { marked } from "marked";
/**
* Rehber makaleleri: content/rehber/*.md dosyaları build sırasında okunur ve
* statik HTML'e gömülür (sayfalar generateStaticParams + dynamicParams=false
* ile tamamen prerender edilir; runtime'da fs erişimi olmaz).
*
* Frontmatter elle parse edilir (yalnızca düz `anahtar: değer` satırları) —
* 10 makale için gray-matter bağımlılığına gerek yok.
*/
export type RehberOzet = {
slug: string;
baslik: string;
aciklama: string;
/** ISO tarih — Article JSON-LD datePublished */
tarih: string;
};
export type RehberYazi = RehberOzet & { html: string };
const REHBER_DIZIN = path.join(process.cwd(), "content", "rehber");
function parseFrontmatter(raw: string): {
meta: Record<string, string>;
body: string;
} {
const match = raw.match(/^---\r?\n([\s\S]*?)\r?\n---\r?\n?/);
if (!match) return { meta: {}, body: raw };
const meta: Record<string, string> = {};
for (const satir of match[1].split(/\r?\n/)) {
const ayrac = satir.indexOf(":");
if (ayrac === -1) continue;
const anahtar = satir.slice(0, ayrac).trim();
const deger = satir
.slice(ayrac + 1)
.trim()
.replace(/^["']|["']$/g, "");
if (anahtar) meta[anahtar] = deger;
}
return { meta, body: raw.slice(match[0].length) };
}
function oku(slug: string): RehberYazi | null {
const dosya = path.join(REHBER_DIZIN, `${slug}.md`);
if (!fs.existsSync(dosya)) return null;
const { meta, body } = parseFrontmatter(fs.readFileSync(dosya, "utf8"));
if (!meta.baslik || !meta.aciklama || !meta.tarih) {
throw new Error(
`rehber: ${slug}.md frontmatter eksik (baslik/aciklama/tarih zorunlu)`,
);
}
return {
slug,
baslik: meta.baslik,
aciklama: meta.aciklama,
tarih: meta.tarih,
html: marked.parse(body, { gfm: true, async: false }),
};
}
export function getAllRehberSlugs(): string[] {
if (!fs.existsSync(REHBER_DIZIN)) return [];
return fs
.readdirSync(REHBER_DIZIN)
.filter((f) => f.endsWith(".md"))
.map((f) => f.replace(/\.md$/, ""))
.sort();
}
export function getRehber(slug: string): RehberYazi | null {
// path traversal koruması: slug yalnızca dosya adı olabilir
if (!/^[a-z0-9-]+$/.test(slug)) return null;
return oku(slug);
}
export function getAllRehberler(): RehberOzet[] {
return getAllRehberSlugs()
.map((slug) => oku(slug))
.filter((y): y is RehberYazi => y !== null)
.map(({ slug, baslik, aciklama, tarih }) => ({
slug,
baslik,
aciklama,
tarih,
}))
.sort((a, b) => b.tarih.localeCompare(a.tarih));
}