feat(tasarim): üniversite sayfası "şişko ve sade" dile göre baştan, DESIGN.md know-how'ı
Üniversite sayfası (canlı referans ekran /universite/ankara-universitesi): - Program listesi: ad kesilmez/sarar, telefonda taban sıra alt satıra iner, satır butonları 44 px, tür çipi okunur boyda - Başlık bloğu lg altında ortalı (logo başlığın üstünde), kimlik hapları (Devlet/Ankara) navbar ölçüsünde, ikon + metin - Harita yanında 4 özet kartı (OzetKart): sayı solda iri, ikon sağda; 4. kart URAP Türkiye sırası + piksel sıra şeridi (PixelSira) - Akademik göstergeler (URAP + YÖK İstatistik) sayfadan "Akademik göstergeler ›" satırının açtığı alt sayfaya taşındı: kartsız, ortalı, masonry gösterge kareleri, tek ekrana sığar - Hover tek turuncu (orange-500); liste satırı adı mavi kalır - Üst çubuk başlık geçişi (NavBaslik): h1 kaydırılınca üst çubukta logo + ad belirir; bölüm sayfasında da (yalnız ad) Tasarım dili: - DESIGN.md: temel his (§1.1), hover kuralı (§2.1), yazı alt sınırları, yeni tek kaynak parçalar (§4.8–4.15), lg altı ortala (§5.2), reddedilen denemeler (§7), ölç-tahmin-etme ve tuzaklar (§9) - Denetim: gösterge karesi renk istisnası (bg-indigo-500, bg-green-600) ve site taraması için dört uyarı (minik-yazi, buyuk-harf-etiket, mavi-hover, iri-sayi-tabular) Not: universite-icerik.tsx'teki akademik göstergeler bölümü (URAP/YÖK kartları) Bilal'in commit'lenmemiş işiydi; tasarım değişiklikleriyle aynı dosyada iç içe olduğu için bu commit'e girdi. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,19 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { notFound } from "next/navigation";
|
||||
import { ChevronRight } from "lucide-react";
|
||||
import {
|
||||
ArrowRight,
|
||||
Building2,
|
||||
ChevronRight,
|
||||
Landmark,
|
||||
LayoutList,
|
||||
Medal,
|
||||
MapPin,
|
||||
Target,
|
||||
Users,
|
||||
} from "lucide-react";
|
||||
import type { LucideIcon } from "lucide-react";
|
||||
import type { ReactNode } from "react";
|
||||
import {
|
||||
getAllUniversiteler,
|
||||
getAllUniversiteSlugs,
|
||||
@@ -26,17 +38,23 @@ import {
|
||||
sayfaDilimi,
|
||||
siraYiliEtiketi,
|
||||
} from "./sayfalama";
|
||||
import { PagePixelDivider } from "@/components/pixel-decor";
|
||||
import { PagePixelDivider, PixelSira } from "@/components/pixel-decor";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { UniversiteKonumHaritasi } from "./universite-konum-haritasi";
|
||||
import { uniUlkeKonum } from "@/lib/harita-ulkeler";
|
||||
import { UniversiteProgramTablosu } from "./universite-program-tablosu";
|
||||
import { VeriKaynagi } from "./veri-kaynagi";
|
||||
import { URAP_DONEM, URAP_KAYNAK_URL, URAP_TOPLAM } from "@/lib/urap-siralama";
|
||||
import {
|
||||
URAP_DONEM,
|
||||
URAP_KAYNAK_URL,
|
||||
URAP_TOPLAM,
|
||||
} from "@/lib/urap-siralama";
|
||||
YOK_ISTATISTIK_DONEM,
|
||||
YOK_ISTATISTIK_KAYNAK_URL,
|
||||
OGRENCI_BASINA_UYE_MEDYAN,
|
||||
ogrenciBasinaUye,
|
||||
} from "@/lib/yok-istatistik";
|
||||
import { UniLogo } from "@/components/uni-logo";
|
||||
import { UrapLogo } from "./urap-logo";
|
||||
import { AkademikAyrinti } from "./akademik-ayrinti";
|
||||
import { NavBaslik } from "./nav-baslik";
|
||||
import { uniLogoYolu } from "@/lib/uni-logolar";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import type { Program } from "@/types/yokatlas";
|
||||
@@ -124,8 +142,8 @@ function fakulteOzeti({
|
||||
* Atıf pazarlık dışı: URAP'ın izni "urapcenter.org adresine aktif bağlantı"
|
||||
* şartına bağlı, o yüzden gerçek <a href>, yeni sekme, rel="noopener" ve
|
||||
* nofollow YOK. Sıra payda ("198 üniversite arasında") ve dönem olmadan
|
||||
* gösterilmez. URAP listesinde olmayan üniversitede sayı yoktur; eksiklik
|
||||
* gizlenmez, nedeni tek cümleyle yazılır.
|
||||
* gösterilmez. Sıra ve atıf artık AkademikGostergeler kartında; bu satır
|
||||
* yalnız URAP listesinde olmayan üniversitede nedeni tek cümleyle yazar.
|
||||
*/
|
||||
function UrapKaynakSatiri({ uni }: { uni: UniDetay }) {
|
||||
if (!uni.urap) {
|
||||
@@ -139,18 +157,288 @@ function UrapKaynakSatiri({ uni }: { uni: UniDetay }) {
|
||||
</p>
|
||||
);
|
||||
}
|
||||
// Sıra ve zorunlu atıf AkademikGostergeler kartında.
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Akademik göstergeler: URAP sırası + YÖK İstatistik öğrenci/öğretim üyesi.
|
||||
* Sayfada değil, özet kartlarının altındaki "Akademik göstergeler ›"
|
||||
* satırının açtığı alt sayfada (AkademikAyrinti) durur; sıra sayısı ayrıca
|
||||
* dördüncü özet kartında.
|
||||
*
|
||||
* Apple ayrıntı sayfası düzeni (Hava Durumu gibi): kart ve süs ayraç yok,
|
||||
* her şey ortalı; iki dev sayı yan yana ince çizgiyle ayrılır, altında ham
|
||||
* sayılar, tek satır not, buton ve en altta ince yazıyla kaynaklar. Alt
|
||||
* sayfa ekranı doldurmasın diye dikey değil yan yana dizilir.
|
||||
*
|
||||
* URAP: sıra payda ve dönem olmadan gösterilmez; sıranın yeri piksel
|
||||
* şeridinde (PixelSira) turuncu yanar. Atıf pazarlık dışı — URAP'ın izni
|
||||
* urapcenter.org'a aktif bağlantı şartına bağlı: gerçek <a href>, yeni
|
||||
* sekme, rel="noopener", nofollow YOK. Oran kıyası sayfası olan
|
||||
* üniversitelerin medyanıyla yapılır; renk kullanılmaz.
|
||||
*/
|
||||
function AkademikGostergeler({ uni }: { uni: UniDetay }) {
|
||||
const { urap, istatistik: i } = uni;
|
||||
const oran = i ? ogrenciBasinaUye(i) : null;
|
||||
const oranVar = i != null && oran != null;
|
||||
if (!urap && !oranVar) return null;
|
||||
const dilim = urap ? Math.ceil((urap.sira / URAP_TOPLAM) * 100) : 0;
|
||||
const kaynakLinki =
|
||||
"font-medium text-primary transition-colors hover:text-orange-500 hover:underline";
|
||||
// Dört gösterge dört canlı karede, logodaki kareler gibi yerleşir: iki
|
||||
// sütun, sağdaki aşağı kaymış, kare boyları farklı — ne tepeler ne
|
||||
// bitişler hizalı (masonry). Renk sempati katar, anlamı etiket taşır;
|
||||
// yazı beyaz (turuncu/mavi zeminde sitenin CTA'larıyla aynı ikili).
|
||||
const kare =
|
||||
"flex flex-col items-center justify-center rounded-3xl px-3 text-white";
|
||||
const etiket = "text-sm font-bold text-white/90";
|
||||
const devSayi =
|
||||
"font-heading text-5xl font-bold leading-none tracking-tight";
|
||||
const orta = "font-heading text-3xl font-bold leading-none";
|
||||
|
||||
const siraKaresi = urap ? (
|
||||
<div className={`${kare} min-h-40 bg-orange-500 py-4`}>
|
||||
<dt className={etiket}>Türkiye sırası</dt>
|
||||
<dd className="mt-3 flex items-baseline justify-center gap-1">
|
||||
<span className={devSayi}>{sayi(urap.sira)}.</span>
|
||||
<span className="text-base font-bold text-white/80">
|
||||
/ {sayi(URAP_TOPLAM)}
|
||||
</span>
|
||||
</dd>
|
||||
<dd className="mt-2 text-base font-bold">
|
||||
{dilim <= 50 ? `İlk %${dilim}` : `${URAP_DONEM} listesi`}
|
||||
</dd>
|
||||
<dd className="mt-3 text-white">
|
||||
<PixelSira
|
||||
sira={urap.sira}
|
||||
toplam={URAP_TOPLAM}
|
||||
hucre={10}
|
||||
zemin="koyu"
|
||||
className="h-3"
|
||||
/>
|
||||
</dd>
|
||||
</div>
|
||||
) : null;
|
||||
const ogrenciKaresi = oranVar ? (
|
||||
<div className={`${kare} min-h-24 bg-indigo-500 py-3`}>
|
||||
<dd className={orta}>{sayi(i.ogrenci)}</dd>
|
||||
<dt className={`mt-1.5 ${etiket}`}>Örgün öğrenci</dt>
|
||||
</div>
|
||||
) : null;
|
||||
const oranKaresi = oranVar ? (
|
||||
<div className={`${kare} min-h-32 bg-primary py-4`}>
|
||||
<dt className={etiket}>Hoca başına öğrenci</dt>
|
||||
<dd className={`mt-3 ${devSayi}`}>{sayi(oran)}</dd>
|
||||
<dd className="mt-2 text-base font-bold text-white/90">
|
||||
Türkiye: {sayi(OGRENCI_BASINA_UYE_MEDYAN)}
|
||||
</dd>
|
||||
</div>
|
||||
) : null;
|
||||
const uyeKaresi = oranVar ? (
|
||||
<div className={`${kare} bg-green-600 py-5`}>
|
||||
<dd className={orta}>{sayi(i.ogretimUyesi)}</dd>
|
||||
<dt className={`mt-1.5 ${etiket}`}>Öğretim üyesi</dt>
|
||||
</div>
|
||||
) : null;
|
||||
const ikiSutun = urap != null && oranVar;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center text-center">
|
||||
<dl className="flex w-full max-w-md items-start gap-3">
|
||||
<div className="flex flex-1 flex-col gap-3">
|
||||
{siraKaresi}
|
||||
{ogrenciKaresi}
|
||||
</div>
|
||||
{ikiSutun || (!urap && oranVar) ? (
|
||||
<div className={`flex flex-1 flex-col gap-3 ${ikiSutun ? "mt-12" : ""}`}>
|
||||
{oranKaresi}
|
||||
{uyeKaresi}
|
||||
</div>
|
||||
) : null}
|
||||
</dl>
|
||||
|
||||
{urap ? (
|
||||
<>
|
||||
<p className="mt-4 max-w-md text-sm leading-relaxed text-slate-500">
|
||||
Türkiye sırası araştırma performansını ölçer; eğitim kalitesini
|
||||
ya da iş bulma oranını ölçmez.
|
||||
</p>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
variant="outline"
|
||||
className="mt-4 cursor-pointer px-6 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]"
|
||||
>
|
||||
<Link href="/universite-siralamasi">
|
||||
Tüm sıralamayı gör
|
||||
<ArrowRight className="size-4" aria-hidden />
|
||||
</Link>
|
||||
</Button>
|
||||
</>
|
||||
) : null}
|
||||
|
||||
<div className="mt-5 flex w-full max-w-md items-center justify-center gap-3 border-t border-slate-100 pt-4 text-left text-xs leading-5 text-slate-500">
|
||||
{urap ? <UrapLogo className="h-7 shrink-0" /> : null}
|
||||
<div>
|
||||
{urap ? (
|
||||
<p>
|
||||
URAP {URAP_DONEM} ·{" "}
|
||||
<a
|
||||
href={URAP_KAYNAK_URL}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className={kaynakLinki}
|
||||
>
|
||||
urapcenter.org
|
||||
</a>
|
||||
</p>
|
||||
) : null}
|
||||
{i ? (
|
||||
<p>
|
||||
YÖK {YOK_ISTATISTIK_DONEM} ·{" "}
|
||||
<a
|
||||
href={YOK_ISTATISTIK_KAYNAK_URL}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className={kaynakLinki}
|
||||
>
|
||||
istatistik.yok.gov.tr
|
||||
</a>
|
||||
</p>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Özet kartı (Apple Fitness özet kartlarının düzeni, sitenin ölçüleriyle):
|
||||
* kartın en baskın öğesi iri sayı; ikonu sağında, küçük ikon kutusunda
|
||||
* (DESIGN.md §4.4 ikon kutusunun küçük hali). Altında başlık ve tek satır
|
||||
* açıklama. Telefonda kart iç genişliği ~131 px: en uzun sayı ("13.889",
|
||||
* text-4xl ≈ 90 px) + size-8 ikon kutusu sığar; sm'den itibaren text-5xl.
|
||||
* Harita yanındaki dört hücrenin tek kaynağı. `ek` verilirse açıklamanın
|
||||
* altında durur (ör. Türkiye sırasındaki piksel şeridi). dl anlamı için dt
|
||||
* DOM'da önce gelir, görsel sıra `order` ile kurulur.
|
||||
*/
|
||||
function OzetKart({
|
||||
ikon: Ikon,
|
||||
etiket,
|
||||
deger,
|
||||
birim,
|
||||
alt,
|
||||
ek,
|
||||
className,
|
||||
}: {
|
||||
ikon: LucideIcon;
|
||||
etiket: string;
|
||||
deger: ReactNode;
|
||||
birim?: string;
|
||||
alt: ReactNode;
|
||||
ek?: ReactNode;
|
||||
className?: string;
|
||||
}) {
|
||||
return (
|
||||
<div
|
||||
className={`flex flex-col rounded-2xl border border-slate-200 bg-white p-4 sm:p-5 ${className ?? ""}`}
|
||||
>
|
||||
<dt className="order-2 mt-2 text-base font-semibold text-slate-900">
|
||||
{etiket}
|
||||
</dt>
|
||||
<dd className="order-1 flex items-start justify-between gap-1.5">
|
||||
<span className="flex min-w-0 flex-wrap items-baseline gap-x-1">
|
||||
<span className="font-heading text-4xl font-bold leading-none tracking-tight text-slate-900 sm:text-5xl">
|
||||
{deger}
|
||||
</span>
|
||||
{birim ? (
|
||||
<span className="text-base font-semibold text-slate-400">
|
||||
{birim}
|
||||
</span>
|
||||
) : null}
|
||||
</span>
|
||||
<span className="flex size-8 shrink-0 items-center justify-center rounded-xl bg-primary/10 sm:size-10">
|
||||
<Ikon className="size-4 text-primary sm:size-5" aria-hidden />
|
||||
</span>
|
||||
</dd>
|
||||
<dd className="order-3 mt-0.5 text-sm text-slate-500">{alt}</dd>
|
||||
{ek ? <dd className="order-4 mt-3">{ek}</dd> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dördüncü özet kartı: URAP Türkiye sırası. Açıklamanın altında sıranın
|
||||
* yerini gösteren piksel şeridi (PixelSira) durur. Kartın tamamı sıralama
|
||||
* sayfasına gider (after: ile gerilmiş link); hover kenarlığı bunu belli
|
||||
* eder. Atıf pazarlık dışı: sıra payda ve dönem olmadan gösterilmez;
|
||||
* urapcenter.org'a aktif bağlantı (yeni sekme, rel="noopener", nofollow YOK)
|
||||
* z-10 ile kart linkinin üstünde kalır.
|
||||
*/
|
||||
function TurkiyeSirasiKarti({ sira }: { sira: number }) {
|
||||
const dilim = Math.ceil((sira / URAP_TOPLAM) * 100);
|
||||
return (
|
||||
<OzetKart
|
||||
className="group relative transition-[background-color,border-color] duration-150 hover:border-orange-500 hover:bg-orange-50/60"
|
||||
ikon={Medal}
|
||||
ek={<PixelSira sira={sira} toplam={URAP_TOPLAM} className="h-3" />}
|
||||
etiket="Türkiye sırası"
|
||||
deger={
|
||||
<Link
|
||||
href="/universite-siralamasi"
|
||||
aria-label={`Türkiye sıralamasında ${sayi(sira)}. — tüm üniversite sıralamasını gör`}
|
||||
className="transition-colors after:absolute after:inset-0 after:rounded-2xl group-hover:text-orange-500 focus-visible:outline-none focus-visible:after:ring-2 focus-visible:after:ring-primary"
|
||||
>
|
||||
{sayi(sira)}.
|
||||
</Link>
|
||||
}
|
||||
birim={`/ ${sayi(URAP_TOPLAM)}`}
|
||||
alt={
|
||||
<>
|
||||
{dilim <= 50 ? (
|
||||
<span className="block font-semibold text-slate-700">
|
||||
İlk %{dilim}
|
||||
</span>
|
||||
) : null}
|
||||
<a
|
||||
href={URAP_KAYNAK_URL}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className="relative z-10 font-medium text-primary transition-colors hover:text-orange-500 hover:underline"
|
||||
>
|
||||
URAP {URAP_DONEM}
|
||||
</a>
|
||||
</>
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
/** "Akademik göstergeler ›" satırının ikinci satırı: içeride ne var. */
|
||||
function akademikOnizleme(uni: UniDetay): string {
|
||||
const oran = uni.istatistik ? ogrenciBasinaUye(uni.istatistik) : null;
|
||||
if (oran != null) return `Hoca başına ${sayi(oran)} öğrenci`;
|
||||
return "Türkiye sıralaması ayrıntısı";
|
||||
}
|
||||
|
||||
/** YÖK İstatistik'in ayrı kaynak satırı — dönemi YÖK Atlas'tan ve URAP'tan farklı. */
|
||||
function IstatistikKaynakSatiri({ uni }: { uni: UniDetay }) {
|
||||
if (!uni.istatistik) return null;
|
||||
return (
|
||||
<p className="mt-2 text-xs leading-5 text-slate-500">
|
||||
URAP Türkiye Sıralaması {URAP_DONEM} ({sayi(URAP_TOPLAM)} üniversite
|
||||
arasında) — akademik yayın ve araştırma performansını ölçer; eğitim
|
||||
kalitesini ya da iş bulma oranını ölçmez. Kaynak:{" "}
|
||||
Öğrenci ve öğretim üyesi sayıları: YÖK Yükseköğretim İstatistikleri{" "}
|
||||
{YOK_ISTATISTIK_DONEM}. Örgün öğrenci birinci ve ikinci öğretimdeki tüm
|
||||
düzeyleri (ön lisans–doktora) kapsar, uzaktan ve açık öğretim dahil
|
||||
değildir; öğretim üyesi profesör, doçent ve doktor öğretim üyesidir.
|
||||
Kaynak:{" "}
|
||||
<a
|
||||
href={URAP_KAYNAK_URL}
|
||||
href={YOK_ISTATISTIK_KAYNAK_URL}
|
||||
target="_blank"
|
||||
rel="noopener"
|
||||
className="font-medium text-primary hover:underline"
|
||||
className="font-medium text-primary transition-colors hover:text-orange-500 hover:underline"
|
||||
>
|
||||
urapcenter.org
|
||||
istatistik.yok.gov.tr
|
||||
</a>
|
||||
.
|
||||
</p>
|
||||
@@ -231,7 +519,7 @@ export function UniversiteIcerik({
|
||||
// özet paragrafının hemen altında, tablonun (ve ilk sayfadaki istatistik
|
||||
// ızgarasının) üstünde durur. Alttaki kart yerinde kalır.
|
||||
const ustSiraSatiri = (
|
||||
<div className="mt-6">
|
||||
<div className="mt-8">
|
||||
<CtaSiraForm varyant="kompakt" konum="ust" baslik={ctaBaslik} />
|
||||
</div>
|
||||
);
|
||||
@@ -276,71 +564,88 @@ export function UniversiteIcerik({
|
||||
|
||||
<nav
|
||||
aria-label="breadcrumb"
|
||||
className="flex items-center gap-1 text-xs text-slate-500"
|
||||
className="flex flex-wrap items-center justify-center gap-1.5 text-sm text-slate-500 lg:justify-start"
|
||||
>
|
||||
<Link href="/" className="hover:text-primary hover:underline">
|
||||
<Link
|
||||
href="/"
|
||||
className="transition-colors hover:text-orange-500 hover:underline"
|
||||
>
|
||||
Ana Sayfa
|
||||
</Link>
|
||||
<ChevronRight className="size-3" aria-hidden />
|
||||
<ChevronRight className="size-3.5 shrink-0" aria-hidden />
|
||||
<Link
|
||||
href="/universiteler"
|
||||
className="hover:text-primary hover:underline"
|
||||
className="transition-colors hover:text-orange-500 hover:underline"
|
||||
>
|
||||
Üniversiteler
|
||||
</Link>
|
||||
<ChevronRight className="size-3" aria-hidden />
|
||||
<ChevronRight className="size-3.5 shrink-0" aria-hidden />
|
||||
{ilkSayfa ? (
|
||||
<span className="text-slate-700">{uni.ad}</span>
|
||||
) : (
|
||||
<>
|
||||
<Link
|
||||
href={`/universite/${slug}`}
|
||||
className="hover:text-primary hover:underline"
|
||||
className="transition-colors hover:text-orange-500 hover:underline"
|
||||
>
|
||||
{uni.ad}
|
||||
</Link>
|
||||
<ChevronRight className="size-3" aria-hidden />
|
||||
<ChevronRight className="size-3.5 shrink-0" aria-hidden />
|
||||
<span className="text-slate-700">Sayfa {sayfa}</span>
|
||||
</>
|
||||
)}
|
||||
</nav>
|
||||
|
||||
<div className="mt-4 flex items-center gap-4">
|
||||
{/* Başlık üst çubuğun altına girince üst çubukta logo + ad belirir */}
|
||||
<NavBaslik
|
||||
baslikId="uni-baslik"
|
||||
ad={uni.ad}
|
||||
logo={<UniLogo slug={slug} ad={uni.ad} boy="xs" />}
|
||||
/>
|
||||
{/* Geniş ekran (lg) altında başlık bloğu ortalı: logo başlığın
|
||||
üstünde, yol satırı, çipler ve özet paragraf ortada. */}
|
||||
<div className="mt-6 flex flex-col items-center gap-4 text-center lg:flex-row lg:text-left">
|
||||
<UniLogo slug={slug} ad={uni.ad} boy="lg" />
|
||||
<h1 className="font-heading text-3xl font-bold text-slate-900 sm:text-4xl">
|
||||
<h1
|
||||
id="uni-baslik"
|
||||
className="font-heading text-3xl font-bold leading-tight text-slate-900 sm:text-5xl"
|
||||
>
|
||||
{uni.ad} Taban Puanları {BASLIK_YILI}
|
||||
{ilkSayfa ? "" : ` — Sayfa ${sayfa}`}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{/* Kurumun kimliği (tür + il): ızgaradaki kartlar sayısal ve
|
||||
karşılaştırılabilir metriklerdir, tür ise kategoridir — sitenin
|
||||
geri kalanında da başlığın altında çip olarak duruyor. Çipin sınıf
|
||||
seti program-tablosu.tsx:329-333'ten birebir kopyadır (AGENTS.md
|
||||
"ortak elemanlar tek kaynaktan"); yeni varyant üretilmez.
|
||||
Sayfalama sayfalarında da yazar: ziyaretçi Google'dan doğrudan
|
||||
/sayfa/N'ye inebiliyor, kimlik orada da aynı. `unitur` NULL ise
|
||||
satırın tamamı düşer, kopuk boşluk kalmaz. */}
|
||||
{turEtiketi ? (
|
||||
<p className="mt-3 flex min-w-0 items-center gap-1.5 text-xs text-slate-500">
|
||||
<span
|
||||
className={`shrink-0 rounded px-1 py-px text-[10px] font-medium leading-4 ${
|
||||
uniturDevletMi(uni.unitur)
|
||||
? "bg-slate-100 text-slate-600"
|
||||
: "bg-violet-50 text-violet-600"
|
||||
}`}
|
||||
>
|
||||
{turEtiketi.cip}
|
||||
</span>
|
||||
karşılaştırılabilir metriklerdir, tür ise kategoridir — başlığın
|
||||
altında iki iri hap olarak durur (navbar'daki hap butonların
|
||||
ölçüsü: h-10, tam yuvarlak, ikon + tek kelime). Tür renkle değil
|
||||
ikon + metinle ayrılır. Sayfalama sayfalarında da yazar:
|
||||
ziyaretçi Google'dan doğrudan /sayfa/N'ye inebiliyor. `unitur`
|
||||
NULL ise tür hapı düşer, kopuk boşluk kalmaz. */}
|
||||
{turEtiketi || uni.il ? (
|
||||
<p className="mt-5 flex flex-wrap items-center justify-center gap-2 lg:justify-start">
|
||||
{turEtiketi ? (
|
||||
<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">
|
||||
{uniturDevletMi(uni.unitur) ? (
|
||||
<Landmark className="size-4 text-primary" aria-hidden />
|
||||
) : (
|
||||
<Building2 className="size-4 text-primary" aria-hidden />
|
||||
)}
|
||||
{turEtiketi.cip}
|
||||
</span>
|
||||
) : null}
|
||||
{uni.il ? (
|
||||
<span className="truncate">{trBaslikDuzeni(uni.il)}</span>
|
||||
<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">
|
||||
<MapPin className="size-4 shrink-0 text-primary" aria-hidden />
|
||||
<span className="truncate">{trBaslikDuzeni(uni.il)}</span>
|
||||
</span>
|
||||
) : null}
|
||||
</p>
|
||||
) : null}
|
||||
|
||||
{ilkSayfa ? (
|
||||
<>
|
||||
<p className="mt-4 max-w-3xl text-sm leading-7 text-slate-600">
|
||||
<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">
|
||||
{uni.ad}
|
||||
{uni.il ? ` (${trBaslikDuzeni(uni.il)})` : ""}
|
||||
{turCumlesi ? `, ${turCumlesi};` : ","} {SON_YIL} YKS yerleştirme
|
||||
@@ -370,82 +675,68 @@ export function UniversiteIcerik({
|
||||
|
||||
{ustSiraSatiri}
|
||||
|
||||
<div className="mt-6 grid grid-cols-2 gap-3 lg:grid-cols-[1fr_1fr_1.35fr] lg:grid-rows-2">
|
||||
<div className="mt-8 grid grid-cols-2 gap-4 lg:grid-cols-[1fr_1fr_1.35fr] lg:grid-rows-2">
|
||||
<UniversiteKonumHaritasi universite={uni.ad} il={uni.il} />
|
||||
{/* Şablon tam 4 hücre bırakıyor: masaüstünde harita 3. sütunu
|
||||
iki satır boyunca kaplıyor, 5. kart ızgarayı bozar. Fakülte
|
||||
sayısı Program kartının alt satırında; boşalan hücrede
|
||||
Türkiye sırası. Geri kalan akademik ayrıntı alttaki
|
||||
"Akademik göstergeler ›" penceresinde. */}
|
||||
<dl className="contents">
|
||||
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
||||
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||
Program
|
||||
</dt>
|
||||
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
||||
{sayi(uni.programSayisi)}
|
||||
</dd>
|
||||
</div>
|
||||
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
||||
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||
Fakülte / Birim
|
||||
</dt>
|
||||
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
||||
{sayi(uni.fakulteSayisi)}
|
||||
</dd>
|
||||
</div>
|
||||
{/* Şablon tam 4 hücre bırakıyor: masaüstünde harita 3. sütunu
|
||||
iki satır boyunca kaplıyor (lg:grid-rows-2 + row-span-2), 5.
|
||||
kart ızgarayı bozar. Bu yüzden 4. hücre tek: URAP'ta olan
|
||||
üniversitede URAP sırası, olmayan 31 sayfada toplam
|
||||
kontenjan. Toplam kontenjanı 0 olan üniversite yok
|
||||
(yokatlas.db: GROUP BY universite HAVING
|
||||
SUM(COALESCE(kontenjan2026,0))=0 → 0 satır), yani hiçbir
|
||||
sayfada "—" çıkmaz. URAP'ta payda kartın içindedir: "18."
|
||||
tek başına yanıltır. */}
|
||||
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
||||
{uni.urap ? (
|
||||
<>
|
||||
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||
URAP Türkiye
|
||||
</dt>
|
||||
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
||||
{sayi(uni.urap.sira)} / {sayi(URAP_TOPLAM)}
|
||||
<span className="mt-0.5 block font-sans text-xs font-medium text-slate-500">
|
||||
{URAP_DONEM}
|
||||
</span>
|
||||
</dd>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||
Toplam kontenjan
|
||||
</dt>
|
||||
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
||||
{sayi(uni.stats.toplamKontenjan)}
|
||||
</dd>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="rounded-xl border border-slate-200 bg-white p-4">
|
||||
<dt className="text-xs font-medium uppercase tracking-wide text-slate-500">
|
||||
En iyi sıralama
|
||||
</dt>
|
||||
<dd className="mt-1 font-heading text-2xl font-bold text-slate-900">
|
||||
{uni.stats.minSira != null ? sayi(uni.stats.minSira) : "—"}
|
||||
</dd>
|
||||
</div>
|
||||
<OzetKart
|
||||
ikon={LayoutList}
|
||||
etiket="Program"
|
||||
deger={sayi(uni.programSayisi)}
|
||||
alt={`${sayi(uni.fakulteSayisi)} birimde`}
|
||||
/>
|
||||
<OzetKart
|
||||
ikon={Users}
|
||||
etiket="Kontenjan"
|
||||
deger={sayi(uni.stats.toplamKontenjan)}
|
||||
alt={`${SON_YIL} toplamı`}
|
||||
/>
|
||||
<OzetKart
|
||||
ikon={Target}
|
||||
etiket="En iyi sıralama"
|
||||
deger={
|
||||
uni.stats.minSira != null ? sayi(uni.stats.minSira) : "—"
|
||||
}
|
||||
alt={`${SON_YIL} taban sırası`}
|
||||
/>
|
||||
{uni.urap ? (
|
||||
<TurkiyeSirasiKarti sira={uni.urap.sira} />
|
||||
) : (
|
||||
<OzetKart
|
||||
ikon={Building2}
|
||||
etiket="Fakülte / birim"
|
||||
deger={sayi(uni.fakulteSayisi)}
|
||||
alt="programların dağıldığı"
|
||||
/>
|
||||
)}
|
||||
</dl>
|
||||
</div>
|
||||
{uni.urap || uni.istatistik ? (
|
||||
<AkademikAyrinti
|
||||
universite={uni.ad}
|
||||
onizleme={akademikOnizleme(uni)}
|
||||
>
|
||||
<AkademikGostergeler uni={uni} />
|
||||
</AkademikAyrinti>
|
||||
) : null}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<p className="mt-4 max-w-3xl text-sm leading-7 text-slate-600">
|
||||
<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">
|
||||
{uni.ad} taban puanları tablosunun {sayfa}. sayfası (
|
||||
{sayi(tumProgramlar.length)} programın{" "}
|
||||
{sayi((sayfa - 1) * SAYFA_BOYU + 1)}–
|
||||
{sayi(Math.min(sayfa * SAYFA_BOYU, tumProgramlar.length))}.
|
||||
satırları, fakülte sırasıyla).
|
||||
{birimler ? ` Bu sayfadaki birimler: ${birimler}.` : ""} Üniversite
|
||||
özeti ve istatistikler{" "}
|
||||
{birimler ? ` Bu sayfadaki birimler: ${birimler}.` : ""}{" "}
|
||||
Üniversite özeti ve istatistikler{" "}
|
||||
<Link
|
||||
href={`/universite/${slug}`}
|
||||
className="font-medium text-primary hover:underline"
|
||||
className="font-medium text-primary transition-colors hover:text-orange-500 hover:underline"
|
||||
>
|
||||
ilk sayfada
|
||||
</Link>
|
||||
@@ -455,13 +746,13 @@ export function UniversiteIcerik({
|
||||
</>
|
||||
)}
|
||||
|
||||
<PagePixelDivider seed={57} className="mt-8" />
|
||||
<PagePixelDivider seed={57} className="mx-auto mt-12 lg:mx-0" />
|
||||
|
||||
<div id="programlar" className="mt-8">
|
||||
<h2 className="font-heading text-xl font-bold text-slate-900">
|
||||
<div id="programlar" className="mt-10 text-center lg:text-left">
|
||||
<h2 className="font-heading text-2xl font-bold text-slate-900 sm:text-3xl">
|
||||
Üniversite programları
|
||||
</h2>
|
||||
<p className="mt-1 text-xs text-slate-500">
|
||||
<p className="mt-2 text-base text-slate-500">
|
||||
Fakülte ve birimlere göre
|
||||
</p>
|
||||
</div>
|
||||
@@ -474,6 +765,7 @@ export function UniversiteIcerik({
|
||||
</VeriKaynagi>
|
||||
|
||||
{ilkSayfa ? <UrapKaynakSatiri uni={uni} /> : null}
|
||||
{ilkSayfa ? <IstatistikKaynakSatiri uni={uni} /> : null}
|
||||
|
||||
<Sayfalama
|
||||
tabanYol={`/universite/${slug}`}
|
||||
@@ -497,21 +789,21 @@ export function UniversiteIcerik({
|
||||
export function UniversiteIcerikSkeleton() {
|
||||
return (
|
||||
<main className="mx-auto w-full max-w-5xl px-4 py-12 sm:py-16">
|
||||
<Skeleton className="h-4 w-64" />
|
||||
<div className="mt-4 flex items-center gap-4">
|
||||
<Skeleton className="h-5 w-64" />
|
||||
<div className="mt-6 flex items-center gap-4">
|
||||
<Skeleton className="size-14 rounded-lg" />
|
||||
<Skeleton className="h-10 w-2/3 max-w-xl" />
|
||||
</div>
|
||||
<Skeleton className="mt-4 h-5 w-full max-w-3xl" />
|
||||
<div className="mt-6 grid grid-cols-2 gap-3 lg:grid-cols-[1fr_1fr_1.35fr] lg:grid-rows-2">
|
||||
<div className="mt-8 grid grid-cols-2 gap-4 lg:grid-cols-[1fr_1fr_1.35fr] lg:grid-rows-2">
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<Skeleton key={i} className="h-24 w-full rounded-xl" />
|
||||
<Skeleton key={i} className="h-28 w-full rounded-2xl" />
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-16 space-y-3">
|
||||
<Skeleton className="h-7 w-64" />
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<Skeleton key={i} className="h-12 w-full" />
|
||||
<Skeleton key={i} className="h-20 w-full rounded-2xl" />
|
||||
))}
|
||||
</div>
|
||||
</main>
|
||||
|
||||
Reference in New Issue
Block a user