128 lines
4.9 KiB
TypeScript
128 lines
4.9 KiB
TypeScript
"use client";
|
||
|
||
import Link from "next/link";
|
||
import type { Program } from "@/lib/db";
|
||
import {
|
||
ProgramSiraGecmisi,
|
||
ProgramTabanTrendi,
|
||
programEtkinSira,
|
||
} from "@/components/program-liste-verileri";
|
||
import { ProgramEkleButonu } from "@/components/manuel-liste/program-ekle-butonu";
|
||
import {
|
||
Table,
|
||
TableBody,
|
||
TableCell,
|
||
TableHead,
|
||
TableHeader,
|
||
TableRow,
|
||
} from "@/components/ui/table";
|
||
|
||
const sayi = (n: number) => n.toLocaleString("tr-TR");
|
||
|
||
const TUR_ETIKET: Record<string, string> = {
|
||
SAYISAL: "SAY",
|
||
"EŞİT AĞIRLIK": "EA",
|
||
SÖZEL: "SÖZ",
|
||
DİL: "DİL",
|
||
TYT: "TYT",
|
||
};
|
||
|
||
export type UniProgramSatiri = Program & { bolumSlug: string | null };
|
||
|
||
export function UniversiteProgramTablosu({
|
||
gruplar,
|
||
}: {
|
||
gruplar: { fakulte: string; programlar: UniProgramSatiri[] }[];
|
||
}) {
|
||
return (
|
||
<>
|
||
{gruplar.map(({ fakulte, programlar }, i) => (
|
||
<section key={`${fakulte}-${i}`} className="mt-6">
|
||
<h2 className="mb-3 font-heading text-xl font-bold text-slate-900">
|
||
{fakulte}
|
||
</h2>
|
||
<div className="overflow-hidden rounded-2xl border border-slate-200 bg-white">
|
||
<Table>
|
||
<TableHeader>
|
||
<TableRow>
|
||
<TableHead>Program</TableHead>
|
||
<TableHead className="hidden text-right md:table-cell">
|
||
Son 5 yıl
|
||
</TableHead>
|
||
<TableHead className="hidden text-right lg:table-cell">
|
||
2025 puan
|
||
</TableHead>
|
||
<TableHead className="hidden text-right sm:table-cell">
|
||
Kontenjan
|
||
</TableHead>
|
||
<TableHead className="text-right">Taban sıra</TableHead>
|
||
<TableHead className="w-14 text-right">
|
||
<span className="sr-only">Listeye ekle</span>
|
||
</TableHead>
|
||
</TableRow>
|
||
</TableHeader>
|
||
<TableBody>
|
||
{programlar.map((p) => {
|
||
const taban = programEtkinSira(p);
|
||
return (
|
||
<TableRow key={p.id}>
|
||
<TableCell className="max-w-0 w-full">
|
||
{p.bolumSlug ? (
|
||
<Link
|
||
href={`/bolum/${p.bolumSlug}`}
|
||
className="block truncate text-sm font-semibold text-slate-900 hover:text-primary hover:underline focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
|
||
>
|
||
{p.isim.trim()}
|
||
</Link>
|
||
) : (
|
||
<span className="block truncate text-sm font-semibold">
|
||
{p.isim.trim()}
|
||
</span>
|
||
)}
|
||
<span className="mt-0.5 flex items-center gap-1.5 text-xs text-slate-500">
|
||
<span className="shrink-0 rounded bg-slate-100 px-1 py-px text-[10px] font-medium leading-4 text-slate-600">
|
||
{TUR_ETIKET[p.tur] ?? p.tur}
|
||
</span>
|
||
{p.sure ? (
|
||
<span className="shrink-0">{p.sure} yıl</span>
|
||
) : null}
|
||
</span>
|
||
</TableCell>
|
||
<TableCell className="hidden text-right text-xs md:table-cell">
|
||
<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(".", ",")
|
||
: "—"}
|
||
</TableCell>
|
||
<TableCell className="hidden text-right text-xs tabular-nums text-slate-500 sm:table-cell">
|
||
{p.kontenjan2025 != null
|
||
? `${sayi(p.kontenjan2025)} 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} />
|
||
{taban != null ? `~${sayi(taban)}.` : "—"}
|
||
</span>
|
||
</TableCell>
|
||
<TableCell className="pr-3 text-right">
|
||
<ProgramEkleButonu
|
||
program={p}
|
||
kaynak="universite"
|
||
className="size-8 min-h-8 min-w-8"
|
||
/>
|
||
</TableCell>
|
||
</TableRow>
|
||
);
|
||
})}
|
||
</TableBody>
|
||
</Table>
|
||
</div>
|
||
</section>
|
||
))}
|
||
</>
|
||
);
|
||
}
|