All checks were successful
Deploy / deploy (push) Successful in 6m23s
- TemaSaglayici (next-themes) + alt bilgide TemaSecici - globals.css: .dark bloğunda palet token'ları çevrilir; bileşenlere dark: sınıfı yazılmaz - yüzeyler bg-white → bg-card, koyu haplar text-slate-50, SVG'lerde sabit renk yerine değişken - DESIGN.md §2.3 + tasarim-denetim kuralları (yuzey-beyaz, koyu-hap-beyaz-yazi, dark-sinif), AGENTS.md karanlık mod bölümü - docs: koyu tema denetimi raporu Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
81 lines
2.5 KiB
TypeScript
81 lines
2.5 KiB
TypeScript
import Link from "next/link";
|
||
import { cn } from "@/lib/utils";
|
||
import type { IlOzet } from "../katalog-queries";
|
||
|
||
const sayi = (n: number) => n.toLocaleString("tr-TR");
|
||
|
||
/**
|
||
* Şehir çipi (DESIGN.md §4.17): sihirbazın il çipiyle aynı kalıp — 40 px,
|
||
* tam yuvarlak, hover §2.1 tek turuncu; seçili/aktif hâl mavi dolu.
|
||
* Etkileşimli çip olduğu için rozet (§4.2) kuralının dışındadır.
|
||
*/
|
||
const CIP_TEMEL =
|
||
"inline-flex h-10 cursor-pointer items-center gap-1.5 rounded-full border px-3.5 text-sm font-semibold transition-[background-color,border-color,color,transform] duration-150 active:scale-[0.97]";
|
||
const CIP_PASIF =
|
||
"border-slate-200 bg-card text-slate-700 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500";
|
||
const CIP_AKTIF = "border-primary bg-primary text-white";
|
||
|
||
/**
|
||
* Şehre göre üniversite gezinme çipleri. `iller` verilen sırayla dizilir
|
||
* (çağıran genelde üniversite sayısına göre azalan verir). `aktifSlug`
|
||
* bulunulan şehir sayfasıdır: mavi dolu ve `aria-current="page"`.
|
||
* `tumuHref` verilirse sona "Tüm şehirler" çipi eklenir (A–Z listesine).
|
||
*/
|
||
export function SehirCipleri({
|
||
iller,
|
||
aktifSlug,
|
||
tumuHref,
|
||
tumuEtiket,
|
||
className,
|
||
}: {
|
||
iller: IlOzet[];
|
||
aktifSlug?: string;
|
||
tumuHref?: string;
|
||
tumuEtiket?: string;
|
||
className?: string;
|
||
}) {
|
||
return (
|
||
<ul
|
||
className={cn(
|
||
"flex flex-wrap items-center justify-center gap-2 lg:justify-start",
|
||
className,
|
||
)}
|
||
>
|
||
{iller.map((il) => {
|
||
const aktif = il.slug === aktifSlug;
|
||
return (
|
||
<li key={il.slug}>
|
||
<Link
|
||
href={`/universiteler/${il.slug}`}
|
||
aria-current={aktif ? "page" : undefined}
|
||
className={cn(CIP_TEMEL, aktif ? CIP_AKTIF : CIP_PASIF)}
|
||
>
|
||
{il.ad}
|
||
<span
|
||
className={cn(
|
||
"font-normal tabular-nums",
|
||
aktif ? "text-white/80" : "text-slate-400",
|
||
)}
|
||
>
|
||
{sayi(il.uniler.length)}
|
||
</span>
|
||
</Link>
|
||
</li>
|
||
);
|
||
})}
|
||
{tumuHref ? (
|
||
<li>
|
||
<Link href={tumuHref} className={cn(CIP_TEMEL, CIP_PASIF)}>
|
||
{tumuEtiket ?? "Tüm şehirler"}
|
||
</Link>
|
||
</li>
|
||
) : null}
|
||
</ul>
|
||
);
|
||
}
|
||
|
||
/** Çip satırında gösterilecek şehirler: en az iki üniversitesi olanlar. */
|
||
export function oneCikanIller(iller: IlOzet[]): IlOzet[] {
|
||
return iller.filter((il) => il.uniler.length >= 2);
|
||
}
|