feat(katalog+tasarim): devlet/vakıf tür sayfaları, tür çipleri link; kayıtlı-sıra satırı şişko ve sade
All checks were successful
Deploy / deploy (push) Successful in 5m1s

- /universiteler/devlet ve /universiteler/vakif: şehir sayfası iskeleti,
  haritada bu türden üniversitesi olan her il turuncu (yakınlaşma yok), üç
  özet kartı, şehir çipleri (sayfa içi çapa), şehir şehir §4.15 satırları,
  öteki türe geçiş hapı; metadata + sitemap.
- TurCipi tek kaynak: devlet/vakıf çipi tür sayfasına link (sonuç, listem,
  tadımlık, bölüm, şehir/tür satırları); üniversite sayfası tür hapı ve
  /universiteler başlıkları da link. UniSatirlari ortak dosyada: ad, tür ve
  il ayrı linkler.
- Kompakt profilli satır (DESIGN.md §10.9): iri kupa kutusu + text-3xl/4xl
  sıra, text-xl/2xl başlık, 48 px buton; telefonda alt alta, lg'de tek satır.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-09-24 15:53:54 +03:00
parent a0e94bc024
commit a43c045828
17 changed files with 606 additions and 109 deletions

View File

@@ -2,16 +2,6 @@ import type { Metadata } from "next";
import Link from "next/link";
import { notFound } from "next/navigation";
import { Building2, ChevronRight, Landmark, MapPin } from "lucide-react";
import {
SATIR_AD_DUZ,
SATIR_CIP,
SATIR_GRUP,
SATIR_META,
} from "@/components/liste-satiri";
import { UniLogo } from "@/components/uni-logo";
import { trBaslikDuzeni } from "@/lib/slug";
import { UNITUR_ETIKET } from "@/lib/unitur";
import { cn } from "@/lib/utils";
import {
getAllIller,
getAllIlSlugs,
@@ -32,6 +22,7 @@ import { NavBaslik } from "./nav-baslik";
import { SehirCipleri, oneCikanIller } from "./sehir-cipleri";
import { SehirPikselHaritasi } from "./sehir-piksel-haritasi";
import { SehirYuzeyi } from "./sehir-yuzeyi";
import { UniSatirlari } from "./uni-satirlari";
const sayi = (n: number) => n.toLocaleString("tr-TR");
@@ -55,57 +46,6 @@ export function ilSayfaMetadata(slug: string): Metadata {
});
}
/**
* Şehir sayfasının üniversite satırları — DESIGN.md §4.15 liste satırı
* (Bilal, 24 Eyl 2026: "il kısmında bulunan üniler küçük gözüküyor"): 48 px
* logo, `text-base font-semibold` ad, altında tür çipi + program sayısı,
* satırın tamamı üniversite sayfasına link (44 px'ten iri dokunma hedefi).
* Ad hover'ı §2.1 istisnasıyla mavi, satır zemini turuncuya döner, sağdaki
* ok kayar. Üniversitenin ana ili bu sayfadan farklıysa (ODTÜ KKTC sayfasında)
* il de metada yazar.
*/
function UniSatirlari({ uniler, buIl }: { uniler: UniOzet[]; buIl: string }) {
return (
<ol className="mt-4 divide-y divide-slate-100 overflow-hidden rounded-xl border border-slate-200 bg-white text-left">
{uniler.map((u) => {
const tur = u.unitur ? UNITUR_ETIKET[u.unitur]?.cip : null;
const digerIl = u.il && u.il !== buIl ? trBaslikDuzeni(u.il) : null;
return (
<li key={u.slug}>
<Link
href={`/universite/${u.slug}`}
className="group flex items-start gap-3 px-3 py-4 transition-[background-color,transform] duration-150 hover:bg-orange-50/60 active:scale-[0.99] sm:items-center sm:gap-4 sm:px-5 lg:py-3"
>
<UniLogo slug={u.slug} ad={u.ad} boy="sm" />
<span className="min-w-0 flex-1">
<span className={SATIR_GRUP}>
<span
className={cn(
SATIR_AD_DUZ,
"transition-colors group-hover:text-primary group-hover:underline",
)}
>
{u.ad}
</span>
<span className={SATIR_META}>
{tur ? <span className={SATIR_CIP}>{tur}</span> : null}
{digerIl ? <span className="shrink-0">{digerIl}</span> : null}
<span className="shrink-0">{sayi(u.programSayisi)} program</span>
</span>
</span>
</span>
<ChevronRight
className="mt-3 size-4 shrink-0 text-slate-400 transition-[color,transform] duration-150 group-hover:translate-x-0.5 group-hover:text-orange-500 sm:mt-0"
aria-hidden
/>
</Link>
</li>
);
})}
</ol>
);
}
function UniGrubu({
baslik,
uniler,
@@ -124,7 +64,7 @@ function UniGrubu({
{sayi(uniler.length)}
</span>
</h2>
<UniSatirlari uniler={uniler} buIl={buIl} />
<UniSatirlari uniler={uniler} gizliIl={buIl} />
</section>
);
}