feat(veri): bileşenler yılsız Program'a ve veri-yillari sözlüğüne geçti (P-B b)
- SiraSerisi = { siraGecmisi, ilkYil? }; yardımcılar dizinin kendi son iki
elemanıyla çalışır, yıl ilkYil + indeks. raporSiraSerisi diziyi doldurmaz:
5 elemanlı eski raporlar 2024→2025 trendini göstermeye devam eder.
- Tablo başlıkları "Son ${VERI_YIL_SAYISI} yıl"; rapor listesi başlığı kaydın
kendi pencere uzunluğunu söyler (eski rapor: 5).
- siraYiliEtiketi SON_YIL/ONCEKI_YIL'dan; bölüm/üniversite sayfa metinleri ve
metadata SON_YIL, TERCIH_YILI, BASLIK_YILI sözlüğünden.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
@@ -25,6 +25,12 @@ import { VeriKaynagi } from "./veri-kaynagi";
|
||||
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
|
||||
import { SiteFooter } from "@/components/site-footer";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import {
|
||||
BASLIK_YILI,
|
||||
ONCEKI_YIL,
|
||||
SON_YIL,
|
||||
TERCIH_YILI,
|
||||
} from "@/lib/veri-yillari";
|
||||
|
||||
const sayi = (n: number) => n.toLocaleString("tr-TR");
|
||||
|
||||
@@ -65,20 +71,20 @@ 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;
|
||||
// Sırası son yılda olmayıp bir önceki yıldan 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 yalnizOnceki = 0;
|
||||
for (const p of dilim) {
|
||||
const efektif = p.sira2025 ?? p.sira2024;
|
||||
const efektif = p.efektifSira;
|
||||
if (efektif == null) {
|
||||
verisiz += 1;
|
||||
continue;
|
||||
}
|
||||
if (p.sira2025 == null) yalniz2024 += 1;
|
||||
if (p.siraSon == null) yalnizOnceki += 1;
|
||||
if (minSira == null || efektif < minSira) minSira = efektif;
|
||||
if (maxSira == null || efektif > maxSira) maxSira = efektif;
|
||||
}
|
||||
return { tumProgramlar, dilim, minSira, maxSira, verisiz, yalniz2024 };
|
||||
return { tumProgramlar, dilim, minSira, maxSira, verisiz, yalnizOnceki };
|
||||
}
|
||||
|
||||
/** <title> için kısa sıra: 2.425.061 → "2,43 mn", 95.400 → "95 bin". */
|
||||
@@ -99,13 +105,13 @@ function siraAraligiMetni({
|
||||
minSira,
|
||||
maxSira,
|
||||
verisiz,
|
||||
yalniz2024,
|
||||
yalnizOnceki,
|
||||
}: 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 yil = siraYiliEtiketi(yalnizOnceki, dilim.length - verisiz);
|
||||
const aralik =
|
||||
minSira === maxSira
|
||||
? `${yil} taban sırası ${sayi(minSira)} olan programlar`
|
||||
@@ -134,8 +140,8 @@ export function bolumSayfaMetadata(slug: string, sayfa: number): Metadata {
|
||||
const meta = sayfaMetadata({
|
||||
title: baslik,
|
||||
description: aralik
|
||||
? `${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.`,
|
||||
? `${bolum.ad} taban puanları, sayfa ${sayfa}: ${aralik}. Toplam ${stats.toplam} programın son yerleştirme verileri (${SON_YIL}; o yıl verisi olmayanlarda ${ONCEKI_YIL}) — 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 ${SON_YIL} yerleştirme verileri.`,
|
||||
path: `/bolum/${slug}/sayfa/${sayfa}`,
|
||||
openGraph: {
|
||||
images: ustSegmentOgGorseli(
|
||||
@@ -151,8 +157,8 @@ export function bolumSayfaMetadata(slug: string, sayfa: number): Metadata {
|
||||
? ` En iyi taban sıralaması ${sayi(stats.minSira)}.`
|
||||
: "";
|
||||
return sayfaMetadata({
|
||||
title: `${bolum.ad} Taban Puanları ve Başarı Sıralamaları 2026`,
|
||||
description: `${bolum.ad} 2025 yerleştirme verileri: ${stats.toplam} programın taban puanı ve sıralaması, ${stats.devlet} devlet / ${stats.vakif} vakıf.${enIyi} 2026 tercih rehberi.`,
|
||||
title: `${bolum.ad} Taban Puanları ve Başarı Sıralamaları ${BASLIK_YILI}`,
|
||||
description: `${bolum.ad} ${SON_YIL} yerleştirme verileri: ${stats.toplam} programın taban puanı ve sıralaması, ${stats.devlet} devlet / ${stats.vakif} vakıf.${enIyi} ${TERCIH_YILI} tercih rehberi.`,
|
||||
path: `/bolum/${slug}`,
|
||||
});
|
||||
}
|
||||
@@ -230,7 +236,7 @@ export function BolumIcerik({ slug, sayfa }: { slug: string; sayfa: number }) {
|
||||
</h1>
|
||||
{ilkSayfa ? (
|
||||
<p className="mt-3 max-w-2xl text-sm leading-6 text-muted-foreground sm:text-base">
|
||||
{sayi(tumProgramlar.length)} üniversite programının 2025 taban
|
||||
{sayi(tumProgramlar.length)} üniversite programının {SON_YIL} taban
|
||||
puanlarını, başarı sıralamalarını ve kontenjanlarını incele.
|
||||
</p>
|
||||
) : (
|
||||
|
||||
@@ -5,6 +5,7 @@ import Link from "next/link";
|
||||
import { ChevronDown, ChevronUp } from "lucide-react";
|
||||
import type { Program } from "@/types/yokatlas";
|
||||
import { trBaslikDuzeni } from "@/lib/slug";
|
||||
import { VERI_YIL_SAYISI } from "@/lib/veri-yillari";
|
||||
import { Sayfalama, SAYFA_BOYU } from "./sayfalama";
|
||||
import {
|
||||
ProgramSiraGecmisi,
|
||||
@@ -24,14 +25,14 @@ import {
|
||||
|
||||
const sayi = (n: number) => n.toLocaleString("tr-TR");
|
||||
|
||||
type SiralamaAlani = "sira2025" | "puan2025" | "kontenjan2025";
|
||||
type SiralamaAlani = "siraSon" | "puanSon" | "kontenjanSon";
|
||||
type SiralamaYonu = "artan" | "azalan";
|
||||
export type BolumProgrami = Program & { universiteSlug: string | null };
|
||||
|
||||
const ALAN_ETIKETLERI: Record<SiralamaAlani, string> = {
|
||||
sira2025: "Sıralama",
|
||||
puan2025: "Puan",
|
||||
kontenjan2025: "Kontenjan",
|
||||
siraSon: "Sıralama",
|
||||
puanSon: "Puan",
|
||||
kontenjanSon: "Kontenjan",
|
||||
};
|
||||
|
||||
function SiralamaDugmesi({
|
||||
@@ -157,11 +158,11 @@ export function BolumProgramListesi({
|
||||
<TableRow>
|
||||
<TableHead>Üniversite</TableHead>
|
||||
<TableHead className="hidden text-right md:table-cell">
|
||||
Son 5 yıl
|
||||
Son {VERI_YIL_SAYISI} yıl
|
||||
</TableHead>
|
||||
<TableHead className="hidden text-right lg:table-cell">
|
||||
<SiralamaDugmesi
|
||||
alan="puan2025"
|
||||
alan="puanSon"
|
||||
aktifAlan={aktifAlan}
|
||||
yon={yon}
|
||||
onSirala={sirala}
|
||||
@@ -169,7 +170,7 @@ export function BolumProgramListesi({
|
||||
</TableHead>
|
||||
<TableHead className="hidden text-right sm:table-cell">
|
||||
<SiralamaDugmesi
|
||||
alan="kontenjan2025"
|
||||
alan="kontenjanSon"
|
||||
aktifAlan={aktifAlan}
|
||||
yon={yon}
|
||||
onSirala={sirala}
|
||||
@@ -177,7 +178,7 @@ export function BolumProgramListesi({
|
||||
</TableHead>
|
||||
<TableHead className="text-right">
|
||||
<SiralamaDugmesi
|
||||
alan="sira2025"
|
||||
alan="siraSon"
|
||||
aktifAlan={aktifAlan}
|
||||
yon={yon}
|
||||
onSirala={sirala}
|
||||
@@ -243,17 +244,17 @@ export function BolumProgramListesi({
|
||||
<ProgramSiraGecmisi program={p} />
|
||||
</TableCell>
|
||||
<TableCell className="hidden text-right text-xs tabular-nums text-slate-500 lg:table-cell">
|
||||
{p.puan2025 != null
|
||||
? p.puan2025.toFixed(2).replace(".", ",")
|
||||
{p.puanSon != null
|
||||
? p.puanSon.toFixed(2).replace(".", ",")
|
||||
: "—"}
|
||||
</TableCell>
|
||||
<TableCell className="hidden text-right text-xs tabular-nums text-slate-500 sm:table-cell">
|
||||
{p.kontenjan2025 != null ? `${sayi(p.kontenjan2025)} kişi` : "—"}
|
||||
{p.kontenjanSon != null ? `${sayi(p.kontenjanSon)} kişi` : "—"}
|
||||
</TableCell>
|
||||
<TableCell className="text-right text-xs tabular-nums text-slate-500">
|
||||
<span className="inline-flex items-center gap-1">
|
||||
<ProgramTabanTrendi program={p} />
|
||||
{p.sira2025 != null ? `~${sayi(p.sira2025)}.` : "—"}
|
||||
{p.siraSon != null ? `~${sayi(p.siraSon)}.` : "—"}
|
||||
</span>
|
||||
</TableCell>
|
||||
<TableCell className="pr-3 text-right">
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { ReactNode } from "react";
|
||||
import Link from "next/link";
|
||||
import { ChevronLeft, ChevronRight } from "lucide-react";
|
||||
import { ONCEKI_YIL, SON_YIL } from "@/lib/veri-yillari";
|
||||
|
||||
/** Programatik tablo sayfaları için satır dilimi boyutu. */
|
||||
export const SAYFA_BOYU = 50;
|
||||
@@ -13,10 +14,19 @@ export function sayfaDilimi<T>(liste: readonly T[], sayfa: number): T[] {
|
||||
return liste.slice((sayfa - 1) * SAYFA_BOYU, sayfa * SAYFA_BOYU);
|
||||
}
|
||||
|
||||
/** Aralıktaki sıraların hangi yıldan geldiği: hepsi 2025 / hepsi 2024 / karışık. */
|
||||
export function siraYiliEtiketi(yalniz2024: number, siraliSayi: number): string {
|
||||
if (yalniz2024 === 0) return "2025";
|
||||
return yalniz2024 === siraliSayi ? "2024" : "2024–2025";
|
||||
/**
|
||||
* Aralıktaki sıraların hangi yıldan geldiği: hepsi son yıl / hepsi bir önceki
|
||||
* yıl / karışık. `yalnizOnceki`: sırası son yılda olmayıp bir önceki yıldan
|
||||
* gelen satır sayısı; `siraliSayi`: sırası olan toplam satır.
|
||||
*/
|
||||
export function siraYiliEtiketi(
|
||||
yalnizOnceki: number,
|
||||
siraliSayi: number,
|
||||
): string {
|
||||
if (yalnizOnceki === 0) return String(SON_YIL);
|
||||
return yalnizOnceki === siraliSayi
|
||||
? String(ONCEKI_YIL)
|
||||
: `${ONCEKI_YIL}–${SON_YIL}`;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,6 +34,7 @@ import { UniLogo } from "@/components/uni-logo";
|
||||
import { uniLogoYolu } from "@/lib/uni-logolar";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import type { Program } from "@/types/yokatlas";
|
||||
import { BASLIK_YILI, SON_YIL, TERCIH_YILI } from "@/lib/veri-yillari";
|
||||
|
||||
const sayi = (n: number) => n.toLocaleString("tr-TR");
|
||||
|
||||
@@ -91,13 +92,13 @@ function fakulteOzeti({
|
||||
if (adlar.length === 0) return null;
|
||||
if (adlar.length === 1) {
|
||||
const siralar = dilim
|
||||
.map((p) => p.sira2025 ?? p.sira2024)
|
||||
.map((p) => p.efektifSira)
|
||||
.filter((n): n is number => n != null);
|
||||
if (siralar.length === 0) return adlar[0];
|
||||
const min = Math.min(...siralar);
|
||||
const max = Math.max(...siralar);
|
||||
const yil = siraYiliEtiketi(
|
||||
dilim.filter((p) => p.sira2025 == null && p.sira2024 != null).length,
|
||||
dilim.filter((p) => p.siraSon == null && p.efektifSira != null).length,
|
||||
siralar.length,
|
||||
);
|
||||
return min === max
|
||||
@@ -116,10 +117,10 @@ export function uniSayfaMetadata(slug: string, sayfa: number): Metadata {
|
||||
// farklılaştırıcı (o sayfadaki birimler) açıklamaya ve gövdeye gider.
|
||||
const birimler = fakulteOzeti(uniSayfaDilimi(uni, sayfa));
|
||||
return sayfaMetadata({
|
||||
title: `${uni.ad} Taban Puanları 2026 (Sayfa ${sayfa})`,
|
||||
title: `${uni.ad} Taban Puanları ${BASLIK_YILI} (Sayfa ${sayfa})`,
|
||||
description: birimler
|
||||
? `${uni.ad} taban puanları, sayfa ${sayfa}: ${birimler}. Toplam ${uni.programSayisi} programın 2025 yerleştirme verileri — taban puanı, başarı sıralaması ve kontenjan.`
|
||||
: `${uni.ad} taban puanları ve başarı sıralamaları tablosunun ${sayfa}. sayfası — toplam ${uni.programSayisi} programın 2025 yerleştirme verileri.`,
|
||||
? `${uni.ad} taban puanları, sayfa ${sayfa}: ${birimler}. Toplam ${uni.programSayisi} programın ${SON_YIL} yerleştirme verileri — taban puanı, başarı sıralaması ve kontenjan.`
|
||||
: `${uni.ad} taban puanları ve başarı sıralamaları tablosunun ${sayfa}. sayfası — toplam ${uni.programSayisi} programın ${SON_YIL} yerleştirme verileri.`,
|
||||
path: `/universite/${slug}/sayfa/${sayfa}`,
|
||||
openGraph: {
|
||||
images: ustSegmentOgGorseli(
|
||||
@@ -130,8 +131,8 @@ export function uniSayfaMetadata(slug: string, sayfa: number): Metadata {
|
||||
});
|
||||
}
|
||||
return sayfaMetadata({
|
||||
title: `${uni.ad} Taban Puanları ve Başarı Sıralamaları 2026`,
|
||||
description: `${uni.ad} 2025 yerleştirme verileri: ${uni.programSayisi} programın taban puanları, başarı sıralamaları ve kontenjanları${uni.il ? ` (${trBaslikDuzeni(uni.il)})` : ""}. 2026 tercih rehberi.`,
|
||||
title: `${uni.ad} Taban Puanları ve Başarı Sıralamaları ${BASLIK_YILI}`,
|
||||
description: `${uni.ad} ${SON_YIL} yerleştirme verileri: ${uni.programSayisi} programın taban puanları, başarı sıralamaları ve kontenjanları${uni.il ? ` (${trBaslikDuzeni(uni.il)})` : ""}. ${TERCIH_YILI} tercih rehberi.`,
|
||||
path: `/universite/${slug}`,
|
||||
});
|
||||
}
|
||||
@@ -241,7 +242,7 @@ export function UniversiteIcerik({
|
||||
<div className="mt-4 flex items-center gap-4">
|
||||
<UniLogo slug={slug} ad={uni.ad} boy="lg" />
|
||||
<h1 className="font-heading text-3xl font-bold text-slate-900 sm:text-4xl">
|
||||
{uni.ad} Taban Puanları 2026
|
||||
{uni.ad} Taban Puanları {BASLIK_YILI}
|
||||
{ilkSayfa ? "" : ` — Sayfa ${sayfa}`}
|
||||
</h1>
|
||||
</div>
|
||||
@@ -250,7 +251,7 @@ export function UniversiteIcerik({
|
||||
<>
|
||||
<p className="mt-4 max-w-3xl text-sm leading-7 text-slate-600">
|
||||
{uni.ad}
|
||||
{uni.il ? ` (${trBaslikDuzeni(uni.il)})` : ""}, 2025 YKS
|
||||
{uni.il ? ` (${trBaslikDuzeni(uni.il)})` : ""}, {SON_YIL} YKS
|
||||
yerleştirme sonuçlarına göre{" "}
|
||||
<strong>{sayi(uni.programSayisi)} programda</strong> öğrenci aldı
|
||||
{uni.fakulteSayisi > 1
|
||||
@@ -267,10 +268,11 @@ export function UniversiteIcerik({
|
||||
{uni.stats.toplamKontenjan > 0 ? (
|
||||
<> Toplam kontenjan {sayi(uni.stats.toplamKontenjan)}.</>
|
||||
) : null}{" "}
|
||||
Aşağıdaki tablolar 2026 tercihleri için rehber niteliğindedir;{" "}
|
||||
Aşağıdaki tablolar {TERCIH_YILI} tercihleri için rehber
|
||||
niteliğindedir;{" "}
|
||||
<em>
|
||||
2026 taban puanları ve sıralamaları, yerleştirme sonuçları
|
||||
açıklandığında netleşir.
|
||||
{TERCIH_YILI} taban puanları ve sıralamaları, yerleştirme
|
||||
sonuçları açıklandığında netleşir.
|
||||
</em>
|
||||
</p>
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
import Link from "next/link";
|
||||
import type { Program } from "@/types/yokatlas";
|
||||
import { SON_YIL, VERI_YIL_SAYISI } from "@/lib/veri-yillari";
|
||||
import {
|
||||
ProgramSiraGecmisi,
|
||||
ProgramTabanTrendi,
|
||||
@@ -48,10 +49,10 @@ export function UniversiteProgramTablosu({
|
||||
<TableRow>
|
||||
<TableHead>Program</TableHead>
|
||||
<TableHead className="hidden text-right md:table-cell">
|
||||
Son 5 yıl
|
||||
Son {VERI_YIL_SAYISI} yıl
|
||||
</TableHead>
|
||||
<TableHead className="hidden text-right lg:table-cell">
|
||||
2025 puan
|
||||
{SON_YIL} puan
|
||||
</TableHead>
|
||||
<TableHead className="hidden text-right sm:table-cell">
|
||||
Kontenjan
|
||||
@@ -93,13 +94,13 @@ export function UniversiteProgramTablosu({
|
||||
<ProgramSiraGecmisi program={p} />
|
||||
</TableCell>
|
||||
<TableCell className="hidden text-right text-xs tabular-nums text-slate-500 lg:table-cell">
|
||||
{p.puan2025 != null
|
||||
? p.puan2025.toFixed(2).replace(".", ",")
|
||||
{p.puanSon != null
|
||||
? p.puanSon.toFixed(2).replace(".", ",")
|
||||
: "—"}
|
||||
</TableCell>
|
||||
<TableCell className="hidden text-right text-xs tabular-nums text-slate-500 sm:table-cell">
|
||||
{p.kontenjan2025 != null
|
||||
? `${sayi(p.kontenjan2025)} kişi`
|
||||
{p.kontenjanSon != null
|
||||
? `${sayi(p.kontenjanSon)} kişi`
|
||||
: "—"}
|
||||
</TableCell>
|
||||
<TableCell className="text-right text-xs tabular-nums text-slate-500">
|
||||
|
||||
@@ -24,8 +24,7 @@ type ProgramOzet = Pick<
|
||||
| "il"
|
||||
| "unitur"
|
||||
| "tur"
|
||||
| "sira2025"
|
||||
| "sira2024"
|
||||
| "efektifSira"
|
||||
>;
|
||||
|
||||
const PROFILSIZ_EKLEME_TOAST_ID = "profilsiz-ekleme";
|
||||
|
||||
@@ -22,6 +22,7 @@ import type {
|
||||
} from "@/types/yokatlas";
|
||||
import { DILIM_ETIKET, riskHesapla, type RiskSeviyesi } from "@/lib/risk";
|
||||
import { bolumSayfaSlug, uniSayfaSlug } from "@/lib/slug";
|
||||
import { VERI_YIL_SAYISI } from "@/lib/veri-yillari";
|
||||
import {
|
||||
ProgramSiraGecmisi,
|
||||
ProgramTabanTrendi,
|
||||
@@ -239,7 +240,7 @@ export function ProgramTablosu({
|
||||
<TableHead className="w-8" />
|
||||
<TableHead>Program</TableHead>
|
||||
<TableHead className="hidden text-right md:table-cell">
|
||||
Son 5 yıl
|
||||
Son {VERI_YIL_SAYISI} yıl
|
||||
</TableHead>
|
||||
<TableHead className="hidden text-right sm:table-cell">
|
||||
Kontenjan
|
||||
@@ -357,19 +358,19 @@ function ProgramSatiri({
|
||||
<TableCell
|
||||
className="hidden text-right text-xs tabular-nums text-slate-500 sm:table-cell"
|
||||
title={
|
||||
p.kontenjan2025 != null && p.yerlesen2025 != null
|
||||
? `${p.kontenjan2025} kontenjan, ${p.yerlesen2025} yerleşen`
|
||||
p.kontenjanSon != null && p.yerlesenSon != null
|
||||
? `${p.kontenjanSon} kontenjan, ${p.yerlesenSon} yerleşen`
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
{p.kontenjan2025 != null ? (
|
||||
{p.kontenjanSon != null ? (
|
||||
<span className="inline-flex items-center gap-1.5">
|
||||
{p.yerlesen2025 != null && p.yerlesen2025 < p.kontenjan2025 ? (
|
||||
{p.yerlesenSon != null && p.yerlesenSon < p.kontenjanSon ? (
|
||||
<span className="rounded bg-amber-50 px-1 py-px text-[10px] font-medium leading-4 text-amber-600">
|
||||
boş kaldı
|
||||
</span>
|
||||
) : null}
|
||||
{p.kontenjan2025.toLocaleString("tr-TR")} kişi
|
||||
{p.kontenjanSon.toLocaleString("tr-TR")} kişi
|
||||
</span>
|
||||
) : (
|
||||
"—"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
// 24'lük listenin gövdesi. Görsel dil sonuç sayfasındaki ham program
|
||||
// tablosuyla birebir aynıdır (bkz. program-tablosu.tsx): aynı beyaz kart,
|
||||
// aynı satır düzeni, aynı "Son 5 yıl" / "Taban sıra" sütunları. Buradaki fark
|
||||
// aynı satır düzeni, aynı "Son N yıl" / "Taban sıra" sütunları. Buradaki fark
|
||||
// içerik: satır sırası tercih numarası, risk sütunu Yapay Zeka'dan gelir ve
|
||||
// satır açıldığında gerekçe/risk notu görünür. Program adı ve tabanlar herkese
|
||||
// açık; Yapay Zeka katmanı kilitliBaslangic sonrasında ücretlidir (metin
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
TableRow,
|
||||
} from "@/components/ui/table";
|
||||
import { bolumSayfaSlug, uniSayfaSlug } from "@/lib/slug";
|
||||
import { VERI_YIL_SAYISI } from "@/lib/veri-yillari";
|
||||
import type { RaporSonuc } from "@/features/rapor/types/rapor";
|
||||
import {
|
||||
DILIM_ETIKET,
|
||||
@@ -47,7 +48,7 @@ const RISK_STIL: Record<RiskSeviyesi, { nokta: string; icon: typeof Rocket }> =
|
||||
guvenli: { nokta: "bg-emerald-500", icon: ShieldCheck },
|
||||
};
|
||||
|
||||
// Sütun sayısı: # · Program · Son 5 yıl · Risk · Taban sıra · detay oku
|
||||
// Sütun sayısı: # · Program · Son N yıl · Risk · Taban sıra · detay oku
|
||||
const SUTUN_SAYISI = 6;
|
||||
|
||||
/**
|
||||
@@ -161,6 +162,19 @@ export function RaporListesi({
|
||||
return iller.size === 1 ? [...iller][0] : null;
|
||||
}, [rapor]);
|
||||
|
||||
// Sütun başlığı kaydın KENDİ penceresini söyler: eski raporların sıra
|
||||
// geçmişi üretildiği günün yıl sayısını taşır (dizi doldurulmaz), başlık
|
||||
// çizgide olmayan bir yılı vaat etmesin. Geçmişi hiç olmayan kayıtta
|
||||
// bugünkü pencereye düşer.
|
||||
const yilSayisi = useMemo(() => {
|
||||
let enUzun = 0;
|
||||
for (const t of rapor.tercihler) {
|
||||
const n = rapor.programlar[t.programId]?.siraGecmisi?.length ?? 0;
|
||||
if (n > enUzun) enUzun = n;
|
||||
}
|
||||
return enUzun > 0 ? enUzun : VERI_YIL_SAYISI;
|
||||
}, [rapor]);
|
||||
|
||||
const satir = (t: RaporSonuc["tercihler"][number], index: number) => {
|
||||
const p = rapor.programlar[t.programId];
|
||||
const analizKilitli = index >= kilitIdx;
|
||||
@@ -168,7 +182,7 @@ export function RaporListesi({
|
||||
(adaySira != null ? riskHesapla(p?.efektifSira, adaySira) : null) ??
|
||||
dilimdenRisk(t.dilim);
|
||||
const stil = RISK_STIL[risk];
|
||||
const seri = raporSiraSerisi(p?.siraGecmisi);
|
||||
const seri = raporSiraSerisi(p?.siraGecmisi, p?.ilkYil);
|
||||
const taban = p?.efektifSira ?? programEtkinSira(seri);
|
||||
const acikMi = acik.has(t.sira);
|
||||
const devlet = p?.unitur === "DEVLET";
|
||||
@@ -366,7 +380,7 @@ export function RaporListesi({
|
||||
<TableHead className="w-8 pl-4 pr-0">#</TableHead>
|
||||
<TableHead>Program</TableHead>
|
||||
<TableHead className="hidden text-right md:table-cell">
|
||||
Son 5 yıl
|
||||
Son {yilSayisi} yıl
|
||||
</TableHead>
|
||||
<TableHead>
|
||||
<span className="hidden sm:inline">Yapay Zeka </span>Risk
|
||||
|
||||
@@ -105,7 +105,7 @@ export function TadimlikSatiri({
|
||||
|
||||
const p = satir.program;
|
||||
const risk = riskHesapla(p.efektifSira, sira) ?? dilimdenRisk(satir.dilim);
|
||||
const seri = raporSiraSerisi(p.siraGecmisi);
|
||||
const seri = raporSiraSerisi(p.siraGecmisi, p.ilkYil);
|
||||
const taban = p.efektifSira ?? programEtkinSira(seri);
|
||||
const devlet = p.unitur === "DEVLET";
|
||||
const girisUrl = `/giris?callback=${encodeURIComponent(sonucHref())}`;
|
||||
|
||||
Reference in New Issue
Block a user