feat(katalog+tasarim): şehir adları her yerde link; piksel yüzeylere beyaz ton

- ilSayfaHref: üniversite sayfası il hapı, /universiteler listesi, bölüm /
  sonuç / listem / tadımlık satırlarındaki il metası şehir sayfasına gider.
- Şehir kümeleri tüm (üniversite, il) çiftlerinden: DB'deki her il değerinin
  sayfası var (ODTÜ Ankara + KKTC); dev'de eski globalThis önbelleğine dayanıklı.
- PikselZemin ton="acik", CtaBandi/CtaSiraForm ton="beyaz": /universiteler
  altı ve /meraklisina kapanışı beyaz, diğer bantlar mavi (dönüşümlü).
- ilUlkeHaritasi: il değerinden ülke haritası + şehir konumu.

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 c27f24e6a6
commit 259534fa9c
13 changed files with 193 additions and 49 deletions

View File

@@ -4,7 +4,8 @@ import { startTransition, useMemo, useRef, useState } from "react";
import Link from "next/link";
import { ChevronDown, ChevronUp } from "lucide-react";
import type { Program } from "@/types/yokatlas";
import { trBaslikDuzeni } from "@/lib/slug";
import { ilSayfaHref, trBaslikDuzeni } from "@/lib/slug";
import { cn } from "@/lib/utils";
import { UNITUR_ETIKET } from "@/lib/unitur";
import { VERI_YIL_SAYISI } from "@/lib/veri-yillari";
import { Sayfalama, SAYFA_BOYU } from "./sayfalama";
@@ -23,6 +24,7 @@ import {
SATIR_BUTON_KABI,
SATIR_CIP,
SATIR_GRUP,
SATIR_IKINCIL_LINK,
SATIR_META,
SATIR_MOBIL_SAYI,
} from "@/components/liste-satiri";
@@ -247,9 +249,13 @@ export function BolumProgramListesi({
</span>
) : null}
{p.il ? (
<span className="shrink-0">
<Link
href={ilSayfaHref(p.il)}
className={cn("shrink-0", SATIR_IKINCIL_LINK)}
title={`${trBaslikDuzeni(p.il)} üniversiteleri`}
>
{trBaslikDuzeni(p.il)}
</span>
</Link>
) : null}
{p.sure ? (
<span className="shrink-0">{p.sure} yıl</span>

View File

@@ -18,7 +18,7 @@ import {
getUniversiteBySlug,
bolumSlugFromIsim,
} from "../katalog-queries";
import { trBaslikDuzeni } from "@/lib/slug";
import { ilSayfaHref, trBaslikDuzeni } from "@/lib/slug";
import { UNITUR_ETIKET, uniturDevletMi } from "@/lib/unitur";
import {
JsonLd,
@@ -579,10 +579,16 @@ export function UniversiteIcerik({
</span>
) : null}
{uni.il ? (
<span className="inline-flex h-10 min-w-0 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800">
// İl hapı şehir sayfasına gider (Bilal, 24 Eyl 2026: "şehirlerin
// geçtiği her yer tıklanabilir"); hover §2.1 tek turuncu.
<Link
href={ilSayfaHref(uni.il)}
title={`${trBaslikDuzeni(uni.il)} üniversiteleri`}
className="inline-flex h-10 min-w-0 items-center gap-2 rounded-full border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-800 transition-[background-color,border-color,color,transform] duration-150 hover:border-orange-500 hover:bg-orange-50/60 hover:text-orange-500 active:scale-[0.97]"
>
<MapPin className="size-4 shrink-0 text-primary" aria-hidden />
<span className="truncate">{trBaslikDuzeni(uni.il)}</span>
</span>
</Link>
) : null}
</p>
) : null}

View File

@@ -4,7 +4,7 @@ import {
getAllUniversiteler,
type UniOzet,
} from "../katalog-queries";
import { trBaslikDuzeni } from "@/lib/slug";
import { ilSayfaHref, trBaslikDuzeni } from "@/lib/slug";
import { SehirCipleri, oneCikanIller } from "./sehir-cipleri";
import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form";
import { PagePixelDivider } from "@/components/pixel-decor";
@@ -15,25 +15,41 @@ import { SON_YIL, TERCIH_YILI } from "@/lib/veri-yillari";
const sayi = (n: number) => n.toLocaleString("tr-TR");
export function UniLinkleri({ uniler }: { uniler: UniOzet[] }) {
// Ad ve il ayrı linkler (iç içe <a> olmaz): logo + ad üniversiteye, alt
// satırdaki şehir adı şehir sayfasına (Bilal, 24 Eyl 2026: "şehirlerin
// geçtiği her yer tıklanabilir"). Hover §2.1 tek turuncu.
return (
<ul className="mt-4 grid gap-x-6 gap-y-2 sm:grid-cols-2">
{uniler.map((u) => (
<li key={u.slug}>
<li key={u.slug} className="grid grid-cols-[auto_minmax(0,1fr)] items-center gap-x-3 text-sm">
<Link
href={`/universite/${u.slug}`}
className="group flex items-center gap-3 text-sm text-slate-700 transition-colors hover:text-orange-500"
tabIndex={-1}
aria-hidden
className="row-span-2"
>
<UniLogo slug={u.slug} ad={u.ad} boy="sm" />
<span className="min-w-0">
<span className="block truncate group-hover:underline">
{u.ad}
</span>
<span className="block text-xs text-slate-400">
{u.il ? `${trBaslikDuzeni(u.il)} · ` : ""}
{sayi(u.programSayisi)} program
</span>
</span>
</Link>
<Link
href={`/universite/${u.slug}`}
className="block truncate text-slate-700 transition-colors hover:text-orange-500 hover:underline"
>
{u.ad}
</Link>
<span className="block text-xs text-slate-400">
{u.il ? (
<>
<Link
href={ilSayfaHref(u.il)}
className="transition-colors hover:text-orange-500 hover:underline"
>
{trBaslikDuzeni(u.il)}
</Link>
{" · "}
</>
) : null}
{sayi(u.programSayisi)} program
</span>
</li>
))}
</ul>
@@ -146,7 +162,7 @@ export function UniversiteKatalogu() {
</section>
<div className="mt-12">
<CtaSiraForm />
<CtaSiraForm ton="beyaz" />
</div>
</>
);