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:
@@ -1,30 +1,37 @@
|
||||
import { TrendingDown, TrendingUp } from "lucide-react";
|
||||
import type { Program } from "@/types/yokatlas";
|
||||
import { ILK_YIL } from "@/lib/veri-yillari";
|
||||
|
||||
/** Taban sıra sütunlarının yapısal alt kümesi: hem DB programı hem de
|
||||
* rapordaki kaydedilmiş sıra geçmişi (bkz. raporSiraSerisi) bu tipe uyar. */
|
||||
export type SiraSerisi = Pick<
|
||||
Program,
|
||||
"sira2021" | "sira2022" | "sira2023" | "sira2024" | "sira2025"
|
||||
>;
|
||||
/** Taban sıra geçmişinin yapısal alt kümesi: hem DB programı hem de rapordaki
|
||||
* kaydedilmiş sıra geçmişi (bkz. raporSiraSerisi) bu tipe uyar. Dizi `ilkYil`'a
|
||||
* (yoksa veri penceresinin ilk yılına) demirlidir: eleman yılı
|
||||
* `ilkYil + indeks`. Uzunluk sabit DEĞİL — eski kayıtlı raporlar daha kısa
|
||||
* dizi taşır; yardımcılar dizinin kendi son iki elemanıyla çalışır. */
|
||||
export type SiraSerisi = {
|
||||
siraGecmisi: readonly (number | null)[];
|
||||
ilkYil?: number;
|
||||
};
|
||||
|
||||
/** Rapordaki [2021..2025] dizisini sütunlu seriye çevirir. */
|
||||
export function raporSiraSerisi(gecmis?: (number | null)[]): SiraSerisi {
|
||||
const g = gecmis ?? [];
|
||||
return {
|
||||
sira2021: g[0] ?? null,
|
||||
sira2022: g[1] ?? null,
|
||||
sira2023: g[2] ?? null,
|
||||
sira2024: g[3] ?? null,
|
||||
sira2025: g[4] ?? null,
|
||||
};
|
||||
/** Rapordaki kayıtlı diziyi seriye çevirir. Dizi DOLDURULMAZ: 5 elemanlı eski
|
||||
* kayıt 5 elemanlı kalır, "son iki yıl" kaydın kendi son iki yılıdır. */
|
||||
export function raporSiraSerisi(
|
||||
gecmis?: (number | null)[],
|
||||
ilkYil?: number,
|
||||
): SiraSerisi {
|
||||
return { siraGecmisi: gecmis ?? [], ilkYil };
|
||||
}
|
||||
|
||||
/** Serinin son iki yılı: [bir önceki, son]. */
|
||||
function sonIkiSira(program: SiraSerisi): [number | null, number | null] {
|
||||
const g = program.siraGecmisi;
|
||||
return [g[g.length - 2] ?? null, g[g.length - 1] ?? null];
|
||||
}
|
||||
|
||||
export function programEtkinSira(program: SiraSerisi): number | null {
|
||||
return program.sira2025 ?? program.sira2024;
|
||||
const [onceki, son] = sonIkiSira(program);
|
||||
return son ?? onceki;
|
||||
}
|
||||
|
||||
/** 2021–2025 taban sıralamasını sonuç listesindeki kompakt çizgiyle gösterir. */
|
||||
/** Taban sıralaması geçmişini sonuç listesindeki kompakt çizgiyle gösterir. */
|
||||
export function ProgramSiraGecmisi({ program }: { program: SiraSerisi }) {
|
||||
// Satır başına render edilen bileşen: filter/map/min/max/map/map'in 6 ayrı
|
||||
// geçişi tek döngüde toplanır (js-combine-iterations, js-min-max-loop)
|
||||
@@ -32,14 +39,10 @@ export function ProgramSiraGecmisi({ program }: { program: SiraSerisi }) {
|
||||
let min = Infinity;
|
||||
let max = -Infinity;
|
||||
const ozetParcalari: string[] = [];
|
||||
for (const [yil, sira] of [
|
||||
[2021, program.sira2021],
|
||||
[2022, program.sira2022],
|
||||
[2023, program.sira2023],
|
||||
[2024, program.sira2024],
|
||||
[2025, program.sira2025],
|
||||
] as const) {
|
||||
const ilkYil = program.ilkYil ?? ILK_YIL;
|
||||
for (const [indeks, sira] of program.siraGecmisi.entries()) {
|
||||
if (sira == null) continue;
|
||||
const yil = ilkYil + indeks;
|
||||
yillar.push([yil, sira]);
|
||||
if (sira < min) min = sira;
|
||||
if (sira > max) max = sira;
|
||||
@@ -89,12 +92,13 @@ export function ProgramSiraGecmisi({ program }: { program: SiraSerisi }) {
|
||||
|
||||
/** Son iki yılın tabanı %10'dan fazla değiştiğinde yönü işaretler. */
|
||||
export function ProgramTabanTrendi({ program }: { program: SiraSerisi }) {
|
||||
if (program.sira2025 == null || program.sira2024 == null) return null;
|
||||
const [onceki, son] = sonIkiSira(program);
|
||||
if (son == null || onceki == null) return null;
|
||||
|
||||
const oran = (program.sira2024 - program.sira2025) / program.sira2024;
|
||||
const oran = (onceki - son) / onceki;
|
||||
if (Math.abs(oran) < 0.1) return null;
|
||||
|
||||
const gecis = `${program.sira2024.toLocaleString("tr-TR")} → ${program.sira2025.toLocaleString("tr-TR")}`;
|
||||
const gecis = `${onceki.toLocaleString("tr-TR")} → ${son.toLocaleString("tr-TR")}`;
|
||||
if (oran > 0) {
|
||||
return (
|
||||
<TrendingUp
|
||||
|
||||
Reference in New Issue
Block a user