import type { Metadata } from "next"; import Link from "next/link"; import { notFound } from "next/navigation"; 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, getUniversiteBySlug, bolumSlugFromIsim, } from "../katalog-queries"; import { trBaslikDuzeni } from "@/lib/slug"; import { UNITUR_ETIKET, uniturDevletMi } from "@/lib/unitur"; import { JsonLd, breadcrumbJsonLd, sayfaMetadata, SITE_URL, ustSegmentOgGorseli, } from "@/lib/seo"; import { CtaSiraForm } from "@/features/sihirbaz/components/cta-sira-form"; import { SiteFooter } from "@/components/site-footer"; import { KATALOG_CTA_ACIKLAMA, Sayfalama, SAYFA_BOYU, sayfaDilimi, siraYiliEtiketi, } from "./sayfalama"; 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 { 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"; import { BASLIK_YILI, SON_YIL, TERCIH_YILI } from "@/lib/veri-yillari"; const sayi = (n: number) => n.toLocaleString("tr-TR"); export function uniToplamSayfa(programSayisi: number): number { return Math.max(1, Math.ceil(programSayisi / SAYFA_BOYU)); } // Sayfaların generateStaticParams'ı için — sayfalar *-queries import etmez. export function uniStaticSlugs(): string[] { return getAllUniversiteSlugs(); } // 2..N sayfaları; 1. sayfa taban rota (/universite/[slug]) olduğundan üretilmez. export function uniSayfaStaticParams(): { slug: string; no: string }[] { return getAllUniversiteler().flatMap((u) => { const toplam = uniToplamSayfa(u.programSayisi); return Array.from({ length: Math.max(0, toplam - 1) }, (_, i) => ({ slug: u.slug, no: String(i + 2), })); }); } type UniDetay = NonNullable>; /** * Sayfanın satır dilimi + o dilimde geçen fakülte/birim adları (tablo * sırasıyla, tekrarsız). Liste fakülteye göre dizili olduğundan her derin * sayfa belirli birimleri kapsar. Metadata ve gövde aynı hesabı buradan alır. * Fakültesi boş satırlar tabloda "Diğer" grubuna düşer; ad listesine girmez. */ function uniSayfaDilimi(uni: UniDetay, sayfa: number) { // Sayfalama fakülte sıralı düz liste üzerinden; dilim içi yeniden gruplanır const tumProgramlar = uni.fakulteler.flatMap((f) => f.programlar); const dilim = sayfaDilimi(tumProgramlar, sayfa); const fakulteAdlari: string[] = []; for (const p of dilim) { if (p.fakulte && !fakulteAdlari.includes(p.fakulte)) { fakulteAdlari.push(p.fakulte); } } return { tumProgramlar, dilim, fakulteAdlari }; } /** * İlk 2 ad + "ve N birim daha"; ad yoksa null (çağıran eski metne düşer). * Dilim tek birimden ibaretse (50'den çok programlı MYO'lar art arda iki * sayfayı doldurabiliyor) sayfalar ayırt edilsin diye birim içi taban sırası * aralığı eklenir — birim içinde satırlar zaten taban sırasına göre dizili. */ function fakulteOzeti({ dilim, fakulteAdlari: adlar, }: ReturnType): string | null { if (adlar.length === 0) return null; if (adlar.length === 1) { const siralar = dilim .map((p) => p.efektifSira) .filter((n): n is number => n != null); if (siralar.length === 0) return adlar[0]; const min = Math.min(...siralar); const max = Math.max(...siralar); const yil = siraYiliEtiketi( dilim.filter((p) => p.siraSon == null && p.efektifSira != null).length, siralar.length, ); return min === max ? `${adlar[0]} (${yil} taban sırası ${sayi(min)})` : `${adlar[0]} (${yil} taban sırası ${sayi(min)}–${sayi(max)} arası)`; } if (adlar.length === 2) return `${adlar[0]} ve ${adlar[1]}`; return `${adlar[0]}, ${adlar[1]} ve ${adlar.length - 2} birim daha`; } /** * Tablonun altındaki AYRI ikinci kaynak satırı. `VeriKaynagi` kullanılmaz ve * kopyalanmaz: o satır YÖK Atlas'ın yerleştirme yılına ve son güncelleme * tarihine bağlı, URAP'ın dönemi başka — aynı satırda birleşirlerse URAP * verisi YÖK Atlas tarihiyle sunulmuş olur. * * Atıf pazarlık dışı: URAP'ın izni "urapcenter.org adresine aktif bağlantı" * şartına bağlı, o yüzden gerçek , yeni sekme, rel="noopener" ve * nofollow YOK. Sıra payda ("198 üniversite arasında") ve dönem olmadan * 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) { const yurtDisi = uni.unitur === "KKTC" || uni.unitur?.startsWith("YURTDISI"); return (

{yurtDisi ? "Bu üniversite URAP Türkiye sıralamasında yer almıyor — URAP yalnız Türkiye'deki üniversiteleri sıralıyor." : `Bu üniversite URAP Türkiye Sıralaması ${URAP_DONEM} listesinde yer almıyor.`}

); } // 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
, 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 ? (
Türkiye sırası
{sayi(urap.sira)}. / {sayi(URAP_TOPLAM)}
{dilim <= 50 ? `İlk %${dilim}` : `${URAP_DONEM} listesi`}
) : null; const ogrenciKaresi = oranVar ? (
{sayi(i.ogrenci)}
Örgün öğrenci
) : null; const oranKaresi = oranVar ? (
Hoca başına öğrenci
{sayi(oran)}
Türkiye: {sayi(OGRENCI_BASINA_UYE_MEDYAN)}
) : null; const uyeKaresi = oranVar ? (
{sayi(i.ogretimUyesi)}
Öğretim üyesi
) : null; const ikiSutun = urap != null && oranVar; return (
{siraKaresi} {ogrenciKaresi}
{ikiSutun || (!urap && oranVar) ? (
{oranKaresi} {uyeKaresi}
) : null}
{urap ? ( <>

Türkiye sırası araştırma performansını ölçer; eğitim kalitesini ya da iş bulma oranını ölçmez.

) : null}
{urap ? : null}
{urap ? (

URAP {URAP_DONEM} ·{" "} urapcenter.org

) : null} {i ? (

YÖK {YOK_ISTATISTIK_DONEM} ·{" "} istatistik.yok.gov.tr

) : null}
); } /** * Ö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 (
{etiket}
{deger} {birim ? ( {birim} ) : null}
{alt}
{ek ?
{ek}
: null}
); } /** * 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 ( } etiket="Türkiye sırası" deger={ {sayi(sira)}. } birim={`/ ${sayi(URAP_TOPLAM)}`} alt={ <> {dilim <= 50 ? ( İlk %{dilim} ) : null} URAP {URAP_DONEM} } /> ); } /** "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 (

Öğ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:{" "} istatistik.yok.gov.tr .

); } export function uniSayfaMetadata(slug: string, sayfa: number): Metadata { const uni = getUniversiteBySlug(slug); if (!uni) return {}; if (sayfa > 1) { // Üniversite adları uzun: sayfa numarasıyla kalır (~60 karakter), // farklılaştırıcı (o sayfadaki birimler) açıklamaya ve gövdeye gider. const birimler = fakulteOzeti(uniSayfaDilimi(uni, sayfa)); return sayfaMetadata({ title: `${uni.ad} Taban Puanları ${BASLIK_YILI} (Sayfa ${sayfa})`, description: birimler ? `${uni.ad} taban puanları, sayfa ${sayfa}: ${birimler}. Toplam ${uni.programSayisi} programın ${SON_YIL} yerleştirme verileri — taban puanı, başarı sıralaması ve kontenjan.` : `${uni.ad} taban puanları ve başarı sıralamaları tablosunun ${sayfa}. sayfası — toplam ${uni.programSayisi} programın ${SON_YIL} yerleştirme verileri.`, path: `/universite/${slug}/sayfa/${sayfa}`, openGraph: { images: ustSegmentOgGorseli( `/universite/${slug}`, "Üniversite taban puanları ve sıralamaları — KolayTercih", ), }, }); } return sayfaMetadata({ title: `${uni.ad} Taban Puanları ve Başarı Sıralamaları ${BASLIK_YILI}`, description: `${uni.ad} ${SON_YIL} yerleştirme verileri: ${uni.programSayisi} programın taban puanları, başarı sıralamaları ve kontenjanları${uni.il ? ` (${trBaslikDuzeni(uni.il)})` : ""}. ${TERCIH_YILI} tercih rehberi.`, path: `/universite/${slug}`, }); } export function UniversiteIcerik({ slug, sayfa, }: { slug: string; sayfa: number; }) { const uni = getUniversiteBySlug(slug); if (!uni) notFound(); const sayfaDilim = uniSayfaDilimi(uni, sayfa); const { tumProgramlar, dilim } = sayfaDilim; const toplamSayfa = uniToplamSayfa(tumProgramlar.length); if (sayfa < 1 || sayfa > toplamSayfa) notFound(); const birimler = fakulteOzeti(sayfaDilim); const gruplar: { fakulte: string; programlar: (Program & { bolumSlug: string | null })[]; }[] = []; for (const p of dilim) { const anahtar = p.fakulte ?? "Diğer"; const satir = { ...p, bolumSlug: bolumSlugFromIsim(p.isim) }; const son = gruplar[gruplar.length - 1]; if (son && son.fakulte === anahtar) son.programlar.push(satir); else gruplar.push({ fakulte: anahtar, programlar: [satir] }); } const ilkSayfa = sayfa === 1; // Tür iki yerde geçer ve bu bilinçli: H1'in altındaki çip taranmak, // özet paragrafın ilk virgülündeki öbek okunmak içindir. Izgarada "Tür" // kartı yok (şablon 4 hücre, bkz. aşağıdaki ızgara yorumu). Haritada // olmayan ya da NULL bir `unitur`'da öbek hiç yazılmaz: cümlede kopuk // virgül/boşluk kalmaz ve ham DB değeri cümlenin içine sızmaz. const turEtiketi = uni.unitur ? UNITUR_ETIKET[uni.unitur] : undefined; const turCumlesi = turEtiketi?.cumle; const buYol = ilkSayfa ? `/universite/${slug}` : `/universite/${slug}/sayfa/${sayfa}`; const yurtdisi = uniUlkeKonum(uni.ad, uni.il); // Üst satır ve alt kart aynı soruyu sorar; sayfalama sayfalarında da // üniversite adı geçer (ziyaretçi Google'dan doğrudan /sayfa/N'ye iniyor). const ctaBaslik = `Sıralaman ${uni.ad} tabanlarının neresinde?`; // Tek sayfada çıkan ziyaretçi alttaki karta inmiyor: kompakt sıra girişi // ö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-8"> <CtaSiraForm varyant="kompakt" konum="ust" baslik={ctaBaslik} /> </div> ); return ( <> <main className="mx-auto w-full max-w-5xl px-4 py-12 sm:py-16"> <JsonLd data={breadcrumbJsonLd([ { name: "Ana Sayfa", path: "/" }, { name: "Üniversiteler", path: "/universiteler" }, { name: uni.ad, path: `/universite/${slug}` }, ...(ilkSayfa ? [] : [{ name: `Sayfa ${sayfa}`, path: buYol }]), ])} /> {ilkSayfa ? ( <JsonLd data={{ "@context": "https://schema.org", "@type": "CollegeOrUniversity", name: uni.ad, url: `${SITE_URL}/universite/${slug}`, ...(uniLogoYolu(slug) ? { logo: `${SITE_URL}${uniLogoYolu(slug)}` } : {}), ...(uni.il || yurtdisi ? { address: { "@type": "PostalAddress", ...(yurtdisi?.sehir ? { addressLocality: yurtdisi.sehir } : uni.il ? { addressLocality: trBaslikDuzeni(uni.il) } : {}), addressCountry: yurtdisi ? yurtdisi.iso : "TR", }, } : {}), }} /> ) : null} <nav aria-label="breadcrumb" className="flex flex-wrap items-center justify-center gap-1.5 text-sm text-slate-500 lg:justify-start" > <Link href="/" className="transition-colors hover:text-orange-500 hover:underline" > Ana Sayfa </Link> <ChevronRight className="size-3.5 shrink-0" aria-hidden /> <Link href="/universiteler" className="transition-colors hover:text-orange-500 hover:underline" > Üniversiteler </Link> <ChevronRight className="size-3.5 shrink-0" aria-hidden /> {ilkSayfa ? ( <span className="text-slate-700">{uni.ad}</span> ) : ( <> <Link href={`/universite/${slug}`} className="transition-colors hover:text-orange-500 hover:underline" > {uni.ad} </Link> <ChevronRight className="size-3.5 shrink-0" aria-hidden /> <span className="text-slate-700">Sayfa {sayfa}</span> </> )} </nav> {/* 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 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 — 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="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="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 sonuçlarına göre{" "} <strong>{sayi(uni.programSayisi)} programda</strong> öğrenci aldı {uni.fakulteSayisi > 1 ? `; programlar ${sayi(uni.fakulteSayisi)} fakülte/yüksekokula dağılıyor` : ""} . {uni.stats.minSira != null ? ( <> {" "} En iyi taban başarı sıralaması{" "} <strong>{sayi(uni.stats.minSira)}</strong>. </> ) : null} {uni.stats.toplamKontenjan > 0 ? ( <> Toplam kontenjan {sayi(uni.stats.toplamKontenjan)}.</> ) : null}{" "} Aşağıdaki tablolar {TERCIH_YILI} tercihleri için rehber niteliğindedir;{" "} <em> {TERCIH_YILI} taban puanları ve sıralamaları, yerleştirme sonuçları açıklandığında netleşir. </em> </p> {ustSiraSatiri} <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"> <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="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{" "} <Link href={`/universite/${slug}`} className="font-medium text-primary transition-colors hover:text-orange-500 hover:underline" > ilk sayfada </Link> . </p> {ustSiraSatiri} </> )} <PagePixelDivider seed={57} className="mx-auto mt-12 lg:mx-0" /> <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-2 text-base text-slate-500"> Fakülte ve birimlere göre </p> </div> <UniversiteProgramTablosu gruplar={gruplar} /> <VeriKaynagi> "—": o yıl için yerleştirme verisi bulunmuyor (yeni açılan veya o yıl yerleşen çıkmayan program).{" "} </VeriKaynagi> {ilkSayfa ? <UrapKaynakSatiri uni={uni} /> : null} {ilkSayfa ? <IstatistikKaynakSatiri uni={uni} /> : null} <Sayfalama tabanYol={`/universite/${slug}`} sayfa={sayfa} toplamSayfa={toplamSayfa} /> <div className="mt-10"> <CtaSiraForm konum="alt" baslik={ctaBaslik} aciklama={KATALOG_CTA_ACIKLAMA} /> </div> </main> <SiteFooter /> </> ); } export function UniversiteIcerikSkeleton() { return ( <main className="mx-auto w-full max-w-5xl px-4 py-12 sm:py-16"> <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-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-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-20 w-full rounded-2xl" /> ))} </div> </main> ); }