fix: p7/p4 denetim bulguları — derin sayfa sıra yılı ve başlık uzunluğu, giriş sayacı, rybbit host
- derin /bolum ve /universite sayfalarında sıra aralığı hangi yıldan geldiğini söyler (2025 / 2024 / 2024–2025); 2024 sırası '2025 verisi' diye sunulmaz - <title> yuvarlanmış rakamlarla ve şablon eki olmadan ≤~86 karakter - giriş formunda tek geri sayım interval'i (çift sayaç butonu erken açıyordu) - RYBBIT_HOST sonundaki '/' atılır Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,12 @@ import {
|
||||
sayfaMetadata,
|
||||
ustSegmentOgGorseli,
|
||||
} from "@/lib/seo";
|
||||
import { KATALOG_CTA_ACIKLAMA, SAYFA_BOYU, sayfaDilimi } from "./sayfalama";
|
||||
import {
|
||||
KATALOG_CTA_ACIKLAMA,
|
||||
SAYFA_BOYU,
|
||||
sayfaDilimi,
|
||||
siraYiliEtiketi,
|
||||
} from "./sayfalama";
|
||||
import { BolumProgramListesi } from "./bolum-program-listesi";
|
||||
import { VeriKaynagi } from "./veri-kaynagi";
|
||||
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
|
||||
@@ -60,16 +65,28 @@ function bolumSayfaDilimi(bolum: BolumDetay, sayfa: number) {
|
||||
let minSira: number | null = null;
|
||||
let maxSira: number | null = null;
|
||||
let verisiz = 0;
|
||||
// Sırası 2025'te olmayıp 2024'ten gelen satırlar: aralık metni yılı dürüstçe
|
||||
// söylesin (tablonun Sıralama sütunu bu satırlarda "—" gösterir).
|
||||
let yalniz2024 = 0;
|
||||
for (const p of dilim) {
|
||||
const efektif = p.sira2025 ?? p.sira2024;
|
||||
if (efektif == null) {
|
||||
verisiz += 1;
|
||||
continue;
|
||||
}
|
||||
if (p.sira2025 == null) yalniz2024 += 1;
|
||||
if (minSira == null || efektif < minSira) minSira = efektif;
|
||||
if (maxSira == null || efektif > maxSira) maxSira = efektif;
|
||||
}
|
||||
return { tumProgramlar, dilim, minSira, maxSira, verisiz };
|
||||
return { tumProgramlar, dilim, minSira, maxSira, verisiz, yalniz2024 };
|
||||
}
|
||||
|
||||
/** <title> için kısa sıra: 2.425.061 → "2,43 mn", 95.400 → "95 bin". */
|
||||
function kisaSira(n: number): string {
|
||||
if (n >= 1_000_000) {
|
||||
return `${(n / 1e6).toLocaleString("tr-TR", { maximumFractionDigits: 2 })} mn`;
|
||||
}
|
||||
return n >= 10_000 ? `${Math.round(n / 1000)} bin` : sayi(n);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,15 +99,17 @@ function siraAraligiMetni({
|
||||
minSira,
|
||||
maxSira,
|
||||
verisiz,
|
||||
yalniz2024,
|
||||
}: ReturnType<typeof bolumSayfaDilimi>): string | null {
|
||||
if (dilim.length === 0) return null;
|
||||
if (minSira == null || maxSira == null) {
|
||||
return "taban verisi olmayan programlar";
|
||||
}
|
||||
const yil = siraYiliEtiketi(yalniz2024, dilim.length - verisiz);
|
||||
const aralik =
|
||||
minSira === maxSira
|
||||
? `taban sırası ${sayi(minSira)} olan programlar`
|
||||
: `taban sırası ${sayi(minSira)}–${sayi(maxSira)} arası programlar`;
|
||||
? `${yil} taban sırası ${sayi(minSira)} olan programlar`
|
||||
: `${yil} taban sırası ${sayi(minSira)}–${sayi(maxSira)} arası programlar`;
|
||||
return verisiz > 0 ? `${aralik} ile taban verisi olmayanlar` : aralik;
|
||||
}
|
||||
|
||||
@@ -102,17 +121,20 @@ export function bolumSayfaMetadata(slug: string, sayfa: number): Metadata {
|
||||
const sayfaDilim = bolumSayfaDilimi(bolum, sayfa);
|
||||
const aralik = siraAraligiMetni(sayfaDilim);
|
||||
const { minSira, maxSira } = sayfaDilim;
|
||||
// <title> kısa kalsın: aralığın yalnız rakamları; açıklama tam cümleyi taşır.
|
||||
// <title> kısa kalsın (arama sonucunda ayırt edici kısım kesilmesin):
|
||||
// yuvarlanmış rakamlar, kök şablonun " — KolayTercih" eki yok; açıklama tam
|
||||
// cümleyi taşır. "s. N" yuvarlamada çakışan iki sayfayı yine ayırır.
|
||||
const baslikEki =
|
||||
minSira != null && maxSira != null
|
||||
? minSira === maxSira
|
||||
? `Sıra ${sayi(minSira)}, Sayfa ${sayfa}`
|
||||
: `Sıra ${sayi(minSira)}–${sayi(maxSira)}, Sayfa ${sayfa}`
|
||||
? `Sıra ${kisaSira(minSira)}, s. ${sayfa}`
|
||||
: `Sıra ${kisaSira(minSira)}–${kisaSira(maxSira)}, s. ${sayfa}`
|
||||
: `Sayfa ${sayfa}`;
|
||||
return sayfaMetadata({
|
||||
title: `${bolum.ad} Taban Puanları 2026 (${baslikEki})`,
|
||||
const baslik = `${bolum.ad} Taban Puanları (${baslikEki})`;
|
||||
const meta = sayfaMetadata({
|
||||
title: baslik,
|
||||
description: aralik
|
||||
? `${bolum.ad} taban puanları, sayfa ${sayfa}: ${aralik}. Toplam ${stats.toplam} programın 2025 yerleştirme verileri — taban puanı, başarı sıralaması ve kontenjan.`
|
||||
? `${bolum.ad} taban puanları, sayfa ${sayfa}: ${aralik}. Toplam ${stats.toplam} programın son yerleştirme verileri (2025; 2025'te verisi olmayanlarda 2024) — taban puanı, başarı sıralaması ve kontenjan.`
|
||||
: `${bolum.ad} taban puanları ve başarı sıralamaları tablosunun ${sayfa}. sayfası — toplam ${stats.toplam} programın 2025 yerleştirme verileri.`,
|
||||
path: `/bolum/${slug}/sayfa/${sayfa}`,
|
||||
openGraph: {
|
||||
@@ -122,6 +144,7 @@ export function bolumSayfaMetadata(slug: string, sayfa: number): Metadata {
|
||||
),
|
||||
},
|
||||
});
|
||||
return { ...meta, title: { absolute: baslik } };
|
||||
}
|
||||
const enIyi =
|
||||
stats.minSira != null
|
||||
|
||||
Reference in New Issue
Block a user