feat(tasarim): şehir sayfasına hero dilinde piksel harita; üniversite konum kartı da aynı harita
All checks were successful
Deploy / deploy (push) Successful in 4m39s

- scripts/il-izgara-uret.ts → src/lib/il-izgara-verisi.ts: 81 il ve 7 ülke
  kontürü hero'nun dot-matrix ızgarasına (72×31) rasterize; küçük iller 2×2 garanti.
- SehirPikselHaritasi: iri kareler, altı opaklık, kıyı serpintisi, usePixelHeat
  ısı fırçası; bulunulan il iri turuncu karelerle sırayla belirir (kt-piksel-belir)
  ve nabız atar; KKTC/yurt dışında şehir merkezinde 2×2 iri kare.
- Şehir sayfası başlığı beyaz piksel dokulu yüzeyde (SehirYuzeyi), harita sağda/altta.
- UniversiteKonumHaritasi düz SVG yerine aynı piksel haritayı kullanır.
- DESIGN.md §4.12/§4.17/§10.8 güncellendi.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
bilalgursen
2026-09-24 14:56:11 +03:00
parent 259534fa9c
commit eefac56659
8 changed files with 671 additions and 108 deletions

View File

@@ -20,6 +20,8 @@ import {
import { BASLIK_YILI, SON_YIL, TERCIH_YILI } from "@/lib/veri-yillari";
import { NavBaslik } from "./nav-baslik";
import { SehirCipleri, oneCikanIller } from "./sehir-cipleri";
import { SehirPikselHaritasi } from "./sehir-piksel-haritasi";
import { SehirYuzeyi } from "./sehir-yuzeyi";
import { UniLinkleri } from "./universite-listesi";
const sayi = (n: number) => n.toLocaleString("tr-TR");
@@ -123,39 +125,49 @@ export function IlIcerik({ slug }: { slug: string }) {
</nav>
<NavBaslik baslikId="il-baslik" ad={`${il.ad} üniversiteleri`} />
<h1
id="il-baslik"
className="mt-6 text-center font-heading text-3xl font-bold leading-tight text-slate-900 sm:text-5xl lg:text-left"
>
{il.ad} Üniversiteleri Taban Puanları {BASLIK_YILI}
</h1>
{/* Başlık yüzeyi: beyaz kart + slate piksel doku, şehrin dot-matrix
haritası (DESIGN.md §4.17). lg altında metin ortalı, harita altta. */}
<SehirYuzeyi
seed={31}
harita={<SehirPikselHaritasi il={il.il} ad={il.ad} />}
metin={
<div className="text-center lg:text-left">
<h1
id="il-baslik"
className="font-heading text-3xl font-bold leading-tight text-slate-900 sm:text-5xl"
>
{il.ad} Üniversiteleri Taban Puanları {BASLIK_YILI}
</h1>
{/* Kimlik hapları (DESIGN.md §4.12): il + üniversite sayısı */}
<p className="mt-5 flex flex-wrap items-center justify-center gap-2 lg:justify-start">
<span className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800">
<MapPin className="size-4 text-primary" aria-hidden />
{il.ad}
</span>
<span className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800">
{devlet.length >= vakif.length ? (
<Landmark className="size-4 text-primary" aria-hidden />
) : (
<Building2 className="size-4 text-primary" aria-hidden />
)}
{sayi(il.uniler.length)} üniversite
</span>
</p>
{/* Kimlik hapları (DESIGN.md §4.12): il + üniversite sayısı */}
<p className="mt-5 flex flex-wrap items-center justify-center gap-2 lg:justify-start">
<span className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800">
<MapPin className="size-4 text-primary" aria-hidden />
{il.ad}
</span>
<span className="inline-flex h-10 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800">
{devlet.length >= vakif.length ? (
<Landmark className="size-4 text-primary" aria-hidden />
) : (
<Building2 className="size-4 text-primary" aria-hidden />
)}
{sayi(il.uniler.length)} üniversite
</span>
</p>
<p className="mx-auto mt-6 max-w-3xl text-center text-base leading-relaxed text-slate-600 sm:text-lg lg:mx-0 lg:text-left">
{il.ad}&apos;da {SON_YIL} YKS yerleştirmesinde öğrenci alan{" "}
<strong>{sayi(il.uniler.length)} üniversite</strong>
{ozetParcalar.length > 1 ? ` (${ozetParcalar.join(", ")})` : ""} ve
toplam <strong>{sayi(il.programSayisi)} program</strong> var.
Üniversiteye tıklayınca programlarının taban puanlarını, başarı
sıralamalarını ve kontenjanlarını fakülte fakülte görürsün. Veriler
YÖK Atlas {SON_YIL} yerleştirme sonuçlarına dayanır; {TERCIH_YILI}{" "}
tercihleri için rehber niteliğindedir.
</p>
<p className="mx-auto mt-6 max-w-2xl text-base leading-relaxed text-slate-600 sm:text-lg lg:mx-0">
{il.ad}&apos;da {SON_YIL} YKS yerleştirmesinde öğrenci alan{" "}
<strong>{sayi(il.uniler.length)} üniversite</strong>
{ozetParcalar.length > 1 ? ` (${ozetParcalar.join(", ")})` : ""}{" "}
ve toplam <strong>{sayi(il.programSayisi)} program</strong> var.
Üniversiteye tıklayınca programlarının taban puanlarını, başarı
sıralamalarını ve kontenjanlarını fakülte fakülte görürsün.
Veriler YÖK Atlas {SON_YIL} yerleştirme sonuçlarına dayanır;{" "}
{TERCIH_YILI} tercihleri için rehber niteliğindedir.
</p>
</div>
}
/>
<div className="mt-8">
<CtaSiraForm varyant="kompakt" konum="ust" baslik={ctaBaslik} />
@@ -196,12 +208,7 @@ export function IlIcerikSkeleton() {
return (
<main className="mx-auto w-full max-w-5xl px-4 py-12 sm:py-16">
<Skeleton className="mx-auto h-4 w-64 lg:mx-0" />
<Skeleton className="mx-auto mt-6 h-10 w-full max-w-xl lg:mx-0" />
<div className="mt-5 flex justify-center gap-2 lg:justify-start">
<Skeleton className="h-10 w-28 rounded-full" />
<Skeleton className="h-10 w-32 rounded-full" />
</div>
<Skeleton className="mx-auto mt-6 h-5 w-full max-w-3xl lg:mx-0" />
<Skeleton className="mt-6 h-72 w-full rounded-3xl" />
<div className="mt-10 space-y-4">
<Skeleton className="h-8 w-72" />
{Array.from({ length: 6 }, (_, i) => (